Compile-time C Compiler implemented as C++14 constant expressions

Overview

constexpr-8cc: Compile-time C Compiler Build Status

constexpr-8cc is a compile-time C compiler implemented as C++14 constant expressions. This enables you to compile while you compile! 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.

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 this program, the return value of eight_cc is stored into the variable buf with a constexpr specifier. Thus, you will find that the compilation of a C program is done in compile-time.

Requirements

constexpr-8cc requires Linux with >g++-6.2. I confirmed ./test/hello.c can be compiled with g++-6.2, g++-8.3 and g++-9.3 at least.

  • g++-6.2 worked without any extra flag related to constexpr as there was no limitation of constant's loop counts at this version.
  • With g++-8.3, I needed to enlarge constexpr's loop count with -fconstexpr-loop-limit. The maximum number we can specify is 2**31 - 1.
  • With g++-9.3, in addition to -fconstexpr-loop-limit, enlarging -fconstexpr-ops-limit was needed.
  • There is no guarantee that it works with other versions of g++.
  • I couldn't make it work with clang++ as clang++ has more strict limitation of constexpr loop counts.

How to run

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 about 3 minutes on my laptop
$ chmod +x ./hello.exe                           # 'hello.exe' is i386-linux binary
$ ./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!

For more information about this script, type $ ./run_8cc.py -h.

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 '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!

How was constexpr-8cc generated?

When you see 8cc.hpp, you will know this program was not written by hand. Actually, I used ELVM Compiler Infrastructure to generate it. I just implemented a translator from ELVM IR to C++14 constexpr here.

Author

Keiichi Watanabe (udon.watanabe [at] gmail.com)

Links

Issues
  • Not working on Mac OS X

    Not working on Mac OS X

    run_8cc.py stops running while calling sed.

    (Although g++ is an alias of clang++ in my machine, I believe it doesn't matter because g++ is never called.) Output:

    $ ./run_8cc.py x86 ./test/hello.c -o ./hello.exe
    INFO: Start compilation from "./test/hello.c" to "./hello.exe"
    INFO: Convert C program into C++ string literal
    cp ./test/hello.c ./test/hello.c.txt
    sed -i 1iR\\\"( ./test/hello.c.txt
    sed: 1: "./test/hello.c.txt": invalid command code .
    
    opened by koba-e964 4
  • how to compiler

    how to compiler

    HI dear author,
    It's truly a honor to write a letter to you, I'm building your project nowadays and found the error when building as following, I wonder if there is a chance that you know the reason? :)

    image

    thank you
    best regards to you
    William

    opened by WilliamWangPeng 1
Owner
Keiichi Watanabe
Software engineer who loves strong type systems
Keiichi Watanabe
Read-Compile-Run-Loop: tiny and powerful interactive C++ compiler (REPL)

Read-Compile-Run-Loop: tiny and powerful interactive C++ compiler (REPL) RCRL is a tiny engine for interactive C++ compilation and execution (implemen

Viktor Kirilov 370 Jun 20, 2022
Vaccine Monitor app implemented in C with system Programming techniques.Projects implemented as part of the course Syspro K24

System_Programming_Projects Vaccine Monitor app implemented in C with system Programming techniques.Projects implemented as part of the course Syspro

Aristi_Papastavrou 10 Dec 30, 2021
A simple implementation of a parser and its use to calculate simple mathematical expressions

Calculator C Parser A simple implementation of a parser and its use to calculate simple mathematical expressions I haven't written a detailed descript

Romes 14 Nov 8, 2021
A single-header C/C++ library for parsing and evaluation of arithmetic expressions

ceval A C/C++ header for parsing and evaluation of arithmetic expressions. [README file is almost identical to that of the ceval library] Functions ac

e_t 7 Apr 14, 2022
A single-header C/C++ library for parsing and evaluation of arithmetic expressions

ceval A C/C++ header for parsing and evaluation of arithmetic expressions. [README file is almost identical to that of the ceval library] Functions ac

e_t 7 Apr 14, 2022
A C/C++ library for parsing and evaluation of arithmetic expressions.

ceval A C/C++ header for parsing and evaluation of arithmetic expressions. Functions accessibe from main() Function Argument(s) Return Value ceval_res

e_t 3 Dec 30, 2021
Modern C++ 20 compile time OpenAPI parser and code generator implementation

OpenApi++ : openapipp This is a proof of concept, currently under active work to become the best OpenAPI implementation for C++. It allows compile tim

tipi.build 5 Apr 8, 2022
Ctpg - Compile Time Parser Generator

Ctpg - Compile Time Parser Generator is a C++ single header library which takes a language description as a C++ code and turns it into a LR1 table parser with a deterministic finite automaton lexical analyzer, all in compile time.

Piotr Winter 358 Jun 27, 2022
DimensionalAnalysis - A compact C++ header-only library providing compile-time dimensional analysis and unit awareness

Dimwits ...or DIMensional analysis With unITS is a C++14 library for compile-time dimensional analysis and unit awareness. Minimal Example #include <i

NJOY 7 Feb 1, 2022
Type safe - Zero overhead utilities for preventing bugs at compile time

type_safe type_safe provides zero overhead abstractions that use the C++ type system to prevent bugs. Zero overhead abstractions here and in following

Jonathan Müller 1.1k Jun 24, 2022
Pipet - c++ library for building lightweight processing pipeline at compile-time for string obfuscation, aes ciphering or whatever you want

Pipet Pipet is a lightweight c++17 headers-only library than can be used to build simple processing pipelines at compile time. Features Compile-time p

C. G. 57 Jan 10, 2022
Set of tests to benchmark the compile time of c++ constructs

CompileTimer Set of tests to benchmark the compile time of c++ constructs This project is an attempt to understand what c++ construct take how much ti

Jan Wilmans 6 Sep 21, 2019
[WIP] Experimental C++14 multithreaded compile-time entity-component-system library.

ecst Experimental & work-in-progress C++14 multithreaded compile-time Entity-Component-System header-only library. Overview Successful development of

Vittorio Romeo 443 Jun 16, 2022
Entity-Component-System (ECS) with a focus on ease-of-use, runtime extensibility and compile-time type safety and clarity.

Kengine The Koala engine is a type-safe and self-documenting implementation of an Entity-Component-System (ECS), with a focus on runtime extensibility

Nicolas Phister 451 Jun 7, 2022
A C++ 17 implementation of qntm's base65536 that runs at compile time

A C++ 17 implementation of qntm's base65536 that runs at compile time. With alternatives for C++ 11 and C++ 14 that runs at runtime. Useage: At compil

Sleepy Flower Girl 3 Feb 13, 2022
Einsums in C++ Provides compile-time contraction pattern analysis to determine optimal operation to perform

Einsums in C++ Provides compile-time contraction pattern analysis to determine optimal operation to perform. Examples This will optimize at compile-ti

Justin Turney 6 Jun 15, 2022
Updates the Wii's current system time with the real world time.

Fix Wii System Time This is a homebrew tool I made for the Wii a while ago. It updates the current system time with the real world time via worldtimea

Puzzle 2 Dec 21, 2021
Project PLS is developed based on icarus iverilog and will compile verilog into a much faster optimized model.

Getting Started with PLS The project is developed based on icarus iverilog. Special thanks to Stephen Williams ([email protected]). PLS is a Verilog si

null 7 Jan 11, 2022