A compiler, with every optimization checked
minic: integers, arrays, functions, loops. Lexer, parser, type checker, SSA
intermediate representation, optimization passes, register allocation, and a bytecode VM —
written from scratch, no dependencies, no build step.
An optimization that is merely plausible is not finished. Every pass here
has to preserve the exact output bytes, the exact trap, and the exact exit status of every
program — checked against a reference interpreter across a corpus and across randomly
generated programs, with the cases where a pass would have been wrong written down rather
than quietly fixed.
Status
Phase 7 of 10. The pipeline is complete and optimizing: source becomes a syntax tree, the tree
is checked, a reference interpreter written straight from the semantics executes it, the tree is
lowered to SSA over a control flow graph, four optimization passes rewrite it, linear-scan
allocation puts values in registers, and the result becomes bytecode for a register machine built
here. All three ways of running a program are compared on all twenty-three corpus programs, at
every optimization level, byte for byte, trap positions included.
The first real measurements now exist in golden/measurements.json, written by
tools/bench.js and tools/pressure.js. This page will render from that
file rather than repeating its figures here, so that no number on it is typed in by hand —
which is phase 9's work, when the report is built.
| phase | what it adds | state |
| 0 | language specification, scaffold, CI | done |
| 1 | lexer, parser, AST, diagnostics | done |
| 2 | type checking and scope resolution | done |
| 3 | reference interpreter, corpus, golden outputs | done |
| 4 | SSA intermediate representation, IR interpreter, validator | done |
| 5 | bytecode ISA, code generation, the VM | done |
| 6 | optimization passes, and the cases they get wrong | done |
| 7 | linear-scan register allocation | done |
| 8–9 | random program testing, benchmarks, this report | not started |
| 10 | interactive playground | not started |
Why a bytecode VM
This machine has no assembler and no linker, and no emulator to run their output. Emitted
x86-64 could never be assembled, executed or differentially tested here or in CI — it
would be an artifact whose correctness is asserted rather than checked. The target is therefore
a register-based bytecode VM, built alongside the compiler, which keeps every stage executable
and keeps register allocation a real pass with real spilling. The cost, stated plainly: no
instruction selection against a real ISA, no ABI, no hardware effects, and VM instructions
executed rather than cycles as the primary metric.