Compiler Phases
The phase map from frontend checks through HIR, MIR, runtime, codegen, and later stdlib work.
Phase map
The compiler is being built in phases on purpose so each stage stays reviewable.
The plan is not a promise that every phase is complete right now. It is a dependency map that says which invariants must be true before later work can land without becoming a pile of hidden assumptions.
- Phase 1: full type checking and borrow checking.
- Phase 2: HIR lowering and desugaring.
- Phase 3: MIR construction and control-flow lowering.
- Phase 4: runtime library.
- Phase 5 and 6: LLVM codegen and runtime-backed values.
- Phase 12: dynamic stdlib policy and resolution.
Frontend invariants
The frontend is the correctness boundary, not just a parser.
- Names are resolved before later passes see them.
- Types are concrete before codegen starts.
- Borrow checking rejects invalid ownership uses early.
- The interpreter stays alive as a behavioural reference.
HIR
HIR is the typed, desugared representation the compiler can reason about without surface sugar in the way.
HIR removes the forms that are convenient for readers but awkward for lowering. It keeps the program tree-shaped, carries concrete types, and makes closures and bindings explicit so later passes do not need to rediscover surface syntax.
- F-strings become formatting primitives plus concatenation.
??,?.,?, andwhile letlower to explicit control flow.- Binding sites are assigned stable ids.
- Captured variables are listed explicitly on closures.
MIR
MIR is where the hard lowering work happens and where the control-flow graph becomes explicit.
- It is a CFG of basic blocks with explicit temporaries.
- Match lowering turns into decision trees.
- Closure conversion becomes an explicit environment value.
- Ownership lowering inserts drops and turns moves into the right operands.
Backend and runtime
LLVM stays thin, and the runtime owns the native heap model, string representation, and exported helpers.
- The backend should translate MIR instead of re-inventing semantics.
- The runtime exists so native binaries can share a stable support layer.
- Differential testing checks compiled behaviour against the interpreter.