constexpr-8cc เป็นคอมไพเลอร์คอมไพล์เวลา C ที่ใช้เป็นนิพจน์คงที่ C ++ 14 สิ่งนี้ช่วยให้คุณสามารถ รวบรวมได้ในขณะที่คุณรวบรวม! โครงการนี้เป็นพอร์ต 8cc ที่สร้างขึ้นบนโครงสร้างพื้นฐาน ELVM
นิพจน์คงที่ใน C ++ เป็นนิพจน์ที่สามารถประเมินได้ในเวลาคอมไพล์ ใน C ++ 14 โดยการผ่อนคลายข้อ จำกัด การแสดงออกอย่างต่อเนื่องมี ประสิทธิภาพ มากจน สามารถใช้คอมไพเลอร์ C ได้ !
ใน constexpr-8cc กิจวัตรหลักสำหรับการรวบรวมโปรแกรม C ถูกนำมาใช้ในฟังก์ชัน C ++ 14 constexpr ดังนั้นหากคุณรวบรวม 8cc.cpp ไปยังไฟล์ไบนารีโดย G ++ การรวบรวมโปรแกรม C จะดำเนินการเป็นการคำนวณเวลาคอมไพล์และผลลัพธ์ของการรวบรวม C นี้จะถูกฝังลงในไบนารีที่สร้างขึ้น ในแง่นี้ CONSTEXPR-8CC เป็น คอมไพเลอร์คอมไพล์เวลา
ต่อไปนี้เป็นฟังก์ชั่น 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 เพื่อที่จะลอง 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 ด้วยตนเองคุณต้องแปลงโปรแกรมดิบเป็นตัวอักษรสตริงดังต่อไปนี้:
$ 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 Compiler (@bolero-murakami)
TMP-8CC: คอมไพเลอร์คอมไพล์เวลาอื่น
TMP ได้รับความทรงจำจำนวนมาก TMP-8cc โชคไม่ดีที่ ไม่สามารถใช้งานได้ กับเครื่องจักรจริงโพสต์บล็อกของฉัน (ภาษาญี่ปุ่น)