ConstexPR-8CC是一種編譯時C編譯器,該編譯器以C ++ 14常數表達式實現。這使您可以在編譯時進行編譯!該項目是建立在ELVM基礎架構上的8CC的港口。
C ++中的常數表達式是可以在編譯時評估的表達式。在C ++ 14中,通過放鬆約束,恆定表達式變得如此強大,以至於可以實現C編譯器!
在ConstexPR-8CC中,C ++ 14 constexpr函數中實現了C程序編譯的主要例程。因此,如果將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]);
}
}在此程序中,使用constexpr規範符將eight_cc的返回值存儲在變量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外,還需要使用G ++ -9.3,還需要擴大-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之前,您必須將RAW程序轉換為字符串文字,如以下內容:
$ 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無法在真實機器上使用。我的博客文章(日語)