The natural complement to Holy C. What makes it unholy? Well, it's C.
This project loosely follows the book Writing a C Compiler for writing a x86-64 C compiler using Rust, targeted for Intel assembly syntax. This specific implementation is for a Linux system, and uses GCC tools for preprocessing and linking.
The book comes with a git repo containing tests for compiler features added in each chapter.
Each chapter comes in six stages:
- Lexing/Tokenization
- Parsing
- Semantic Analysis (e.g., Typechecking, label creation, etc.)
- TACKY (Three Address Code IR Generation)
- Code Generation
- Code Emission
Build the compiler into target/release/unholy_c relative to the repository
root using the command:
cargo b --release
Alternatively, build/run the compiler directly with the command:
cargo r --release -- <filepath> <optional flag>
By default, the compiler takes in a single input argument for the path to compile. This will run through all of the stages, link/assemble with any other libraries, and write the completed binary into the same directory as the input file. By passing it a specific flag corresponding to one of the preceding stages, it can instead write intermediary output to stdout. The flags are:
- Lexing:
--lex - Parsing:
--parse - Semantic Analysis:
--validate - IR Generation:
--tacky - Code Generation:
--codegen - Assembly:
--asm
The git repo linked earlier contains the full instructions for running tests, but generally is:
./test_compiler <Unholy C Binary Path> --chapter <n> --stage <n>
Git hooks are located in the .githooks/ directory. These are configured to be
run with the command:
git config --local core.hooksPath .githooks/