# Lower phase — slice 0 (mechanism + scalar L0 subset) Branch `ast-stage-c`. Suite **180/180** (178 + 2 Lower comparisons); self-hosting fixpoint **OK** (**3,090,949 bytes**; slice 13 was 3,042,040). Plan of record: `docs/plan-lower.md`. ## What landed The **mechanism** that lets the AST be lowered and byte-compared against the legacy emit, plus the first subset. - **`compiler/src/Lower.def/.mod`** — the walk. `CanLower(unit)` gates a unit to the supported subset; `LowerUnit(unit)` re-emits it: `OpenModule`, `SetOutName(L)`, `SetModule()`, declarations, `BeginBody`, body, `EndModule()`. - **`QbeGen.SetOutName`** (new, additive): overrides only the *image file name* used by `EndModule`, leaving the mangled symbol name unchanged — so a matching walk writes a byte-identical image to a different file. - **`-lower`** driver flag: the grammar re-emits the program unit from the AST **inside the unit's `END` action, right after the legacy `EndModule` and before `SymTab.EndUnit`** (the module scope must still be open — `Lower` resolves names through `SymTab`). - Grammar exports `SetLower`/`GetUnit`; `parser.frm`'s definition module re-exports them; `Lower` is linked like `AST`. ### L0 subset A program unit with scalar `CONST`/`VAR` and a body of `x := ` (literals/idents, `+ - * DIV MOD`, unary `-`), reproducing `Design`'s scalar emit (`LoadVar` / const `CopyOp`) and `AssOrDecl`'s scalar store, including `Fold2` constant folding. ## Verified `./M2 -lower tests/t_exit.mod` and `t_arith.mod` produce `gen_ssa/L.ssa` **byte-identical** to the legacy image (now asserted by `lower_ok` in `run_tests.sh`). ## Finding `SymTab.EndUnit` closes the module scope, so `Lower` cannot run *after* `Parse` (names no longer resolve). It must run at unit end, before `EndUnit` — and after the legacy `EndModule` so re-opening the backend does not clobber the legacy image buffer. ## Next (per `docs/plan-lower.md`) Extend the subset one step at a time — L1 relations/booleans/short-circuit, L2 control flow, L3 procedures, … — each gated by `lower_ok` + suite + fixpoint, until a unit can be lowered from the AST instead of inline (phase 3), then delete the inline emit and `Fwd*` machinery.