AST.def 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. DEFINITION MODULE AST;
  2. (* Abstract syntax tree for m2compiler-V3 (Stage A: node store only).
  3. This is the foundation for a two-phase frontend: productions build
  4. nodes here while parsing, and a later walk resolves names and
  5. lowers to QBE. Until the grammar is converted, nothing calls it.
  6. Design notes
  7. ------------
  8. - Nodes live in a flat, pre-allocated arena and are referenced by an
  9. integer index (`Node`), exactly like `SymTab.TypeIndex`. This
  10. avoids pointers in the interface and keeps the structure
  11. self-hosting-friendly (no GC, bounded memory).
  12. - Every node has a `kind` (NKind) and a `ty` (a SymTab.TypeIndex set
  13. by the checker), plus up to `MaxChild` children. This mirrors the
  14. `armornick/CocoR` AST.java pattern (a Node base with per-construct
  15. subclasses) but flattened into one record array so Modula-2 can
  16. store it without variant-class machinery.
  17. - Text (identifiers, literals, operator spellings) is kept in a
  18. pooled string table; `TxtIndex` is an index into it.
  19. - `NoNode` is the null node. *)
  20. CONST
  21. NoNode = -1;
  22. NoTxt = -1;
  23. (* how many children a node may carry. Statements/expressions in
  24. Modula-2 nest shallowly (a body is a list, an expression is a
  25. spine); 8 covers every construct in the current grammar with room
  26. to spare. *)
  27. MaxChild = 8;
  28. (* ---- node kinds ----
  29. Grouped by role; the numeric values are stable and may be stored
  30. in listings. *)
  31. (* module / unit structure *)
  32. NkUnit = 0; (* [0]=name txt, [1]=decls, [2]=body *)
  33. NkDefUnit = 1;
  34. NkImplUnit = 2;
  35. NkDeclSeq = 3; (* [0..n)=declarations *)
  36. NkImport = 4; (* [0]=module txt, [1..n)=names (or FROM list) *)
  37. (* declarations *)
  38. NkConstDecl = 10; (* [0]=name txt, [1]=value expr *)
  39. NkTypeDecl = 11; (* [0]=name txt, [1]=type *)
  40. NkVarDecl = 12; (* [0..n)=name txt, [1]=type (names then type) *)
  41. NkProcDecl = 13; (* [0]=name, [1]=formals, [2]=result type,
  42. [3]=body, [4]=forward flag node *)
  43. NkClassDecl = 14;
  44. NkFieldDecl = 15;
  45. (* type constructors *)
  46. NkTypeIdent = 20; (* [0]=name txt (possibly qualified: a.b) *)
  47. NkSubrange = 21; (* [0]=lo expr, [1]=hi expr *)
  48. NkEnum = 22; (* [0..n)=literal name txts *)
  49. NkArray = 23; (* [0..n-2)=index types, [last]=element type *)
  50. NkRecord = 24; (* [0..n)=fields *)
  51. NkSet = 25; (* [0]=base type *)
  52. NkPointer = 26; (* [0]=base type *)
  53. NkProcType = 27; (* [0]=formals, [1]=result type *)
  54. (* statements *)
  55. NkAssign = 40; (* [0]=designator, [1]=value *)
  56. NkCall = 41; (* [0]=callee, [1..n)=actuals *)
  57. NkIf = 42; (* [0]=cond, [1]=then, [2]=else (or NoNode) *)
  58. NkWhile = 43; (* [0]=cond, [1]=body *)
  59. NkRepeat = 44; (* [0]=body, [1]=until cond *)
  60. NkLoop = 45; (* [0]=body *)
  61. NkExit = 46;
  62. NkFor = 47; (* [0]=control var, [1]=lo, [2]=hi, [3]=by, [4]=body *)
  63. NkCase = 48; (* [0]=selector, [1..n)=case arms *)
  64. NkCaseArm = 49; (* [0..n-1)=labels, [n]=body *)
  65. NkWith = 50; (* [0..n-1)=designators, [n]=body *)
  66. NkReturn = 51; (* [0]=expr (or NoNode) *)
  67. NkBlock = 52; (* [0..n)=statements *)
  68. NkHalt = 53;
  69. NkGoto = 54; (* [0]=label ident *)
  70. NkLabel = 55; (* [0]=label ident *)
  71. (* expressions *)
  72. NkBinExpr = 70; (* [0]=left, [1]=right; `op` holds the operator *)
  73. NkUnary = 71; (* [0]=operand; `op` holds the operator *)
  74. NkDesignator = 72; (* [0]=base, [1..n)=selectors *)
  75. NkSelector = 73; (* .field / [idx] / ^ ; `op` distinguishes *)
  76. NkIdent = 74; (* [0]=name txt, [1]=qualifier txt (or NoTxt) *)
  77. NkIntLit = 75; (* [0]=digits txt *)
  78. NkRealLit = 76;
  79. NkStrLit = 77;
  80. NkCharLit = 78;
  81. NkBraceLit = 79; (* [0]=type, [1..n)=elements *)
  82. NkSetLit = 80;
  83. (* ---- relational / arithmetic / selector operator codes ---- *)
  84. OpAdd = 0; OpSub = 1; OpOr = 2;
  85. OpMul = 3; OpDiv = 4; OpMod = 5; OpAnd = 6;
  86. OpEq = 7; OpNe = 8; OpLt = 9; OpLe = 10; OpGt = 11; OpGe = 12;
  87. OpIn = 13; OpNot = 14;
  88. (* selector codes (NkSelector.op) *)
  89. SelField = 0; SelIndex = 1; SelDeref = 2;
  90. TYPE
  91. Node = INTEGER; (* index into the arena, or NoNode *)
  92. TxtIndex = INTEGER; (* index into the text pool, or NoTxt *)
  93. (* ---------------- lifecycle ---------------- *)
  94. PROCEDURE Init;
  95. (* Clears the arena and text pool. *)
  96. (* ---------------- text pool ---------------- *)
  97. PROCEDURE AddTxt (s : ARRAY OF CHAR) : TxtIndex;
  98. (* Interns s, returning its index (deduplicated). *)
  99. PROCEDURE Txt (i : TxtIndex; VAR s : ARRAY OF CHAR);
  100. (* Copies the i-th text into s (empty when out of range). *)
  101. (* ---------------- node construction ---------------- *)
  102. PROCEDURE MakeNode (kind : INTEGER) : Node;
  103. (* A fresh node of the given kind, no children, ty = SymTab.InvalidType
  104. (the caller sets it). NoNode when the arena is full. *)
  105. PROCEDURE MakeLeaf (kind : INTEGER; name : ARRAY OF CHAR) : Node;
  106. (* A fresh node with child[0] set to the interned text of name. *)
  107. PROCEDURE MakeBin (kind, op : INTEGER; l, r : Node) : Node;
  108. (* A fresh node with op and two children (binary expr, assign, …). *)
  109. PROCEDURE MakeUn (kind, op : INTEGER; e : Node) : Node;
  110. (* A fresh node with op and one child (unary expr, selector, …). *)
  111. (* ---------------- node accessors ---------------- *)
  112. PROCEDURE Kind (n : Node) : INTEGER;
  113. PROCEDURE Op (n : Node) : INTEGER;
  114. PROCEDURE SetOp (n : Node; op : INTEGER);
  115. PROCEDURE Ty (n : Node) : INTEGER;
  116. (* The SymTab.TypeIndex attached by the checker (InvalidType until
  117. then). Declared as INTEGER to avoid a circular import with
  118. SymTab. *)
  119. PROCEDURE SetTy (n : Node; t : INTEGER);
  120. PROCEDURE NChild (n : Node) : CARDINAL;
  121. PROCEDURE Child (n : Node; i : CARDINAL) : Node;
  122. PROCEDURE AddChild (n : Node; c : Node) : BOOLEAN;
  123. PROCEDURE SetChild (n : Node; i : CARDINAL; c : Node);
  124. (* Replaces child i, extending the node when i = NChild. *)
  125. (* ---------------- listing (debug) ---------------- *)
  126. PROCEDURE Dump (n : Node; depth : CARDINAL);
  127. (* Writes a one-line-per-node indented tree to StdOut (via FileIO).
  128. Used by the Stage-A self-test and future debugging. *)
  129. END AST.