SymTab.def 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. DEFINITION MODULE SymTab;
  2. IMPORT AST;
  3. (* Symbol table with static type checking for the M2comp compiler
  4. (Modula-2 program modules, step 2: semantic analysis, no codegen).
  5. Base: Test1 SimpleMod2 table (flat scopes with levels, type
  6. descriptors with aliases, integer-family leniency, InvalidType
  7. cascade suppression). Extensions for step 2:
  8. - procedures: nested, value/VAR params, function results; signatures
  9. persist in procs[] after body scopes pop (no FORWARD headings)
  10. - local modules (Wirth form): body scope + export table for M.x
  11. - call checking with an 8-deep frame stack (nested calls safe);
  12. invalid callees get a dead frame to suppress cascades
  13. - open arrays (formal-only) + WrapArray/IsOpen helpers
  14. - loop-depth tracking for EXIT validation (230)
  15. Error codes follow m2c/Test1: 200 duplicate, 201 undeclared,
  16. 202 name mismatch, 210 bad assignment, 211 arithmetic, 212 boolean
  17. operand, 213 comparison, 214 condition, 215 not a record,
  18. 216 unknown field, 217 not an array, 218 bad index, 219 not a
  19. pointer, 220 FOR misuse, 221 not a type, 222 set mismatch,
  20. 223 cyclical type, 224 ordinal required, 230 unsupported construct
  21. (EXIT outside LOOP, open array outside formal), 232 bad RETURN,
  22. 233 invalid call. 231 (forward mismatch) unused: no FORWARD.
  23. - flat scopes with levels: globals at level 0 (duplicates within
  24. one level rejected, shadowing allowed in nested scopes)
  25. - every symbol carries a type descriptor index (InvalidType if
  26. unknown, e.g. imported names); unknown types suppress follow-on
  27. errors to avoid cascades *)
  28. CONST
  29. MaxSyms = 256;
  30. InvalidType = -1;
  31. (* symbol kinds *)
  32. KindConst = 0;
  33. KindType = 1;
  34. KindVar = 2;
  35. KindImport = 3;
  36. KindModule = 4;
  37. KindPredef = 5;
  38. KindField = 6;
  39. KindProc = 7;
  40. KindParam = 8;
  41. KindVarPar = 9;
  42. (* type classes returned by ClassOf *)
  43. ClInvalid = 0;
  44. ClInt = 1;
  45. ClReal = 2;
  46. ClChar = 3;
  47. ClBool = 4;
  48. ClEnum = 5;
  49. ClArray = 6;
  50. ClRecord = 7;
  51. ClSet = 8;
  52. ClPtr = 9;
  53. ClStr = 10;
  54. (* operator codes; all groups use distinct ranges so a
  55. tree-walking backend can dispatch on the code alone *)
  56. OpEq = 20; OpNeq1 = 21; OpNeq2 = 22;
  57. OpLt = 23; OpLe = 24; OpGt = 25; OpGe = 26;
  58. OpIn = 27;
  59. (* operator codes for AddOp / MulOp; MulOp codes are offset *)
  60. OpAdd = 0; OpSub = 1; OpOr = 2;
  61. OpTimes = 10; OpSlash = 11; OpDiv = 12; OpMod = 13; OpAnd = 14;
  62. TYPE
  63. Name = ARRAY [0 .. 63] OF CHAR;
  64. TypeIndex = INTEGER;
  65. BoundsArr = ARRAY [0 .. 7] OF INTEGER;
  66. (* Per-dimension bounds for WrapArrayB (Coco/R attribute type). *)
  67. (* ---------------- symbols and scopes ---------------- *)
  68. PROCEDURE Init;
  69. (* Clears the table and enters predefined identifiers
  70. (INTEGER, CARDINAL, SHORTINT, LONGINT, REAL, LONGREAL, CHAR,
  71. BOOLEAN, TRUE, FALSE, NIL). *)
  72. PROCEDURE Enter (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  73. (* Enters name at the current scope level (type InvalidType).
  74. Returns FALSE on duplicate within the same level. *)
  75. PROCEDURE EnterPending (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  76. (* Like Enter, but remembers the entry for a later FixPending call
  77. (used for VAR identifier lists whose type is parsed afterwards).
  78. Returns FALSE on duplicate (entry not recorded). *)
  79. PROCEDURE FixPending (t: TypeIndex);
  80. (* Assigns type t to all pending entries, clears the buffer. *)
  81. PROCEDURE FieldPending (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  82. (* Records a field name for record descriptor rec (type fixed later
  83. with FixPendingF). Returns FALSE on duplicate field. *)
  84. PROCEDURE FixPendingF (rec: TypeIndex; t: TypeIndex);
  85. (* Assigns type t to pending fields owned by rec. *)
  86. PROCEDURE Lookup (name: ARRAY OF CHAR): BOOLEAN;
  87. (* TRUE if name is visible (innermost scope wins). *)
  88. PROCEDURE SymType (name: ARRAY OF CHAR): TypeIndex;
  89. (* Type of innermost visible entry, InvalidType if absent. *)
  90. PROCEDURE SetSymType (name: ARRAY OF CHAR; t: TypeIndex);
  91. (* Sets type of innermost visible entry. *)
  92. PROCEDURE SymKind (name: ARRAY OF CHAR): INTEGER;
  93. (* Kind of innermost visible entry, -1 if absent. *)
  94. PROCEDURE Equal (a, b: ARRAY OF CHAR): BOOLEAN;
  95. PROCEDURE PushScope;
  96. PROCEDURE PopScope;
  97. (* WITH statement support: PushRecord pushes a record's fields. *)
  98. PROCEDURE PushRecord (t: TypeIndex): BOOLEAN;
  99. (* Pushes a scope containing t's fields (as KindField). FALSE if t
  100. is not a record type (or invalid). Caller must PopScope after.
  101. Kept for a future WITH statement; unused by the step-2 grammar. *)
  102. PROCEDURE PrintTable;
  103. (* ---------------- procedures ---------------- *)
  104. (* Signatures live in procs[]/params[] keyed by a per-procedure number
  105. stored on the symbol, so they survive PopScope (nested and exported
  106. procedures stay callable). No FORWARD headings in step 2. *)
  107. PROCEDURE EnterProc (name: ARRAY OF CHAR): BOOLEAN;
  108. (* Enters a KindProc name in the current scope, assigns the next proc
  109. number with an empty signature. FALSE on duplicate or table full.
  110. Sets the current-proc context for EnterParamPending calls. *)
  111. PROCEDURE OpenProcScope;
  112. (* Pushes a body scope for the current procedure (depth + 1, fresh
  113. return-type context). *)
  114. PROCEDURE CloseProc;
  115. (* Pops the procedure body scope, restores the enclosing context. *)
  116. PROCEDURE EnterParamPending (name: ARRAY OF CHAR; isVar: BOOLEAN): BOOLEAN;
  117. (* Like EnterPending for FPSection identifier lists whose type is
  118. parsed afterwards. FALSE on duplicate (not recorded). *)
  119. PROCEDURE FixParamPending (t: TypeIndex): BOOLEAN;
  120. (* Enters all pending parameters of the current procedure with type t
  121. (KindParam or KindVarPar), appends them to its signature. FALSE if
  122. any entry failed (duplicate or table full). *)
  123. PROCEDURE SetProcRet (t: TypeIndex);
  124. (* Sets the return type of the current procedure (InvalidType =
  125. proper procedure) and of the current return-type context. *)
  126. PROCEDURE ProcNum (name: ARRAY OF CHAR): INTEGER;
  127. (* Proc number of the visible procedure, or -1 if absent / not one. *)
  128. PROCEDURE ProcRet (name: ARRAY OF CHAR): TypeIndex;
  129. PROCEDURE ProcNPar (name: ARRAY OF CHAR): CARDINAL;
  130. PROCEDURE ParamType (name: ARRAY OF CHAR; i: CARDINAL): TypeIndex;
  131. PROCEDURE ParamIsVar (name: ARRAY OF CHAR; i: CARDINAL): BOOLEAN;
  132. (* Signature queries by name (InvalidType/0/FALSE if absent). *)
  133. PROCEDURE ProcRetByNum (num: INTEGER): TypeIndex;
  134. PROCEDURE ProcNParByNum (num: INTEGER): CARDINAL;
  135. PROCEDURE ParamTypeByNum (num: INTEGER; i: CARDINAL): TypeIndex;
  136. PROCEDURE ParamIsVarByNum (num: INTEGER; i: CARDINAL): BOOLEAN;
  137. (* Same queries keyed by procedure number (exported module procs). *)
  138. PROCEDURE InProc (): BOOLEAN;
  139. (* TRUE inside a procedure body. *)
  140. PROCEDURE InFunction (): BOOLEAN;
  141. (* TRUE inside a function (non-InvalidType return) body. *)
  142. PROCEDURE CurRet (): TypeIndex;
  143. (* Current return type (InvalidType = proper procedure or outside). *)
  144. (* ---------------- local modules (Wirth form) ---------------- *)
  145. (* Local MODULEs nest at any level. EXPORT names resolve at END into
  146. the export table keyed by (module, name); M.x qualified access
  147. consults it, or the live body scope from inside M itself. *)
  148. PROCEDURE EnterModule (name: ARRAY OF CHAR): BOOLEAN;
  149. (* Enters KindModule + pushes the body scope + module context.
  150. FALSE on duplicate. *)
  151. PROCEDURE ModuleAddExp (name: ARRAY OF CHAR): BOOLEAN;
  152. (* Records an export name for the current module. FALSE if not in a
  153. module, on duplicate, or when the export list is full. *)
  154. PROCEDURE ExitModule (): BOOLEAN;
  155. (* Resolves exports against the body scope into the export table,
  156. pops scope + context. FALSE when an EXPORT name was not declared
  157. (ghost export). *)
  158. PROCEDURE InModule (): BOOLEAN;
  159. (* TRUE inside a local MODULE body (including its procedures). *)
  160. PROCEDURE CurModName (VAR m: Name);
  161. (* Innermost module name, empty if none. *)
  162. PROCEDURE ExpKind (mod, exp: ARRAY OF CHAR): INTEGER;
  163. (* Exported kind, -1 if absent. *)
  164. PROCEDURE ExpType (mod, exp: ARRAY OF CHAR): TypeIndex;
  165. (* Exported type (InvalidType if absent / not a typed export). *)
  166. PROCEDURE ExpProc (mod, exp: ARRAY OF CHAR): INTEGER;
  167. (* Exported proc number, -1 if absent / not a procedure. *)
  168. PROCEDURE SelfKind (mod, exp: ARRAY OF CHAR): INTEGER;
  169. (* Kind of exp as M.exp from inside M itself (live body scope at
  170. body level, since exports resolve only at END). -1 if absent. *)
  171. PROCEDURE SelfType (mod, exp: ARRAY OF CHAR): TypeIndex;
  172. (* Type of an M.exp self reference (InvalidType if absent). *)
  173. PROCEDURE SelfProc (mod, exp: ARRAY OF CHAR): INTEGER;
  174. (* Proc number of an M.exp self reference (-1 if absent). *)
  175. (* ---------------- call checking ---------------- *)
  176. (* An 8-deep frame stack keeps nested calls (f(g(x))) safe. A dead
  177. frame (proc -1) accepts everything: the grammar pushes one for
  178. invalid callees so actuals parse without cascade errors. *)
  179. PROCEDURE CallBeginNum (num: INTEGER);
  180. (* Opens a call frame for procedure num (-1 = dead frame). *)
  181. PROCEDURE CallActual (t: TypeIndex; isVar: BOOLEAN): BOOLEAN;
  182. (* Checks one actual against the current formal (VAR formals need a
  183. storable designator of identical type, value formals need
  184. assignment compatibility) and advances. FALSE on mismatch. *)
  185. PROCEDURE CallEndNum (n: CARDINAL): BOOLEAN;
  186. (* Closes the frame; FALSE on arity mismatch (n # formals). *)
  187. (* ---------------- loops ---------------- *)
  188. PROCEDURE LoopEnter;
  189. PROCEDURE LoopExit;
  190. PROCEDURE InLoop (): BOOLEAN;
  191. (* Innermost LOOP tracking for EXIT validation (error 230). *)
  192. (* ---------------- type descriptors ---------------- *)
  193. PROCEDURE NewAlias (): TypeIndex;
  194. PROCEDURE NewSub (base: TypeIndex): TypeIndex;
  195. PROCEDURE NewEnum (): TypeIndex;
  196. PROCEDURE NewArray (elem: TypeIndex): TypeIndex;
  197. PROCEDURE NewOpen (elem: TypeIndex): TypeIndex;
  198. PROCEDURE WrapArray (elem: TypeIndex; dims: CARDINAL): TypeIndex;
  199. (* WrapArray nests elem in dims ARRAY levels (dims = 0 gives an open
  200. array). Open arrays are formal-only (grammar reports 230). *)
  201. PROCEDURE IsOpen (t: TypeIndex): BOOLEAN;
  202. PROCEDURE NewSubB (base: TypeIndex; lo, hi: INTEGER): TypeIndex;
  203. PROCEDURE NewArrayB (elem: TypeIndex; lo, hi: INTEGER): TypeIndex;
  204. PROCEDURE WrapArrayB (elem: TypeIndex; los, his: BoundsArr;
  205. dims: CARDINAL): TypeIndex;
  206. (* Bounded nesting for ARRAY index lists (dims = 0 gives an open
  207. array). Bounds come from folded index expressions (grammar). *)
  208. PROCEDURE IndexBounds (t: TypeIndex; VAR lo, hi: INTEGER): BOOLEAN;
  209. (* Finite bounds of an index type: subrange (stored), CHAR (0..255),
  210. BOOLEAN (0..1). FALSE for INTEGER/CARDINAL (unbounded) and
  211. anything else (grammar reports 230). *)
  212. PROCEDURE ArrayLo (t: TypeIndex): INTEGER;
  213. PROCEDURE ArrayHi (t: TypeIndex): INTEGER;
  214. PROCEDURE ArrayLen (t: TypeIndex): CARDINAL;
  215. PROCEDURE TypeSlots (t: TypeIndex): CARDINAL;
  216. (* Stack slots for a value: 1 per scalar/pointer/set, len*elem for
  217. arrays, summed members for records. Cycle-guarded. *)
  218. PROCEDURE FieldOffset (rec: TypeIndex; name: ARRAY OF CHAR): INTEGER;
  219. (* Slot offset of a record field in declaration order. *)
  220. PROCEDURE NewRecord (): TypeIndex;
  221. PROCEDURE NewSet (base: TypeIndex): TypeIndex;
  222. PROCEDURE NewPtr (base: TypeIndex): TypeIndex;
  223. PROCEDURE NewStr (): TypeIndex;
  224. (* Fresh descriptors; base/elem may be InvalidType. InvalidType is
  225. returned when the table is full. *)
  226. PROCEDURE SetTarget (t, base: TypeIndex);
  227. (* Sets an alias target (TYPE declaration completion). *)
  228. PROCEDURE IntType (): TypeIndex;
  229. PROCEDURE RealType (): TypeIndex;
  230. PROCEDURE CharType (): TypeIndex;
  231. PROCEDURE BoolType (): TypeIndex;
  232. PROCEDURE ClassOf (t: TypeIndex): INTEGER;
  233. (* Resolves aliases; InvalidType maps to ClInvalid. *)
  234. PROCEDURE IsIntFamily (t: TypeIndex): BOOLEAN;
  235. (* INTEGER, CARDINAL or subrange thereof (Invalid suppresses). *)
  236. PROCEDURE SameType (a, b: TypeIndex): BOOLEAN;
  237. (* Same resolved descriptor (Invalid suppresses). *)
  238. PROCEDURE FieldExists (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  239. PROCEDURE FieldType (rec: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
  240. PROCEDURE ArrayElem (t: TypeIndex): TypeIndex;
  241. PROCEDURE PtrBase (t: TypeIndex): TypeIndex;
  242. (* ---------------- predicates used by grammar checks ---------------- *)
  243. (* All return TRUE if either operand is InvalidType (no cascades). *)
  244. PROCEDURE Assignable (src, dst: TypeIndex): BOOLEAN;
  245. (* Assignment compatibility (210). *)
  246. PROCEDURE ArithCheck (l, r: TypeIndex; divmod: BOOLEAN;
  247. VAR res: TypeIndex): BOOLEAN;
  248. (* + - * / (divmod FALSE) or DIV MOD (TRUE); res is result type (211). *)
  249. PROCEDURE UnaryCheck (t: TypeIndex; VAR res: TypeIndex): BOOLEAN;
  250. (* Unary + - (part of 211). *)
  251. PROCEDURE BoolCheck (t: TypeIndex): BOOLEAN;
  252. (* BOOLEAN required: NOT/AND/OR operands (212), conditions (214). *)
  253. PROCEDURE RelCheck (l, r: TypeIndex; op: INTEGER): BOOLEAN;
  254. (* = # <> < <= > >= IN (213/222 chosen by caller via op). *)
  255. PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
  256. (* = # compatibility, also reused for CASE label matching. *)
  257. PROCEDURE InCheck (l, set: TypeIndex): BOOLEAN;
  258. PROCEDURE SetElemCheck (first, elem: TypeIndex): BOOLEAN;
  259. PROCEDURE SetFor (elem: TypeIndex): TypeIndex;
  260. (* Fresh SET OF elem descriptor for set literals. *)
  261. PROCEDURE StrLen (s: ARRAY OF CHAR): CARDINAL;
  262. (* ---------------- compile-time constants ---------------- *)
  263. (* Integer values of CONST declarations, recorded at parse time for
  264. array/subrange bound folding (grammar) and MGen lookups. Chained
  265. consts fold (Neg = -N + 2 with N = 10 gives -8); anything else
  266. stays undefined (bounds then report 230). *)
  267. PROCEDURE NoteConst (name: ARRAY OF CHAR; v: INTEGER; ok: BOOLEAN);
  268. (* Records the folded value of a just-declared CONST (ok = foldable). *)
  269. PROCEDURE ConstVal (name: ARRAY OF CHAR; VAR v: INTEGER): BOOLEAN;
  270. (* Value of the visible integer CONST (TRUE/FALSE predefs included);
  271. FALSE if absent, non-const, or undefined. *)
  272. PROCEDURE ConstFold (n: AST.Node; VAR v: INTEGER): BOOLEAN;
  273. (* Folds nkInt / nkUn(+/-) / const nkName nodes. Needs AST import. *)
  274. END SymTab.