ConstexPR-8CC-это компилятор C, реализованный как CSTURE COMPILER COMPILE COMPILER COMPIRESER COMITS 14. Это позволяет вам компилировать во время компиляции! Этот проект представляет собой порт 8CC, построенный на инфраструктуре ELVM.
Постоянные выражения в C ++-это выражения, которые могут быть оценены во время компиляции. В C ++ 14, с расслабляющими ограничениями, постоянные выражения стали настолько мощными , что C может быть реализован компилятор C !
В ConstexPR-8CC основная процедура для компиляций C-программ реализована в функции constexpr C ++ 14. Поэтому, если вы составляете 8cc.cpp в двоичный файл с помощью G ++, компиляция программы C будет выполняться в качестве вычисления времени компиляции, и результат этого компиляции C будет включена в генерируемый бинарник. В этом смысле ContexPR-8CC является компиляцией C-компилятора C.
Ниже приведена main функция в 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]);
}
} В этой программе возвратное значение eight_cc хранится в переменной buf с помощью спецификатора constexpr . Таким образом, вы обнаружите, что компиляция программы C выполняется во время компиляции.
constexpr-8cc требует Linux с> g ++-6.2. Я подтвердил ./test/hello.c может быть скомпилирован с g++-6.2 , g++-8.3 и g++-9.3 по крайней мере.
-fconstexpr-loop-limit . Максимальное число, которое мы можем указать, составляет 2**31 - 1 .-fconstexpr-loop-limit , необходимо увеличить -fconstexpr-ops-limit .run_8cc.py Чтобы легко попробовать ContexPR-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 здесь.
Кейичи Ватанабе (udon.watanabe [at] gmail.com)
8cc (@rui314)
Elvm (@shinh)
8cc.vim (@rhysd), 8cc.tex (@hak7a3)
Компиляция Brainf*ck Compiler (@bolero-murakami)
TMP-8CC: еще один компилятор с компиляцией C
TMP Neads огромное количество воспоминаний, TMP-8cc к сожалению, не работает на реальных машинах.Мой пост в блоге (японский)