SymTab.def 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. DEFINITION MODULE SymTab;
  2. (* Symbol table with static type checking for the M2c compiler
  3. (Modula-2 program modules, procedures arrive in a later phase).
  4. - flat scopes with levels: globals at level 0, WITH statement
  5. bodies push the record's fields as an inner scope (shadowing
  6. allowed, duplicates within one level rejected)
  7. - every symbol carries a type descriptor index (InvalidType if
  8. unknown, e.g. imported names); unknown types suppress follow-on
  9. errors to avoid cascades
  10. - type descriptors: aliases (one per TYPE declaration, so
  11. self-references such as POINTER TO Person resolve), subranges,
  12. enumerations, arrays, records (with field lists), sets,
  13. pointers, predefined types, string literals
  14. - INTEGER, CARDINAL and subranges thereof form one lenient
  15. "integer family"; mixed INTEGER/REAL arithmetic is rejected *)
  16. CONST
  17. MaxSyms = 256;
  18. InvalidType = -1;
  19. (* symbol kinds *)
  20. KindConst = 0;
  21. KindType = 1;
  22. KindVar = 2;
  23. KindImport = 3;
  24. KindModule = 4;
  25. KindPredef = 5;
  26. KindField = 6;
  27. KindProc = 7;
  28. KindParam = 8;
  29. KindVarPar = 9;
  30. (* type classes returned by ClassOf *)
  31. ClInvalid = 0;
  32. ClInt = 1;
  33. ClReal = 2;
  34. ClChar = 3;
  35. ClBool = 4;
  36. ClEnum = 5;
  37. ClArray = 6;
  38. ClRecord = 7;
  39. ClSet = 8;
  40. ClPtr = 9;
  41. ClStr = 10;
  42. (* operator codes for RelCheck *)
  43. OpEq = 0; OpNeq1 = 1; OpNeq2 = 2;
  44. OpLt = 3; OpLe = 4; OpGt = 5; OpGe = 6;
  45. OpIn = 7;
  46. (* operator codes for AddOp / MulOp *)
  47. OpAdd = 0; OpSub = 1; OpOr = 2;
  48. OpTimes = 0; OpSlash = 1; OpDiv = 2; OpMod = 3; OpAnd = 4;
  49. TYPE
  50. Name = ARRAY [0 .. 63] OF CHAR;
  51. TypeIndex = INTEGER;
  52. (* ---------------- symbols and scopes ---------------- *)
  53. PROCEDURE Init;
  54. (* Clears the table and enters predefined identifiers
  55. (INTEGER, CARDINAL, SHORTINT, LONGINT, REAL, LONGREAL, CHAR,
  56. BOOLEAN, TRUE, FALSE, NIL). *)
  57. PROCEDURE Enter (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  58. (* Enters name at the current scope level (type InvalidType).
  59. Returns FALSE on duplicate within the same level. *)
  60. PROCEDURE EnterPending (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  61. (* Like Enter, but remembers the entry for a later FixPending call
  62. (used for VAR identifier lists whose type is parsed afterwards).
  63. Returns FALSE on duplicate (entry not recorded). *)
  64. PROCEDURE FixPending (t: TypeIndex);
  65. (* Assigns type t to all pending entries, clears the buffer. *)
  66. PROCEDURE PendCount (): CARDINAL;
  67. (* Number of entries currently waiting for FixPending. *)
  68. PROCEDURE PendName (i: CARDINAL; VAR n: Name);
  69. (* Name of the i-th pending entry (empty string if out of range).
  70. Used by the backend to emit storage for VAR lists whose
  71. type is parsed after the identifiers. *)
  72. PROCEDURE FieldPending (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  73. (* Records a field name for record descriptor rec (type fixed later
  74. with FixPendingF). Returns FALSE on duplicate field. *)
  75. PROCEDURE FixPendingF (rec: TypeIndex; t: TypeIndex);
  76. (* Assigns type t to pending fields owned by rec. *)
  77. PROCEDURE Lookup (name: ARRAY OF CHAR): BOOLEAN;
  78. (* TRUE if name is visible (innermost scope wins). *)
  79. PROCEDURE SymType (name: ARRAY OF CHAR): TypeIndex;
  80. (* Type of innermost visible entry, InvalidType if absent. *)
  81. PROCEDURE SetSymType (name: ARRAY OF CHAR; t: TypeIndex);
  82. (* Sets type of innermost visible entry. *)
  83. PROCEDURE SymKind (name: ARRAY OF CHAR): INTEGER;
  84. (* Kind of innermost visible entry, -1 if absent. *)
  85. PROCEDURE Equal (a, b: ARRAY OF CHAR): BOOLEAN;
  86. PROCEDURE PushScope;
  87. PROCEDURE PopScope;
  88. (* WITH statement support: PushRecord pushes a record's fields. *)
  89. PROCEDURE SymLev (name: ARRAY OF CHAR): INTEGER;
  90. (* Scope level at declaration (-1 if absent). *)
  91. (* ---------------- local modules (single-file, step 6) *)
  92. (* Local MODULEs live at program level (no nesting, no bodies).
  93. EXPORT names are resolved at END (before PopScope) into an export
  94. table keyed by (module, name); MGen stores module vars qualified
  95. ("M.x") so FindVar has no collisions. *)
  96. PROCEDURE EnterModule (name: ARRAY OF CHAR): BOOLEAN;
  97. (* Enters KindModule + pushes body scope + module context.
  98. FALSE on duplicate. *)
  99. PROCEDURE ModuleAddExp (name: ARRAY OF CHAR): BOOLEAN;
  100. (* Records an export name for the current module (checked for
  101. duplicates in the export list). FALSE if not in a module. *)
  102. PROCEDURE ExitModule(): BOOLEAN;
  103. (* Resolves exports against the body scope, pops scope + context.
  104. TRUE if every EXPORT name was declared (FALSE = ghost export). *)
  105. PROCEDURE InModule (): BOOLEAN;
  106. (* TRUE inside a local MODULE body (including its procedures). *)
  107. PROCEDURE CurModName (VAR m: Name);
  108. (* Top module name, empty if none. *)
  109. PROCEDURE ExpKind (mod, exp: ARRAY OF CHAR): INTEGER;
  110. (* Exported kind, -1 if absent. *)
  111. PROCEDURE ExpType (mod, exp: ARRAY OF CHAR): TypeIndex;
  112. (* Exported type (InvalidType if absent / not a type-ish export). *)
  113. PROCEDURE ExpProc (mod, exp: ARRAY OF CHAR): INTEGER;
  114. (* Exported proc number, -1 if absent / not a procedure. *)
  115. PROCEDURE ExpQual (mod, exp: ARRAY OF CHAR; VAR qual: Name);
  116. (* Qualified MGen name ("M.x"), empty if absent / not a variable
  117. or constant. *)
  118. PROCEDURE SelfKind (mod, exp: ARRAY OF CHAR): INTEGER;
  119. (* Kind of exp as M.exp from inside M itself (live body scope,
  120. since exports resolve only at END). -1 if not applicable. *)
  121. PROCEDURE SelfQual (exp: ARRAY OF CHAR; VAR qual: Name);
  122. (* CurMod.exp for a self reference (call only when SelfKind # -1). *)
  123. PROCEDURE PushRecord (t: TypeIndex): BOOLEAN;
  124. (* Pushes a scope containing t's fields (as KindField). FALSE if t
  125. is not a record type (or invalid). Caller must PopScope after. *)
  126. PROCEDURE PrintTable;
  127. (* ---------------- type descriptors ---------------- *)
  128. PROCEDURE NewAlias (): TypeIndex;
  129. PROCEDURE NewSub (base: TypeIndex): TypeIndex;
  130. PROCEDURE NewSubB (base: TypeIndex; lo, hi: INTEGER): TypeIndex;
  131. PROCEDURE NewEnum (): TypeIndex;
  132. PROCEDURE EnumAdd (t: TypeIndex);
  133. PROCEDURE NewArray (elem: TypeIndex): TypeIndex;
  134. PROCEDURE NewArrayB (elem: TypeIndex; lo, hi: INTEGER): TypeIndex;
  135. PROCEDURE NewOpen (elem: TypeIndex): TypeIndex;
  136. PROCEDURE IsOpen (t: TypeIndex): BOOLEAN;
  137. PROCEDURE NewRecord (): TypeIndex;
  138. PROCEDURE NewSet (base: TypeIndex): TypeIndex;
  139. PROCEDURE NewPtr (base: TypeIndex): TypeIndex;
  140. PROCEDURE NewStr (): TypeIndex;
  141. (* Fresh descriptors; base/elem may be InvalidType. InvalidType is
  142. returned when the table is full. *)
  143. PROCEDURE SetTarget (t, base: TypeIndex);
  144. (* Sets an alias target (TYPE declaration completion). *)
  145. PROCEDURE IntType (): TypeIndex;
  146. PROCEDURE RealType (): TypeIndex;
  147. PROCEDURE CharType (): TypeIndex;
  148. PROCEDURE BoolType (): TypeIndex;
  149. PROCEDURE ClassOf (t: TypeIndex): INTEGER;
  150. (* Resolves aliases; InvalidType maps to ClInvalid. *)
  151. PROCEDURE IsIntFamily (t: TypeIndex): BOOLEAN;
  152. (* INTEGER, CARDINAL or subrange thereof (Invalid suppresses). *)
  153. PROCEDURE SameType (a, b: TypeIndex): BOOLEAN;
  154. (* Same resolved descriptor (Invalid suppresses). *)
  155. PROCEDURE FieldExists (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  156. PROCEDURE FieldType (rec: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
  157. PROCEDURE FieldOffset (rec: TypeIndex; name: ARRAY OF CHAR): INTEGER;
  158. PROCEDURE ArrayElem (t: TypeIndex): TypeIndex;
  159. PROCEDURE ArrayLo (t: TypeIndex): INTEGER;
  160. PROCEDURE ArrayHi (t: TypeIndex): INTEGER;
  161. PROCEDURE ArrayLen (t: TypeIndex): CARDINAL;
  162. PROCEDURE TypeSlots (t: TypeIndex): CARDINAL;
  163. PROCEDURE TypeLo (t: TypeIndex): INTEGER;
  164. PROCEDURE TypeHi (t: TypeIndex): INTEGER;
  165. PROCEDURE TypeLen (t: TypeIndex): CARDINAL;
  166. PROCEDURE PtrBase (t: TypeIndex): TypeIndex;
  167. (* ---------------- predicates used by grammar checks ---------------- *)
  168. (* All return TRUE if either operand is InvalidType (no cascades). *)
  169. PROCEDURE Assignable (src, dst: TypeIndex): BOOLEAN;
  170. (* Assignment compatibility (210). *)
  171. PROCEDURE ArithCheck (l, r: TypeIndex; divmod: BOOLEAN;
  172. VAR res: TypeIndex): BOOLEAN;
  173. (* + - * / (divmod FALSE) or DIV MOD (TRUE); res is result type (211). *)
  174. PROCEDURE UnaryCheck (t: TypeIndex; VAR res: TypeIndex): BOOLEAN;
  175. (* Unary + - (part of 211). *)
  176. PROCEDURE BoolCheck (t: TypeIndex): BOOLEAN;
  177. (* BOOLEAN required: NOT/AND/OR operands (212), conditions (214). *)
  178. PROCEDURE RelCheck (l, r: TypeIndex; op: INTEGER): BOOLEAN;
  179. (* = # <> < <= > >= IN (213/222 chosen by caller via op). *)
  180. PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
  181. (* = # compatibility, also reused for CASE label matching. *)
  182. PROCEDURE InCheck (l, set: TypeIndex): BOOLEAN;
  183. PROCEDURE SetElemCheck (first, elem: TypeIndex): BOOLEAN;
  184. PROCEDURE SetFor (elem: TypeIndex): TypeIndex;
  185. (* Fresh SET OF elem descriptor for set literals. *)
  186. PROCEDURE StrLen (s: ARRAY OF CHAR): CARDINAL;
  187. (* ---------------- procedures ---------------- *)
  188. (* Step 3: nested procedures with value and VAR parameters, forward
  189. declarations, static scoping. Proc numbers start at 1 (0 is the
  190. module body); at most MaxProcs user procedures. *)
  191. PROCEDURE EnterProc (name: ARRAY OF CHAR): BOOLEAN;
  192. (* Enters a procedure name (KindProc, InvalidType) and assigns the
  193. next proc number. FALSE on duplicate or table full. Sets the
  194. current-proc context for following EnterParam/FwdParam calls. *)
  195. PROCEDURE AllocInitNum (): INTEGER;
  196. (* Reserves the next proc number for a module BEGIN init body
  197. (step 10). Init bodies share the procedure number pool so an
  198. init emitted before a later procedure's body can never steal
  199. that procedure's number. The slot has no symbol entry and no
  200. signature; -1 when the pool is full. *)
  201. PROCEDURE IsForward (name: ARRAY OF CHAR): BOOLEAN;
  202. (* TRUE if the visible entry is a forward-declared procedure
  203. whose body is still pending. *)
  204. PROCEDURE ReuseProc (name: ARRAY OF CHAR);
  205. (* Starts the full definition of a forward-declared procedure:
  206. keeps its number, switches signature recording to define mode. *)
  207. PROCEDURE OpenProcScope;
  208. (* Pushes a scope for a procedure body, enters proc depth + 1,
  209. resets slot counters, pushes return-type context. *)
  210. PROCEDURE CloseProc;
  211. (* Pops a procedure body scope, restores the enclosing context. *)
  212. PROCEDURE EnterParam (name: ARRAY OF CHAR; isVar: BOOLEAN;
  213. t: TypeIndex): BOOLEAN;
  214. (* Enters a value (KindParam) or VAR (KindVarPar) parameter in the
  215. current procedure scope with its frame slot, appends it to the
  216. define signature. FALSE on duplicate. *)
  217. PROCEDURE SetProcRet (t: TypeIndex): BOOLEAN;
  218. (* Sets the return type (InvalidType = proper procedure). TRUE
  219. unless it mismatches a forward heading (error 231). *)
  220. PROCEDURE VerifyProc (): BOOLEAN;
  221. (* TRUE unless the define signature mismatches the forward
  222. heading (error 231). *)
  223. PROCEDURE SetForward;
  224. (* Marks the current procedure forward-declared (body pending). *)
  225. PROCEDURE AnyForward (): BOOLEAN;
  226. (* TRUE if some procedure body is still missing (error 231). *)
  227. PROCEDURE ProcNum (name: ARRAY OF CHAR): INTEGER;
  228. (* Proc number, or -1 if absent / not a procedure. *)
  229. PROCEDURE ProcRet (name: ARRAY OF CHAR): TypeIndex;
  230. (* Return type (InvalidType = proper procedure or unknown). *)
  231. PROCEDURE ProcNPar (name: ARRAY OF CHAR): CARDINAL;
  232. (* Arity from the define signature, else the forward one. *)
  233. PROCEDURE ParamType (name: ARRAY OF CHAR; i: CARDINAL): TypeIndex;
  234. PROCEDURE ParamIsVar (name: ARRAY OF CHAR; i: CARDINAL): BOOLEAN;
  235. (* i-th formal parameter (0-based), InvalidType/FALSE if absent. *)
  236. PROCEDURE ProcValid (num: INTEGER): BOOLEAN;
  237. (* TRUE if num is a declared procedure number (survives scope pops,
  238. so module procs stay callable after ExitModule). *)
  239. PROCEDURE ProcNParByNum (num: INTEGER): CARDINAL;
  240. PROCEDURE ParamTypeByNum (num: INTEGER; i: CARDINAL): TypeIndex;
  241. PROCEDURE ParamIsVarByNum (num: INTEGER; i: CARDINAL): BOOLEAN;
  242. PROCEDURE ProcRetByNum (num: INTEGER): TypeIndex;
  243. (* Same signature queries as above, keyed by procedure number. *)
  244. PROCEDURE SymSlot (name: ARRAY OF CHAR): INTEGER;
  245. (* Frame slot (params >= 3, locals negative). Only meaningful
  246. for variables at proc depth > 0. *)
  247. PROCEDURE SymDepth (name: ARRAY OF CHAR): INTEGER;
  248. (* Proc depth at declaration (0 = module level). *)
  249. PROCEDURE CurDepth (): INTEGER;
  250. (* Current proc depth (0 = module body). *)
  251. PROCEDURE CurProc (): INTEGER;
  252. (* Current proc number (0 = module body). *)
  253. PROCEDURE CurNPar (): CARDINAL;
  254. (* Arity of the current procedure (0 outside). *)
  255. PROCEDURE CurRet (): TypeIndex;
  256. (* Current return type (InvalidType = proper or outside). *)
  257. PROCEDURE InProc (): BOOLEAN;
  258. (* TRUE inside a procedure body. *)
  259. PROCEDURE InFunction (): BOOLEAN;
  260. (* TRUE inside a function (non-InvalidType return) body. *)
  261. PROCEDURE ProcNLocals (): CARDINAL;
  262. (* Local slot count of the current procedure (0 outside). *)
  263. END SymTab.