Constexpr-8cc هو برنامج التحويل البرمجي C في وقت الترجمة يتم تنفيذه كتعبيرات ثابتة C ++ 14. هذا يمكّنك من التجميع أثناء التجميع! هذا المشروع هو منفذ 8cc مبني على البنية التحتية ELVM.
التعبيرات المستمرة في C ++ هي تعبيرات يمكن تقييمها في وقت الترجمة. في C ++ 14 ، من خلال قيود الاسترخاء ، أصبحت التعبيرات المستمرة قوية جدًا بحيث يمكن تنفيذ برنامج التحويل البرمجي C !
في constexpr-8cc ، يتم تنفيذ الروتين الرئيسي لمجموعات برامج C في وظيفة C ++ 14 constexpr . لذلك ، إذا قمت بتجميع 8cc.cpp إلى ملف ثنائي بواسطة G ++ ، فسيتم إجراء تجميع برنامج C كحساب وقت الترجمة وسيتم تضمين هذا التجميع C في الثنائي الذي تم إنشاؤه. في هذا المعنى ، Constexpr-8cc هو برنامج التحويل البرمجي 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 ، كانت هناك حاجة إلى Enlarging -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)
ترجمة وقت الترجيع*مترجم CK (@BOLERO-MURAKAMI)
TMP-8CC: برنامج التحويل البرمجي C في وقت الترجمة آخر
TMP Neads كمية ضخمة من الذكريات ، TMP-8cc للأسف لا يعمل على آلات حقيقية.منشور مدونتي (ياباني)