# Session handoff — 2026-10-03 (two-phase frontend, slices 1–5) State: branch **`ast-stage-c`** (off `1c93f19`, not merged to `master`). Suite **178/178**; self-hosting fixpoint **OK** (**3,021,285 bytes**). Working tree clean except the user's `compiler/toto.mod`. Plan of record: `docs/plan-two-phase.md`. Start: §4 slice 3 (statements) or §4 slice 4 (declarations). ## What landed (all inert — emitted `.ssa` unchanged, fixpoint byte-identical) | Tag | Docs | What | | --- | --- | --- | | `v3-ast-slice1` | `summary_two-phase-slice1.md` | `AST` linked into the build; `twoPhase` flag; `AST.Init` per unit | | `v3-ast-slice2` | `summary_two-phase-slice2.md` | expression spine + literals + parens + unary minus (`astCur`, per-invocation `astIsLit`) | | `v3-ast-slice3` | `summary_two-phase-slice3.md` | `Design`: identifiers, `[i]`, `.f`, `^`, qualified names | | `v3-ast-slice4` | `summary_two-phase-slice4.md` | calls/`NkCall` with actuals, `NOT`, builtins as named `NkCall`s | | `v3-ast-slice5` | `summary_two-phase-slice5.md` | statements: `NkBlock`, assign, `IF`/`WHILE`/`REPEAT`/`LOOP`/`EXIT`/`FOR`/`RETURN`/`HALT`, calls | | `v3-ast-slice6` | `summary_two-phase-slice6.md` | declarations: `NkDeclSeq`, `NkConstDecl`, `NkTypeDecl`, `NkVarDecl`, `NkProcDecl` (types by `ty` index) | | `v3-ast-slice7` | `summary_two-phase-slice7.md` | unit root `NkUnit(name, decls, body)`; builtin statements `INCL`/`INC`/`NEW`/… as `NkCall`s | | `v3-ast-slice8` | `summary_two-phase-slice8.md` | `CASE`/`WITH` statements (incremental nodes, no local arrays) | The AST is **built alongside** the existing lowering; nothing consumes it yet. Each slice was gated by `build.sh` + `run_tests.sh` + `fixpoint.sh`, and the tree shape was checked with a **temporary `AST.Dump`** in the root production (removed before each commit). ## Not converted yet (still `NoNode`) - Statements: (all core statements done; `CASE`/`WITH` as of slice 8). - Expressions: brace/set literals, `ResultComp` call suffixes. - Declarations: imports, `CLASS`, nested modules in the unit AST. - **`Lower` + `.ssa` byte-compare** (the point where the old emit path gets deleted) — not started. ## Known bug found this session **Local arrays in a `PROCEDURE` are miscompiled** (module-level arrays are fine). Repro + detail: `docs/wip/local-array-bug.mod`; observed 1, want 60. Pre-existing, unrelated to the refactor, but it bit the self-hosted fixpoint when `IfStat` used a local `ARRAY`. Worth a dedicated fix (same family as the Stage-A array-of-record stride bug). ## Design notes for the next slice - Expression result slot: module-level `astCur`, saved into locals by the combination productions; `Fact` uses a per-invocation `astIsLit` (nested facts cannot corrupt an outer one). - Statement result slot: module-level `astStmt`; `StatSeq` folds into `NkBlock`; calls use the `AstCallNode` helper over `astArgs`/`astNArgs`. - `AST` nodes: `NkDesignator(base, selectors…)`, `NkSelector(op)` with `SelField`/`SelIndex`/`SelDeref`, `NkCall(callee, actuals…)`, plus the kinds/ops in `compiler/src/AST.def` (`OpNot` was added). - **Do not use local arrays** in grammar actions until the bug above is fixed; use scalars or module-level scratch. ## Resume / verify ```sh cd ~/Projets/Projets-Modula2/MyWork/m2compiler-V3 git checkout ast-stage-c cd compiler && ./build.sh && ./run_tests.sh # 178/178 cd .. && ./bootstrap/fixpoint.sh # FIXPOINT OK ```