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无法在真实机器上使用。我的博客文章(日语)