Branch ast-stage-c. Suite 178/178; self-hosting fixpoint OK
(3,007,851 bytes; slice 5 was 3,000,988).
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.
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.
AST.Dump, then removed)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=<record>NkDeclSeq[ NkVarDecl(Ident x) ty=INTEGER ]NkProcDecl(Ident P, NkBlock[ NkAssign(x, a) ])NkUnit), imports (NkImport), CLASS items and nested
modules.CASE/WITH, builtins) and expressions
(brace/set literals, ResultComp).Lower + .ssa byte-compare.A unit/NkUnit root and imports, then the remaining statements, then the
Lower walk (where declaration ty/body nodes finally replace the
inline emit).