Lumi Compiler is a hand-built C compiler project in C with a real multi-stage pipeline:
- lexical analysis
- preprocessing
- recursive-descent parsing
- semantic analysis
- lowered IR-style code generation
It is still a subset compiler, not a full production C implementation, but it now handles enough of the language to lex, preprocess, parse, validate, and lower non-trivial C programs with useful diagnostics.
The lexer recognizes:
- identifiers and C keywords
- integer literals, including decimal, octal, hexadecimal, and 0b-style extensions
- floating literals, including hexadecimal floats like 0x1.fp3
- string and character literals with prefixes like u8, u, U, and L
- comments, digraphs, and multi-character punctuators
The preprocessor currently supports:
- quoted includes like #include "file.h"
- local angle-bracket includes like #include <file.h>
- object-like and function-like #define
- #undef
- #if, #ifdef, #ifndef, #elif, #else, and #endif
- defined(NAME) and defined NAME expressions in #if and #elif
- macro expansion and token pasting with ##
The parser handles a meaningful C subset, including:
- typedefs, declarations, and function definitions
- pointer and array declarators
- parameter lists
- compound statements
- labels and goto
- if, for, while, do ... while, and switch
- case, default, return, break, and continue
- unary, binary, conditional, cast, call, member, and subscript expressions
- struct and union definitions with field declarations
The semantic pass performs:
- scope and symbol-table tracking
- typedef resolution
- duplicate declaration checks
- undeclared identifier checks
- function-call arity checks
- assignment and return-type validation
- struct/union tag resolution, field layout/alignment, and member-access validation for . and ->
- break, continue, case, and default validation
- label resolution for goto
- duplicate label, case, and default detection
- simple non-void return-path checks
The backend lowers parsed C code into a readable intermediate representation (IR) for a supported subset of the language. It handles control flow constructs including loops, conditionals, switch statements, labels, and goto. Basic constant folding is applied to integer expressions during lowering. While the compiler does not yet emit native assembly, this stage establishes a functional code generation pipeline and provides a solid foundation for a future machine-level backend.
Build the compiler:
makeThe binary is written to:
build/bin/C-Compiler
Run the raw lexer:
./build/bin/C-Compiler lex examples/feature_showcase.cYou can also omit lex:
./build/bin/C-Compiler examples/feature_showcase.cRun preprocessing:
./build/bin/C-Compiler preprocess examples/feature_showcase.cPrint the raw AST:
./build/bin/C-Compiler parse examples/feature_showcase.cRun semantic analysis on the preprocessed translation unit:
./build/bin/C-Compiler check examples/feature_showcase.cEmit lowered IR:
./build/bin/C-Compiler codegen examples/feature_showcase.cSemantic analysis:
semantic analysis succeeded
functions: 2
globals: 0
typedefs: 1
Code generation:
func main(void) -> int
entry:
t0 = call mix(7, 0.25)
t1 = cast int, t0
ret t1
end function
- a C11-compatible compiler such as clang or gcc
- make
- clang if you want to run make analyze
git clone <https://github.com/IzonIcy/C-Compiler>
cd C-Compiler
makeinstall -m 755 build/bin/C-Compiler /usr/local/bin/C-CompilerIf your system requires elevated permissions for /usr/local/bin, use sudo.
Run the smoke-test suite, including golden-file IR regression tests:
make testRegenerate golden files after an intentional codegen change:
UPDATE_GOLDEN=1 sh tests/golden_smoke.shRun static analysis:
make analyzeRun both:
make verifyFuzz the compiler with sanitizers (works with any compiler):
make fuzz
./build/bin/fuzz-standalone examples/*.cOn systems with the libFuzzer runtime (e.g. Linux with clang), build the coverage-guided harness instead:
make fuzz-libfuzzer
mkdir -p build/fuzz-corpus
cp examples/*.c tests/*.c build/fuzz-corpus/
./build/bin/fuzz-pipeline -max_total_time=60 build/fuzz-corpusThe repository also includes a GitHub Actions workflow at .github/workflows/ci.yml that runs compiler-matrix tests (clang and gcc), static analysis, sanitizer-backed test runs, a warnings-as-errors build, and a short fuzzing smoke run on pushes and pull requests.
This project still intentionally stops short of being a full ISO C compiler. Some notable limits:
- the preprocessor still focuses on local include resolution and common macro flows
- semantic typing is intentionally lightweight
- the backend emits textual IR, not object code or machine assembly
- advanced C constructs like bit-fields, flexible array members, and full function-pointer coverage are not complete yet