# Two-phase refactor — slice 6 (declarations → AST) Branch `ast-stage-c`. Suite **178/178**; self-hosting fixpoint **OK** (**3,007,851 bytes**; slice 5 was 3,000,988). ## What landed Declarations now build AST nodes. A module-level `astDecl` carries each declaration's node; `DeclSeq` folds them into an `NkDeclSeq`. | Declaration | AST | | --- | --- | | `DeclSeq` | `NkDeclSeq` of the contained declarations | | `CONST …` | `NkDeclSeq` of `NkConstDecl(name=Ident, value=expr)`, `ty` = const type | | `TYPE T = …` | `NkTypeDecl(name=Ident)`, `ty` = the resolved `SymTab.TypeIndex` | | `VAR x, y : T` | `NkVarDecl(names = Ident… )`, `ty` = the type index | | `PROCEDURE P …` | `NkProcDecl(name=Ident, body)`, `op` = 0 normal / 1 forward / 2 external | Each block (`CONST`/`VAR`) that holds several declarations builds its own `NkDeclSeq`; `DeclSeq` adds one node per block. A leading `astDecl := NoNode` in `DeclSeq`/statement loops prevents stale results. ### Design note — types by index, not by tree Declaration nodes do **not** build structural type-constructor trees (`NkRecord`, `NkArray`, …). They record the *resolved* `SymTab.TypeIndex` in the node's `ty` field, which is exactly what `AST.def` intends (`ty : ` a `SymTab.TypeIndex` set by the checker). This keeps declarations cheap and avoids duplicating the type table; a future `Lower` can read `ty` directly. `Block` now resets `astStmt := NoNode` after its `DeclSeq`, so a procedure body with no `BEGIN` yields `NoNode` instead of a stale node from a nested declaration. ## Verified (temporary `AST.Dump`, then removed) ```modula2 CONST c = 5; TYPE R = RECORD f : INTEGER END; VAR x : INTEGER; PROCEDURE P(a : INTEGER); BEGIN x := a END P; ``` produced an `NkDeclSeq`: - `NkDeclSeq[ NkConstDecl(Ident c, 5) ty=INTEGER ]` - `NkTypeDecl(Ident R) ty=` - `NkDeclSeq[ NkVarDecl(Ident x) ty=INTEGER ]` - `NkProcDecl(Ident P, NkBlock[ NkAssign(x, a) ])` ## Deliberately deferred - Unit roots (`NkUnit`), imports (`NkImport`), `CLASS` items and nested modules. - Remaining statements (`CASE`/`WITH`, builtins) and expressions (brace/set literals, `ResultComp`). - `Lower` + `.ssa` byte-compare. ## Next A unit/`NkUnit` root and imports, then the remaining statements, then the `Lower` walk (where declaration `ty`/body nodes finally replace the inline emit).