Quantcast
Channel: Hacker News
Viewing all articles
Browse latest Browse all 25817

Constexpr-8cc: Compile-time C Compiler

$
0
0

README.md

constexpr-8cc is a compile-time C compiler implemented as C++14 constant expressions. This project is a port of 8cc built on ELVM Infrastructure.

Constant expressions in C++ are expressions that can be evaluated at compile-time. In C++14, by relaxing constrains, constant expressions became so powerful that a C compiler can be implemented in!

In constexpr-8cc, the main routine for compilations of C programs is implemented in a C++14 constexpr function. Therefore, if you compile 8cc.cpp to a binary file by g++, compilation of a C program will be performed as a compile-time computation and the result of this C compilation will be embedded into the generated binary. In this sense, constexpr-8cc is a compile-time C compiler.

The following is the main function in 8cc.cpp.

intmain() {// Compile-timeconstexpr buffer buf = eight_cc(); // Compile C code into ELVM IRconstexprunsignedint output_size = buf.size;static_assert(0<= output_size && output_size < EIGHT_CC_OUTPUT_LIMIT, "8cc: Error");// Run-timefor(int i = 0; i < output_size; ++i) {putchar(buf.b[i]);
  }
}

In this program, the return value of eight_cc is stored into the variable buf with a constexpr specifier. So, you will find that the compilation of a C program is done in compile-time.

Usage

constexpr-8cc requires g++ 6.2. (The version of g++ is important!)

Compilation by run_8cc.py

In order to try constexpr-8cc easily, use run_8cc.py.

$ ./run_8cc.py x86 ./test/hello.c -o ./hello.exe # It takes several minutes.
$ chmod +x ./hello.exe
$ ./hello.exe
Hello, world!

You can change the target language of compilations like the following:

$ ./run_8cc.py py ./test/hello.c -o ./hello.py # target language is Python
$ python ./hello.py
Hello, world!

Compilation by hand

If you want to compile 8cc.cpp manually, please look at config.hpp. In this file, the variable EIGHT_CC_INPUT_FILE is defined.EIGHT_CC_INPUT_FILE should be a name of a file that contains a source C program as a C++ string literal. This string will be embedded in 8cc.cpp at pre-processing-time and used as an input of the compile-time computation.

So, before compiling 8cc.cpp manually, you have to convert a raw program to a string literal like the following:

$ sed "1iR\"(" ./test/hello.c | sed "$ a )\""> ./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 "1iR\"(x86" ./test/hello.eir # Convert IR to string literal
$ sed -i "$ a )\"" ./test/hello.eir
$ g++-6 ./elc.cpp -o exe_gen.out
$ ./exe_gen.out > ./hello.exe         # exe_gen.out outputs x86 binary
$ chmod +x ./hello.exe
$ ./hello.exe
Hello, world!

References


Viewing all articles
Browse latest Browse all 25817

Trending Articles