# m2compiler-V3 — feature status (at `v3-step4`, 87/87 green) Pipeline: Coco/R `M2.atg` (1748 lines, 73 productions) → `gm2`-built `M2` → QBE `.ssa` → `qbe` → `cc` → run. `SymTab.mod` 1623 lines, `QbeGen.mod` 2193 lines. Regenerate with `cd compiler && ./build.sh && ./run_tests.sh`. Legend: ✅ done · 🔄 partial · ⏸ not started / deferred. ## Lexical / syntax - ✅ Classic idents (no `_`), `0x`/`0X` hex (no `H`), reals with `E` exponents, `#` `<` `<=` `>` `>=` `=`, `//` + nested `(* *)`, strings `'…'`/`"…"`, `0x` array bounds. - ✅ `NOT`/`AND`/`OR` (no `~`/`&`), unary minus at expr start, no octal `B`/`C` suffixes. ## Types - ✅ `INTEGER`/`CARDINAL`/`SHORTINT`/`LONGINT` (one family, QBE `w`), `REAL`/`LONGREAL` (`d`, widened), `BOOLEAN`, `CHAR`. - ✅ Named types, aliases, integer/char subranges (folded bounds), enumerations declared (literal *use* is 230). - ✅ `ARRAY [lo..hi,…]` (multi-dim) and open `ARRAY OF` formals. - ✅ `RECORD` (flat blobs, nested inline, array fields as pointers). - ✅ `SET OF` bool/char/subrange (multi-word masks). - ✅ `POINTER TO`, `NIL` as a real type. - ✅ Opaque `TYPE T;` + completion in the implementation. - ⏸ Enums in expressions/CASE labels, variant records, procedure types, `LONGINT` quads. ## Declarations - ✅ `CONST` (integer/char/real literals, folded), `VAR`, `TYPE`, `PROCEDURE` headings + bodies, `FORWARD`. - ✅ `DEFINITION`/`IMPLEMENTATION` modules, `IMPORT`/`FROM … IMPORT`, `EXPORT` (parsed), nested local `MODULE` (parsed; lowering pending). - ✅ Opaque completion; module `BEGIN` init bodies. - ⏸ Strict 231 impl-vs-def signature checks (arity checked, types not). ## Statements - ✅ Assignment, `IF/ELSIF/ELSE`, `CASE` (labels, ranges, `ELSE`), `WHILE`, `REPEAT/UNTIL`, `LOOP/EXIT`, `FOR/TO/BY` (static sign), `WITH` (single/multi/nested), `RETURN` (232-checked), `NEW`/`DISPOSE` (builtins), bare and parenthesized calls. - ⏸ `HIGH`/`LEN`, `GOTO`/labels. ## Expressions - ✅ Full precedence, `+ - * / DIV MOD`, comparisons, eager `AND`/`OR`/`NOT`, `IN`, set ops (`+ - * /` = union/diff/inter/symdiff), pointer `=`/`#`, int→real conversion, `^` deref, indexing, field access, qualified `L.x`/`L.P`. - ✅ `NIL` comparisons/assignment. - ⏸ String `=`/`+`, `VAL`/`ADR`/`TSIZE`/`SIZE` builtins, result suffixes (`F()^`). ## Procedures & modules - ✅ Value + `VAR` params, function results, recursion, mutual recursion (`FORWARD`), nested procedures with static-link display (any depth), array/record/set/pointer params, open-array `VAR` formals. - ✅ Separate compilation: `lib.def lib.mod prog.mod` → one image; module init functions; opaque completion. - ⏸ Procedure-type variables / indirect calls, per-file object emission, import cycles. ## Backend (QBE) - ✅ Length-prefixed arrays (count + elements), deep record copy, count-checked whole-array assign, runtime bounds/span traps (`$abort`, rc 134), multi-word sets, `alloc8` heap (`malloc`/`free`), static-link frames, deterministic `%tN`/`@LN`, whole-image buffering. - ✅ `REAL` runtime const flush, string literals as descriptors. - ⏸ `runtime/syslib/Trap` (traps are `$abort` for now), recursive `DISPOSE`. ## Error codes - ✅ 200/201/202, 210–222, 223 (declared), 230, 231, 232, **233 `invalid call`**, plus `file:line:col` console format. ## Not started - ⏸ Clarion `CLASS` lowering (declared + checked only), Unicode `UCHAR`/`UString` (locked design, no lexer/backing), `stdlib` / `runtime/syslib` libraries, self-hosting fixpoint. The TopSpeed legacy grammar (`TopSpeed-V3-M2.atg`) is a separate sidecar, not merged. Next: step 5 — Benjamin stdlib (first real use of separate compilation). Roadmap: `docs/plan.md`, `docs/blaise-phases-map.md`.