Rust-Based Compiler for a Mini-Language with Control Flow and LLVM Trivial SSA Generation
This project is a Rust command-line compiler that tokenizes, parses, and lowers a small imperative language into LLVM IR using trivial SSA (alloca, store, load). It extends a recursive-descent parser to support full control flow (ifβthenβelse, while) and produces executable LLVM IR that can be compiled and run with clang.
- Recursive-Descent Parser implementing a top-down grammar with left-recursion removed:
EXPR β TERM EXPRDASH
EXPRDASH β + TERM EXPRDASH | Ξ΅
TERM β FACTOR TERMDASH
TERMDASH β * FACTOR TERMDASH | Ξ΅
FACTOR β IDENTIFIER | NUMBER | ( EXPR )
-
Scanner recognizes identifiers ([A-Za-z]+), numbers ([0-9]+), +, *, (, ), and skips whitespace.
-
Control-Flow Codegen:
- Lowers if into LLVM blocks:
br i1 %cond, label %if.then, label %if.else- Lowers while into canonical loop form:
br label %while.cond while.cond: %cmp = icmp ... br i1 %cmp, label %while.body, label %while.end -
LLVM IR Generation (Trivial SSA):
- Allocates stack slots for all variables:
%x.alloc = alloca i64- Loads and stores using typed instructions:
store i64 %t1, ptr %x.alloc %t2 = load i64, ptr %x.alloc- Always emits valid i64 IR compatible with clang.
-
Programming Languages/Technologies: Rust, Cargo, C, Makefile
-
Compiler Backend: LLVM IR code generation
-
Build Automation: Makefile (multi-test automation + SDK detection)
-
Key Modules:
scanner.rs β Lexical analysis parser.rs β Recursive-descent parsing ast.rs β AST data structure + BFS printer llvm_codegen.rs β LLVM IR emitter main.rs β Entry point
# Build compiler
cargo build
# Run a program
make exec PROG=programs/pdf_example.rucomp DRIVER=c_driver/driver1.c
# Check IR structure (sanity checks)
make check-ir PROG=programs/pdf_example.rucomp
-
Add constant folding
-
Add SSA optimization pass (extra credit)
- Kelvin Ihezue