# Lower phase — L7 (the flip): status and plan (2026-10-05) Branch **`ast-stage-c`**. L7 = "flip: lower from the AST instead of inline; delete the inline emit + `Fwd*` machinery". ## Why L7 is not incremental The flip makes `Lower` the sole emitter. The obstacle is that `QbeGen` holds **one** session state, used by the inline emit *during* parse; a per-unit `Lower` emit would be clobbered by the next unit's inline emit. So the flip is a **big-bang**: either remove/suppress the grammar's 533 `QbeGen.*` call sites, or give `QbeGen` two states — neither is a byte-verifiable step. The pragmatic path is therefore a **session re-emit**: collect every unit's AST and re-emit the whole session with `Lower` after parsing. That is byte-comparable against the legacy session image and becomes the flip once the inline emit is removed. ## Started (`d30abfd`, tag `v3-lower7-scaffold`) - `Lower.LowerSession/LowerOneUnit/MaterializeGlobals`. - Driver (`compiler.frm`) collects `GetUnit()` per file and calls `Lower.LowerSession` under `-lower`. - `SymTab.Materialize` makes a unit's own VAR/CONST visible in `globScope`, so `GlobalRef` resolves `"_"` at session end (the unit scopes are closed by then). - Removed `Lower.Reset` from the `M2` root so the owned tables persist across a session. Still scaffolding (inline emit untouched); suite **200/200**, FIXPOINT OK (3,401,129 bytes). ## Gaps found (all fixable, all required for the flip) 1. **`DefUnit` builds no AST.** Its `ConstBlock/TypeBlock/VarBlock/ ProcHeading` loop never `AstAppend`s, so a definition module's AST has no decls; its proc *headings* (which consume backend temps) cannot be replayed. Fix: append to `astDecl` in `DefUnit`. 2. **Owned-table size.** `MaxProc=64` / `MaxSym=512` are sized for one unit; a full-session re-emit needs every module's procs/vars. Growing them grows the compiler image (watch the 4 MiB `sessBuf`). 3. **Nested-module globals.** `QualNode(outer, name)` does not see a nested scope's non-exported globals; `ReenterGlobals` re-enters them but with `curMod = -1` (empty `mod`), so `GlobalRef` falls back to `$name` instead of `$_`. 4. **Definition-module proc replay** must emit only the heading (`BeginFunc`/`FuncParam`/`AbortFunc`), like `LowerMethodHeadings`. 5. Possibly more, revealed once a full session is compared. ## Plan 1. Fix (1) and (4); grow tables (2) within the image budget. 2. Compare `Lower.LowerSession`'s image against the legacy session image for the compiler's own sources (the real test). 3. Fix the remaining gaps until the session image byte-matches. 4. Flip: remove the inline emit; keep `Lower` per unit; the fixpoint becomes the gate.