ConstexPR-8CC는 C ++ 14 상수 표현식으로 구현 된 컴파일 타임 C 컴파일러입니다. 컴파일하는 동안 컴파일 할 수 있습니다! 이 프로젝트는 ELVM 인프라를 기반으로 한 8CC 포트입니다.
C ++의 일정한 표현은 컴파일 시간에 평가 될 수있는 표현입니다. C ++ 14에서, 완화 된 제약 조건에 의해, 일정한 표현이 너무 강력 해져서 C 컴파일러를 구현할 수 있습니다 !
ConstexPR-8CC에서 C 프로그램의 컴파일을위한 주요 루틴은 C ++ 14 constexpr 함수에서 구현됩니다. 따라서 8cc.cpp G ++로 바이너리 파일로 컴파일하면 C 프로그램의 컴파일이 컴파일 시간 계산으로 수행 되며이 C 컴파일의 결과는 생성 된 바이너리에 포함됩니다. 이런 의미에서 ConstexPR-8CC는 컴파일 타임 C 컴파일러 입니다.
다음은 8cc.cpp의 main 기능입니다.
int main () {
// Compile-time
constexpr buffer buf = eight_cc (); // Compile C code into ELVM IR
constexpr unsigned int output_size = buf. size ;
static_assert ( 0 <= output_size && output_size < EIGHT_CC_OUTPUT_LIMIT, " 8cc: Error " );
// Run-time
for ( int i = 0 ; i < output_size; ++i) {
putchar (buf. b [i]);
}
} 이 프로그램에서 eight_cc 의 반환 값은 constexpr 지정자와 함께 변수 buf 에 저장됩니다. 따라서 C 프로그램의 컴파일은 컴파일 타임으로 수행된다는 것을 알 수 있습니다.
constexpr-8cc > g ++ -6.2가있는 Linux가 필요합니다. ./test/hello.c g++-6.2 , g++-8.3 및 g++-9.3 으로 컴파일 될 수 있음을 확인했습니다.
-fconstexpr-loop-limit 으로 ConstexPR의 루프 수를 확대해야했습니다. 우리가 지정할 수있는 최대 숫자는 2**31 - 1 입니다.-fconstexpr-loop-limit 외에 -fconstexpr-ops-limit 확대가 필요했습니다.run_8cc.py 에 의한 컴파일 constexpr-8cc를 쉽게 시도하려면 run_8cc.py 사용하십시오.
$ ./run_8cc.py x86 ./test/hello.c -o ./hello.exe # It takes about 3 minutes on my laptop
$ chmod +x ./hello.exe # 'hello.exe' is i386-linux binary
$ ./hello.exe
Hello, world !다음과 같은 컴파일의 대상 언어를 변경할 수 있습니다.
$ ./run_8cc.py py ./test/hello.c -o ./hello.py # target language is Python
$ python ./hello.py
Hello, world ! 이 스크립트에 대한 자세한 내용은 $ ./run_8cc.py -h 입력하십시오.
8cc.cpp 수동으로 컴파일하려면 config.hpp 참조하십시오. 이 파일에서는 변수 EIGHT_CC_INPUT_FILE 이 정의됩니다. EIGHT_CC_INPUT_FILE C ++ 문자열 리터럴로 소스 C 프로그램을 포함하는 파일 이름이어야합니다. 이 문자열은 사전 처리 시간에 8cc.cpp에 내장되어 컴파일 타임 계산의 입력으로 사용됩니다.
따라서 8cc.cpp 수동으로 컴파일하기 전에 원시 프로그램을 다음과 같은 문자열로 변환해야합니다.
$ sed ' 1s/^/R"(/ ' ./test/hello.c | sed ' $s/$/n)"/ ' > ./test/hello.c.txt # Convert C to string literal
$ g++-6 ./8cc.cpp -o eir_gen.out
$ ./eir_gen.out > ./test/hello.eir # eir_gen.out outputs ELVM IR
$ sed -i ' 1s/^/R"(x86/ ' ./test/hello.eir # Convert IR to string literal
$ sed -i ' $s/$/n)"/ ' ./test/hello.eir
$ g++-6 ./elc.cpp -o exe_gen.out
$ ./exe_gen.out > ./hello.exe # exe_gen.out outputs i386-linux binary
$ chmod +x ./hello.exe
$ ./hello.exe
Hello, world ! 8cc.hpp 보면이 프로그램이 손으로 작성되지 않았다는 것을 알게 될 것입니다. 실제로 ELVM 컴파일러 인프라를 사용하여 생성했습니다. 방금 ELVM IR에서 C ++ 14 Constexpr로 번역기를 구현했습니다.
Keiichi Watanabe (udon.watanabe [at] gmail.com)
8cc (@rui314)
elvm (@shinh)
8cc.vim (@rhysd), 8cc.tex (@hak7a3)
컴파일 타임 Brainf*CK 컴파일러 (@bolero-murakami)
TMP-8CC : 다른 컴파일 타임 C 컴파일러
TMP 엄청난 양의 추억을 만들기 때문에 불행히도 TMP-8cc 실제 기계에서 작동하지 않습니다 .내 블로그 게시물 (일본어)