25 — 네이티브: 기계어로 컴파일하기
지금까지 모든 프로그램은 CPython 위에서 실행됐습니다. NME가 Python으로
컴파일하고 Python이 그것을 실행했습니다. 언어의 작은 부분 — 네이티브 코어
— 은 더 나아가 바로 기계어가 될 수 있습니다. nme 네이티브 실행은 그 코어를 C로
바꾸고 시스템 C 컴파일러로 네이티브 실행 파일을 만듭니다.
단계
네이티브 코어 안에 머무는 프로그램을 쓰세요. 코어는 불리언·정수·유한 실수 값과 문자열 리터럴,
while/if/else, 논리and/or,break, 정수return함수,say/show/말해를 다룹니다. 초급times:/번:반복과 문장형 반복도 한 줄 NME 출력 본문을 쓸 수 있습니다. 네이티브if/while과 분기 본문은then/그러면뒤에 한 줄 NME 출력 문장이나break를 이어 쓸 수도 있습니다:
실행해 보기 →score = 0 while score is less than 10 score add 1 end show score
실행해 보기 →준비는 참 만약 준비 그러면 말해 "준비됨"한 줄 반복은 다음처럼 씁니다:
실행해 보기 →repeat 2 times and show Hi 2번 반복해서 안녕 말해줘 2 times: say "beginner" 2번: 말해 "초급"한 줄
break는 네이티브 반복문을 멈추며 반복문 안에서만 쓸 수 있습니다:
실행해 보기 →횟수 = 0 동안 참 횟수에 1 더해 만약 횟수가 2와 같으면 여기서 멈춰 끝 횟수 말해줘문장형 반복도 같은 한 줄 본문을 사용할 수 있습니다:
실행해 보기 →3번 반복해서 여기서 멈춰 말해 "끝"반복문 자체도 한 줄 본문을 사용할 수 있습니다:
실행해 보기 →동안 참 그러면 여기서 멈춰 말해 "끝"일반 Python
for반복문, Python 인라인 본문과 인라인 값 변경은 이 제한된 네이티브 부분집합 밖입니다. 그런 형식에는 CPython 경로를 사용하세요.네이티브 문자열 변수는 검사하는 8192바이트 버퍼를 사용합니다. 저장하거나 이어붙인 값이 UTF-8 8191바이트보다 크면 네이티브 프로그램이 영어·한국어 런타임 오류와 함께 중단됩니다. 이스케이프한 줄바꿈과 탭은 지원하지만 내부 NUL 문자는 거부합니다. 제한 없는 텍스트에는 CPython 경로를 쓰세요. 저장 한도는 UTF-8 바이트 기준이지만
len은 유니코드 문자 수를 셉니다. 네이티브 정수는-2147483648부터2147483647까지의 부호 있는 32비트 값입니다. 오버플로와 0 제수 나머지 연산은 영어·한국어 런타임 오류로 중단됩니다. 네이티브 함수는 현재 정수만 매개변수로 받고 반환하며, 각 함수에는 최상위 정수return이 필요합니다. 한 분기에서 일찍 반환할 수 있지만, 제어 블록 뒤로 계속되는 모든 경로는 그 마지막return에 도달해야 합니다. 도달 가능한 계속 경로가 없는 중첩 조건문도 바깥 분기를 종료한 것으로 취급합니다. 반복문을 빠져나가는 분기도 종료 경로로 취급합니다. 같은 파일의 뒤쪽에 정의된 함수도 호출할 수 있으며 선언된 위치 인자 개수를 맞춰야 합니다. 헤더에는 단순한 정수 매개변수만 쓰며 기본값·가변 인자·키워드 인자는 네이티브 코어 밖에 있고 중첩 함수 정의도 지원하지 않습니다. 실수 리터럴은 유한해야 합니다. 네이티브 실수 산술은 Cdouble을 쓰며, 계산 결과가 유한 범위를 벗어나면 이중 언어 런타임 오류로 멈춥니다.%g출력 때문에5.0이5로 보일 수 있고-0.0의 부호는-0으로 유지됩니다. 네이티브 식에서는 리터럴, 먼저 대입한 이름, 선언된 함수를 사용할 수 있습니다. 함수 값을 사용하거나 매개변수를 중복해서 적거나 함수 이름을 변수·매개변수로 다시 쓰는 경우에는 거부되므로 동적인 Python 이름 동작에는 CPython 경로를 사용하세요.if true뒤에서 실행되지 않는else나else if에만 대입한 이름은 블록 밖에서 사용할 수 없습니다.if/else사슬에서 블록 뒤로 계속되는 모든 경로에 대입한 이름은 그 뒤에 사용할 수 있고, 일찍 반환하거나 감싼 반복문을 빠져나가는 분기는 그 이름을 대입할 필요가 없으며, 그 종료 경로 안에 중첩 조건문이 있어도 같은 규칙을 따릅니다. 계속되는 분기 중 한 곳에서 처음 대입한 이름을 형제 분기에서 읽을 수도 없고 실행되지 않을 수 있는 반복문 안에서 만든 이름은 조건부로 남습니다.불리언 이름은 생성된 C에서 둘 다
int에 저장되더라도 정수 이름과 구별됩니다. 대입하고==/!=로 비교하고 조건에 바로 쓰며True또는False로 출력할 수 있습니다:
실행해 보기 →준비 = True 말해 준비 만약 준비 말해 "준비됨" 끝 준비 = False 말해 준비같은 값은 더 쉬운 영어·한국어 표기로도 적을 수 있습니다:
실행해 보기 →ready save true set ready to True 준비는 참 저장 준비 True불리언 산술,
더해/빼값 변경, 불리언 함수 매개변수·반환은 CPython 경로에서 사용하세요.네이티브로 컴파일해 실행하세요:
nme 네이티브 실행 count10영어 명령
nme 네이티브 count도 같은 방식입니다.C 소스와 실행 파일을 남기려면:
nme 네이티브 빌드 count -o countnme 네이티브 빌드는 실행 파일 옆에count.c를 씁니다.-o없이.ko파일을 빌드하면 C 이름에도 접미사를 유지한count.ko.c를 만들어 영어판과 한국어판을 한 폴더에서 빌드할 수 있습니다. Windows에서는 원본 줄기가.ko로 끝나도 기본 출력에.exe가 붙습니다. C를 읽으면 프로그램이 실제로 무엇이 되는지 볼 수 있습니다.count.c.nme같은 원본은 Unix에서 기본 실행 파일count.c, Windows에서count.c.exe를 사용하고, 생성 C 소스는count.c.c입니다. 명시적인-o count.c만 C 소스 충돌로 거부됩니다.-o옵션은빌드에만 해당합니다.nme 네이티브 실행 count -o count는실행이 결과 파일을 저장하지 않으므로 E9031으로 거부됩니다. 동작 단어는 하나만 선택하세요.실행과빌드를 함께 적으면 마지막 단어를 조용히 적용하지 않고 E9032로 거부합니다.함수와 재귀는 코어 안에서 동작합니다. 한국어판
examples/native-factorial.ko.nme(영어판examples/native-factorial.nme)는 두 백엔드에서 모두 팩토리얼을 계산합니다:
실행해 보기 →# part of examples/native-factorial.ko.nme def fact(n): 만약에 n이 2보다 작으면 return 1 끝 return n * fact(n - 1) show fact(5)nme 실행 examples/native-factorial.ko nme 네이티브 실행 examples/native-factorial.ko둘 다
120을 출력합니다.코어 밖의 것은 명확한 오류로 거부되며 CPython으로 그대로 실행됩니다. 네이티브 백엔드는 절대 조용히 잘못 컴파일하지 않습니다:
nme 네이티브 실행 ask-demo # "지원하지 않습니다" 진단 출력 nme 실행 ask-demo # CPython으로는 그대로 동작
어떻게 동작하나요
nme-native(Rust 크레이트)는 Python 경로와 같은 프론트엔드 AST를 받아
모든 문장을 문서화된 코어와 대조한 뒤 C를 만듭니다. macOS와 Linux에서는
cc가 그것을 -O2로 기계어로 만들고, Windows에서는 Visual Studio
Developer PowerShell의 Microsoft cl이 /O2와 /utf-8로 같은 일을 합니다.
네이티브 코어 레퍼런스는 허용되는 표면을 정리하고,
구조 메모는 이 C 백엔드를 LLVM·Cranelift와 비교하여
왜 C가 첫 백엔드인지 설명합니다.
성능은 정직하게 측정됩니다: 이 머신에서 정수 5,000만 회 반복문이 네이티브에서 CPython보다 약 60배 빠릅니다. 빡빡한 반복 하나의 마이크로벤치마크이지, 모든 프로그램에 대한 주장이 아닙니다.
직접 해보기
카운트다운을 100까지 세도록 바꾸거나, square(n) 함수를 만들고
square(7)을 출력한 뒤 nme 네이티브 실행으로 실행해 보세요.
배운 것
- 네이티브 코어는 C로, macOS·Linux에서는
cc로, Windows에서는 MSVCcl로 네이티브 실행 파일로 컴파일됩니다. nme 네이티브 실행이 실행하고nme 네이티브 빌드가 C와 실행 파일을 남깁니다. 영어 명령은nme 네이티브 run과nme 네이티브 build입니다.- 함수, 반복, 조건,
say/show/말해출력이 모두 코어 안에서 동작하며, 조건과 반복에 정한 한 줄 NME 출력 형식과 반복 안의 한 줄break도 포함합니다. - 코어 밖에서는 잘못 컴파일하는 대신 프로그램을 거부합니다.