ConstExpr-8CC es un compilador C de tiempo de compilación implementado como expresiones constantes C ++ 14. ¡Esto le permite compilar mientras compilas! Este proyecto es un puerto de 8cc construido sobre la infraestructura ELVM.
Las expresiones constantes en C ++ son expresiones que pueden evaluarse en el tiempo de compilación. En C ++ 14, al relajar las restricciones, las expresiones constantes se volvieron tan poderosas que se puede implementar un compilador C !
En ConstExpr-8CC, la rutina principal para las compilaciones de los programas C se implementa en una función C ++ 14 constexpr . Por lo tanto, si compila 8cc.cpp en un archivo binario de G ++, la compilación de un programa C se realizará como un cálculo de tiempo de compilación y el resultado de esta compilación C se incrustará en el binario generado. En este sentido, ConstExpr-8CC es un compilador C de tiempo de compilación .
La siguiente es la función main en 8cc.cpp.
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]);
}
} En este programa, el valor de retorno de eight_cc se almacena en la variable buf con un especificador constexpr . Por lo tanto, encontrará que la compilación de un programa C se realiza en tiempo de compilación.
constexpr-8cc requiere Linux con> G ++-6.2. Confirmé ./test/hello.c se puede compilar con g++-6.2 , g++-8.3 y g++-9.3 al menos.
-fconstexpr-loop-limit . El número máximo que podemos especificar es 2**31 - 1 .-fconstexpr-loop-limit , se necesitaba ampliar -fconstexpr-ops-limit .run_8cc.py Para probar Contexpr-8CC fácilmente, use 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 !Puede cambiar el idioma de destino de las compilaciones como lo siguiente:
$ ./run_8cc.py py ./test/hello.c -o ./hello.py # target language is Python
$ python ./hello.py
Hello, world ! Para obtener más información sobre este script, escriba $ ./run_8cc.py -h .
Si desea compilar manualmente 8cc.cpp , mire config.hpp . En este archivo, se define la variable EIGHT_CC_INPUT_FILE . EIGHT_CC_INPUT_FILE debe ser un nombre de un archivo que contenga un programa de origen C como una cadena C ++ literal. Esta cadena se incrustará en 8CC.CPP en el tiempo de preprocesamiento y se usará como entrada del cálculo de tiempo de compilación.
Entonces, antes de compilar manualmente 8cc.cpp , debe convertir un programa sin procesar en una cadena literal como la siguiente:
$ 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 ! Cuando vea 8cc.hpp , sabrá que este programa no fue escrito a mano. En realidad, utilicé la infraestructura del compilador ELVM para generarla. Acabo de implementar un traductor de ELVM IR a C ++ 14 Constexpr aquí.
Keiichi Watanabe (udon.watanabe [at] gmail.com)
8CC (@RUI314)
Elvm (@shinh)
8cc.vim (@rhysd), 8cc.tex (@hak7a3)
Compilar Brainf*CK Compilador (@Bolero-Murakami)
TMP-8CC: otro compilador C de tiempo de compilación
TMP tiene una gran cantidad de recuerdos, TMP-8cc desafortunadamente no funciona en máquinas reales.Mi publicación de blog (japonés)