This repository is the starter code for a compiler course where each student builds their own compiler frontend for a small language with LLVM backend.
You may implement your compiler in any language you choose. In each consecutive assignment, the language grammar grows in features, and you extend your compiler to support the new syntax and semantics.
| Path | Description |
|---|---|
plan.md |
Full course plan and grammar descriptions |
doc/grammar1.md |
Reference documentation for grammar version 1 |
doc/grammar1.g4 |
ANTLR v4 grammar file for grammar version 1 (used by the fuzzer) |
doc/grammar2.md |
Reference documentation for grammar version 2 |
doc/grammar2.g4 |
ANTLR v4 grammar file for grammar version 2 |
| ... | ... (same pattern for grammars 3-5) |
doc/setup.md |
Toolchain setup: LLVM/Clang installation, compiling IR, linking with the runtime |
doc/runtime.md |
Runtime library documentation (print, println, strings) |
doc/error-handling.md |
Error handling strategy (lexer tokens, parser recovery) |
libruntime/ |
C runtime library for print/println helpers |
test/ |
Test harness, test cases and golden files (see test/README.md) |
- Fork this repository.
- Read
doc/grammar1.md— this is the first language you need to support. - Install the toolchain: see
doc/setup.mdfor LLVM/Clang installation instructions. - Set up your compiler project in the language of your choice.
- Configure the test harness to point to your compiler:
- Copy
test/config.jsonto your own config (or edit it in place). - Set the
buildcommand,stagescommands, anddefault_grammarto match your compiler. - See
test/README.mdfor the full config format.
- Copy
- Write a lexer that tokenises the grammar, outputting tokens as JSON.
- Use the test harness to run the provided lexer tests:
python3 test/run_tests.py --stage lexer --grammar 1 - Once lexer passes, implement the parser to produce an AST in JSON format.
- Then implement LLVM IR code generation so that a
.splsource can be compiled and run.
For each grammar version, new test cases (positive and negative) are provided for each stage (lexer, parser, LLVM IR, full compile-and-run).
The test harness lives in test/. Configure it to point at your own compiler
binary by editing test/config.json (or creating a separate config file).
python3 test/run_tests.py
See test/README.md for the full documentation.
The libruntime/ directory contains a small C runtime library that provides
helper functions (print_int, println_int, println, print_string,
println_string). Starting with grammar 3, your compiler can declare these as extern functions and
link with the library when producing executables.
See doc/runtime.md for the API reference and
doc/setup.md for building and linking it.
- Expressions — variables, assignments,
returnstatement (everything isInt64) - Control flow —
if/while/break/continue - Functions —
def/extern, calling C helpers - Primitive types —
Int8,Int16,Int32,Int64,Bool,String+cast - Structs and arrays — typed fields, stack-allocated arrays
The repository includes a GitHub Actions workflow (.github/workflows/tests.yml)
that runs the test harness. You will need to edit it to build your compiler
before it can run.
Refer to the course materials, ask during seminars or in chat group.