DEFINITION MODULE AST; (* Abstract syntax tree for M2comp step 3. Recipe: H. Mössenböck, "How to Build Abstract Syntax Trees with Coco/R" (docs/AST.pdf) — every nonterminal builds its subtree via output attributes, with plain semantic actions (no special notation). Nodes are heap pointer records with child links (left/right/extra/ more) and a sibling link (next), mirroring the dsc/next shape of the Oberon SymTable (docs/oberon-master) while SymTab itself stays flat. Types are stored as descriptor indices (SymTab.TypeIndex, seen here as INTEGER to keep coupling one-way); there is no separate type subtree. Error-tolerant: nodes are built even when the type is InvalidType, so dumps exist for rejected sources too. *) CONST (* declaration nodes *) nkNone = 0; nkModule = 1; (* name; left=decl chain; right=block *) nkBlock = 2; (* left=decl chain; right=stmt chain *) nkImport = 3; (* name=module ("" for plain IMPORT); left=names *) nkImpName = 4; (* name *) nkExport = 5; (* left=names *) nkConst = 6; (* name; typ; left=expr *) nkTypeDecl = 7; (* name; typ *) nkVar = 8; (* name; typ *) nkMember = 9; (* record field name; typ *) nkParam = 10; (* name; typ; op=ORD(isVar) *) nkProc = 11; (* name; typ=rettype; left=params; right=block *) (* statement nodes *) nkAssign = 20; (* left=dst; right=src *) nkCall = 21; (* left=callee designator; right=actuals; num=pnum *) nkIf = 22; (* left=cond; right=then; extra=else-or-nil *) nkWhile = 23; (* left=cond; right=body *) nkRepeat = 24; (* left=body; right=cond *) nkLoop = 25; (* left=body *) nkFor = 26; (* name=control var; left=lo; right=hi; extra=by-or-nil; more=body *) nkReturn = 27; (* left=expr-or-nil *) nkExit = 28; (* expression nodes *) nkBin = 30; (* op=SymTab op code (OpIn for IN); left; right *) nkUn = 31; (* op=opNot/opNeg/opPos; left *) nkName = 32; (* name; typ *) nkInt = 33; (* num=value; typ *) nkReal = 34; (* text; typ *) nkChar = 35; (* num=ORD; typ *) nkStr = 36; (* text; typ *) nkField = 37; (* left=record; name=field; typ *) nkIndex = 38; (* left=array; right=index chain; typ *) nkDeref = 39; (* left; typ *) nkCallExpr = 40; (* left=callee; right=actuals; num=pnum; typ=ret *) (* unary operator codes (binary ones reuse SymTab op codes) *) opNot = 1; opNeg = 2; opPos = 3; TYPE Node = POINTER TO NodeRec; NodeRec = RECORD kind: INTEGER; typ: INTEGER; op: INTEGER; num: INTEGER; name: ARRAY [0 .. 63] OF CHAR; text: ARRAY [0 .. 63] OF CHAR; left, right, extra, more, next: Node; END; PROCEDURE New (kind: INTEGER): Node; (* Fresh node, all links NIL, typ InvalidType (-1). *) PROCEDURE SetRoot (n: Node); PROCEDURE GetRoot (): Node; (* Module root for the driver dump. *) PROCEDURE Append (head, tail: Node): Node; (* NIL-safe sibling append; returns head (or tail). *) PROCEDURE SetChainType (head: Node; t: INTEGER); (* Assigns typ to every node of a sibling chain (VAR/FP/field identifier lists whose type is parsed afterwards). *) PROCEDURE MkName (nm: ARRAY OF CHAR; t: INTEGER): Node; PROCEDURE MkInt (v: INTEGER; t: INTEGER): Node; PROCEDURE MkChar (v: INTEGER; t: INTEGER): Node; PROCEDURE MkReal (tx: ARRAY OF CHAR; t: INTEGER): Node; PROCEDURE MkStr (tx: ARRAY OF CHAR; t: INTEGER): Node; PROCEDURE MkBin (op: INTEGER; l, r: Node; t: INTEGER): Node; PROCEDURE MkUn (op: INTEGER; e: Node; t: INTEGER): Node; PROCEDURE MkField (rec: Node; field: ARRAY OF CHAR; t: INTEGER): Node; PROCEDURE MkIndex (arr, idx: Node; t: INTEGER): Node; PROCEDURE MkDeref (p: Node; t: INTEGER): Node; PROCEDURE MkCallExpr (callee, actuals: Node; pnum, t: INTEGER): Node; PROCEDURE MkAssign (dst, src: Node): Node; PROCEDURE MkCall (callee, actuals: Node; pnum: INTEGER): Node; PROCEDURE MkIf (c, th, el: Node): Node; PROCEDURE MkWhile (c, body: Node): Node; PROCEDURE MkRepeat (body, c: Node): Node; PROCEDURE MkLoop (body: Node): Node; PROCEDURE MkFor (nm: ARRAY OF CHAR; lo, hi, by, body: Node): Node; PROCEDURE MkReturn (e: Node): Node; PROCEDURE MkExit (): Node; PROCEDURE MkBlock (decls, stmts: Node): Node; PROCEDURE MkModule (nm: ARRAY OF CHAR; decls, body: Node): Node; PROCEDURE MkProc (nm: ARRAY OF CHAR; ret: INTEGER; params, body: Node): Node; PROCEDURE MkConst (nm: ARRAY OF CHAR; e: Node; t: INTEGER): Node; PROCEDURE MkTypeDecl (nm: ARRAY OF CHAR; t: INTEGER): Node; PROCEDURE MkVar (nm: ARRAY OF CHAR; t: INTEGER): Node; PROCEDURE MkMember (nm: ARRAY OF CHAR; t: INTEGER): Node; PROCEDURE MkParam (nm: ARRAY OF CHAR; t: INTEGER; isVar: BOOLEAN): Node; PROCEDURE MkImport (mod: ARRAY OF CHAR; names: Node): Node; PROCEDURE MkImpName (nm: ARRAY OF CHAR): Node; PROCEDURE MkExport (names: Node): Node; PROCEDURE ParseInt (tx: ARRAY OF CHAR; VAR v: INTEGER): BOOLEAN; (* Decimal or H-suffixed hex integer literal text to value. *) PROCEDURE DumpTree (n: Node); (* Indented dump of the tree to StdOut (NIL-safe, depth-capped). *) END AST.