Contexpr-8cc ist ein Kompilierungs-T-T-C-Compiler, der als C ++ 14 konstante Ausdrücke implementiert ist. Dies ermöglicht es Ihnen, zu kompilieren, während Sie kompilieren! Dieses Projekt ist ein Hafen von 8cc, der auf der ELVM -Infrastruktur basiert.
Konstante Ausdrücke in C ++ sind Ausdrücke, die zur Kompilierungszeit bewertet werden können. In C ++ 14 wurden durch entspannende Einschränkungen ständige Ausdrücke so mächtig , dass ein C -Compiler implementiert werden kann !
In ContexPR-8CC wird die Hauptroutine für Zusammenstellungen von C-Programmen in einer C ++ 14 constexpr -Funktion implementiert. Wenn Sie 8cc.cpp mit G ++ zu einer Binärdatei kompilieren, wird die Kompilierung eines C-Programms als Kompilierungszeitberechnung durchgeführt und das Ergebnis dieser C-Kompilierung wird in die erzeugte Binärdatei eingebettet. In diesem Sinne ist Contexpr-8cc ein Compiles-T-T-C-Compiler .
Das Folgende ist die main in 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]);
}
} In diesem Programm wird der Rückgabewert von eight_cc mit einem constexpr -Spezifizierer in den variablen buf gespeichert. Daher werden Sie feststellen, dass die Zusammenstellung eines C-Programms in der Kompilierungszeit durchgeführt wird.
constexpr-8cc erfordert Linux mit> G ++-6.2. Ich habe bestätigt ./test/hello.c kann zumindest mit g++-6.2 , g++-8.3 und g++-9.3 kompiliert werden.
-fconstexpr-loop-limit vergrößern. Die maximale Zahl, die wir angeben können, ist 2**31 - 1 .-fconstexpr-loop-limit -Vergrößerung -fconstexpr-ops-limit vergrößert.run_8cc.py Verwenden Sie run_8cc.py , um ContExpr-8cc problemlos auszuprobieren.
$ ./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 !Sie können die Zielsprache von Zusammenstellungen wie folgt ändern:
$ ./run_8cc.py py ./test/hello.c -o ./hello.py # target language is Python
$ python ./hello.py
Hello, world ! Weitere Informationen zu diesem Skript geben Sie $ ./run_8cc.py -h ein.
Wenn Sie 8cc.cpp manuell kompilieren möchten, schauen Sie sich bitte config.hpp an. In dieser Datei ist die Variable EIGHT_CC_INPUT_FILE definiert. EIGHT_CC_INPUT_FILE sollte ein Name einer Datei sein, die ein Quell -C -Programm als C ++ String Literal enthält. Diese Zeichenfolge wird zur Vorverarbeitungszeit in 8cc.cpp eingebettet und als Eingabe der Kompilierungszeitberechnung verwendet.
Bevor Sie also 8cc.cpp manuell zusammengestellt haben, müssen Sie ein RAW -Programm in ein Streicherliteral wie folgt umwandeln:
$ 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 ! Wenn Sie 8cc.hpp sehen, werden Sie wissen, dass dieses Programm nicht von Hand geschrieben wurde. Eigentlich habe ich die ELVM -Compiler -Infrastruktur verwendet, um sie zu erzeugen. Ich habe gerade einen Übersetzer von ELVM IR auf C ++ 14 Colexpr implementiert.
Keiichi Watanabe (udon.watanabe [at] gmail.com)
8cc (@rui314)
ELVM (@Shinh)
8cc.vim (@rhysd), 8cc.tex (@hak7a3)
Compile-Time Brainf*CK Compiler (@bolero-murakami)
TMP-8CC: Ein weiterer C-Compiler für Kompilierzeit-C-Compiler
TMP eine große Menge an Erinnerungen nimmt, funktioniert TMP-8cc leider nicht auf echten Maschinen.Mein Blog -Beitrag (Japanisch)