A full compiler for Gazprea, a language first designed at IBM in Markham, Ontario, with vectors, matrices, intervals, tuples and streams, and values immutable by default. Built by a team of four, it ranked first in the class, and the team was invited to an online knowledge exchange with HSBI in Germany to present it. It takes source code to native programs through MLIR and LLVM, keeping the program's meaning exactly intact at every step.
What I did
- Built nine ordered checking passes between parsing and code generation, from scope and type resolution to cast validation, each reporting typed errors with line numbers
- Modelled eight kinds of types, including vectors, matrices, intervals, tuples and structs, with promotion, casting and conversion as separate services
- Generated code through six standard MLIR dialects and lowered it to LLVM IR in seven stages, with a dump after each for debugging
- Wrote a C runtime for arrays and vectors: each is a length and a data pointer on the heap, grown as needed and freed automatically when its scope ends
- Optimized the compiler's back end with LLVM's optimization pipeline, shrinking generated code by 85 to 90% across the test suite
- Ran the team of four like a product team: features split into a dependency graph so work ran in parallel, every pull request reviewed, and a protected main branch gated by CI
Highlights
Ranked #1 in the class; the team was invited to an online knowledge exchange with HSBI in Germany to present the compiler.
Cut generated code by up to 90% with LLVM optimization
The compiler produced correct but bloated code. Wiring LLVM's -O3 pass pipeline into the back end took about 30 lines and shrank the output by 85 to 90% across every test, including the hardest stress tests. It showed the value of building on a mature compiler toolchain instead of optimizing by hand.
Designed the compiler as ordered passes, each with one job
Each pass can assume the ones before it succeeded: types are resolved before they are checked, and names are resolved before qualifiers are enforced. Adding a new rule has an obvious place, and a failure points at the exact stage.
Kept a growing compiler correct with 2,101 end-to-end tests
Every feature shipped with tests that compile a real program, run it and check its output, all under a memory checker in CI. The suite grew to 2,101 programs, including deliberately hard stress tests, and AI fuzzing found edge cases the hand-written tests missed. Skills: Software Testing · CI/CD
Ran a four-person compiler build like a small engineering team
We met weekly in person for a stand-up and co-working session, run like an office: review progress, re-plan, and assign the next tasks. The work started from a thin end-to-end skeleton, then split into features mapped by what each depended on, so we could plan the critical path and keep all four people building at once. Every change was reviewed, formatting and linting ran on every commit, and nothing reached main without passing CI. Skills: Project Management · Agile Methodologies · Team Leadership · Code Review · CI/CD
C++ · ANTLR4 · MLIR · LLVM