SymTab.def 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. DEFINITION MODULE SymTab;
  2. (* Symbol table with static type checking for SimpleMod2
  3. (simplified Modula-2 without procedures).
  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. InvalidType = -1;
  18. (* symbol kinds *)
  19. KindConst = 0;
  20. KindType = 1;
  21. KindVar = 2;
  22. KindImport = 3;
  23. KindModule = 4;
  24. KindPredef = 5;
  25. KindField = 6;
  26. KindProc = 7;
  27. KindParam = 8;
  28. (* type classes returned by ClassOf *)
  29. ClInvalid = 0;
  30. ClInt = 1;
  31. ClReal = 2;
  32. ClChar = 3;
  33. ClBool = 4;
  34. ClEnum = 5;
  35. ClArray = 6;
  36. ClRecord = 7;
  37. ClSet = 8;
  38. ClPtr = 9;
  39. ClStr = 10;
  40. ClClass = 11;
  41. ClNil = 12;
  42. ClLong = 13;
  43. (* operator codes for RelCheck *)
  44. OpEq = 0; OpNeq1 = 1; OpNeq2 = 2;
  45. OpLt = 3; OpLe = 4; OpGt = 5; OpGe = 6;
  46. OpIn = 7;
  47. (* operator codes for AddOp / MulOp *)
  48. OpAdd = 0; OpSub = 1; OpOr = 2;
  49. OpTimes = 0; OpSlash = 1; OpDiv = 2; OpMod = 3; OpAnd = 4;
  50. TYPE
  51. Name = ARRAY [0 .. 63] OF CHAR;
  52. TypeIndex = INTEGER;
  53. BoundsArr = ARRAY [0 .. 7] OF INTEGER;
  54. (* Per-dimension bounds for array index lists (grammar locals). *)
  55. (* ---------------- symbols and scopes ---------------- *)
  56. PROCEDURE Init;
  57. (* Clears the table and enters predefined identifiers
  58. (INTEGER, CARDINAL, SHORTINT, LONGINT, SHORTCARD, REAL, LONGREAL,
  59. CHAR, BOOLEAN, TRUE, FALSE, NIL). *)
  60. PROCEDURE Enter (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  61. (* Enters name at the current scope level (type InvalidType).
  62. Returns FALSE on duplicate within the same level. *)
  63. PROCEDURE EnterPending (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  64. (* Like Enter, but remembers the entry for a later FixPending call
  65. (used for VAR identifier lists whose type is parsed afterwards).
  66. Returns FALSE on duplicate (entry not recorded). *)
  67. PROCEDURE FixPending (t: TypeIndex);
  68. (* Assigns type t to all pending entries, clears the buffer. *)
  69. PROCEDURE PendCount (): CARDINAL;
  70. (* Number of entries currently waiting for FixPending. *)
  71. PROCEDURE PendName (i: CARDINAL; VAR n: Name);
  72. (* Name of the i-th pending entry (empty string if out of range).
  73. Used by the QBE backend to emit storage for VAR lists whose
  74. type is parsed after the identifiers. *)
  75. PROCEDURE FieldPending (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  76. (* Records a field name for record descriptor rec (type fixed later
  77. with FixPendingF). Returns FALSE on duplicate field. *)
  78. PROCEDURE FixPendingF (rec: TypeIndex; t: TypeIndex);
  79. (* Assigns type t to pending fields owned by rec. *)
  80. PROCEDURE Lookup (name: ARRAY OF CHAR): BOOLEAN;
  81. (* TRUE if name is visible (innermost scope wins). *)
  82. PROCEDURE SymType (name: ARRAY OF CHAR): TypeIndex;
  83. (* Type of innermost visible entry, InvalidType if absent. *)
  84. PROCEDURE SetSymType (name: ARRAY OF CHAR; t: TypeIndex);
  85. (* Sets type of innermost visible entry. *)
  86. PROCEDURE SymKind (name: ARRAY OF CHAR): INTEGER;
  87. (* Kind of innermost visible entry, -1 if absent. *)
  88. PROCEDURE Equal (a, b: ARRAY OF CHAR): BOOLEAN;
  89. PROCEDURE PushScope;
  90. PROCEDURE PopScope;
  91. (* WITH statement support: PushRecord pushes a record's fields. *)
  92. PROCEDURE PushRecord (t: TypeIndex): BOOLEAN;
  93. (* Pushes a scope containing t's fields (as KindField). FALSE if t
  94. is not a record type (or invalid). Caller must PopScope after. *)
  95. PROCEDURE PrintTable;
  96. (* ---------------- procedures (headings now, bodies step 4) ---------------- *)
  97. PROCEDURE EnterProc (name: ARRAY OF CHAR): BOOLEAN;
  98. (* Enters a KindProc heading and pushes its parameter scope.
  99. FALSE on duplicate (no scope pushed). Resets result to
  100. InvalidType (proper procedure), clears fwd, empties param chain. *)
  101. PROCEDURE ResumeProc (name: ARRAY OF CHAR): BOOLEAN;
  102. (* Resumes a DEFINITION's procedure heading for its
  103. IMPLEMENTATION body: pushes a fresh body scope, clears the
  104. formal chain (the implementation re-enters its own). Only valid
  105. while an IMPLEMENTATION unit is open. *)
  106. PROCEDURE ReenterProc (name: ARRAY OF CHAR): BOOLEAN;
  107. (* Resumes a FORWARD-marked procedure of this scope for its body
  108. heading: clears fwd, pushes a fresh parameter scope. FALSE
  109. when no such forward heading exists (then 200 applies). *)
  110. PROCEDURE EnterParam (name: ARRAY OF CHAR; isVar: BOOLEAN): BOOLEAN;
  111. (* Enters a KindParam in the heading scope and chains it into the
  112. current procedure's positional param list. FALSE on duplicate. *)
  113. PROCEDURE SetProcRes (t: TypeIndex);
  114. (* Sets the current procedure's result type (InvalidType = none). *)
  115. PROCEDURE ProcRes (name: ARRAY OF CHAR): TypeIndex;
  116. (* Result type of the named procedure, InvalidType if absent/none. *)
  117. PROCEDURE MarkFwd;
  118. (* Marks the current procedure FORWARD (body must follow). *)
  119. PROCEDURE MarkVirtual;
  120. (* Marks the current procedure VIRTUAL (dynamically dispatched;
  121. dispatch tables arrive with class lowering). *)
  122. PROCEDURE MarkExternal (link: ARRAY OF CHAR);
  123. (* Marks the current procedure EXTERNAL (no body emitted; calls bind
  124. to the C symbol `link`, or to the procedure's own name if ''). *)
  125. PROCEDURE IsExternal (name: ARRAY OF CHAR): BOOLEAN;
  126. PROCEDURE ProcLink (name: ARRAY OF CHAR; VAR link: Name): BOOLEAN;
  127. (* External-procedure query/link lookup (link name of the named
  128. visible procedure). *)
  129. PROCEDURE CloseProc;
  130. (* Pops the current procedure's scope and its proc-stack entry.
  131. Replaces bare PopScope at the end of headings (DefUnit),
  132. FORWARD clauses and bodies. *)
  133. PROCEDURE InProc (): BOOLEAN;
  134. (* TRUE inside a procedure heading/body (RETURN legal). *)
  135. PROCEDURE CurRes (): TypeIndex;
  136. (* Result type of the innermost open procedure,
  137. InvalidType outside procedures or for proper procedures. *)
  138. PROCEDURE ProcDepth (): CARDINAL;
  139. (* Number of open procedure headings/bodies (nesting depth). *)
  140. PROCEDURE ProcDepthOf (name: ARRAY OF CHAR): CARDINAL;
  141. (* Lexical function-nesting depth of the named procedure
  142. (enclosing procedures; 0 = module level). Drives the static-
  143. link walk count at call sites. *)
  144. PROCEDURE ProcUid (name: ARRAY OF CHAR): CARDINAL;
  145. (* Unique id of the named procedure (0 if absent); drives QBE
  146. name mangling so same-named methods never collide. *)
  147. PROCEDURE ProcNPar (name: ARRAY OF CHAR): CARDINAL;
  148. PROCEDURE ParamType (name: ARRAY OF CHAR; i: CARDINAL): TypeIndex;
  149. PROCEDURE ParamIsVar (name: ARRAY OF CHAR; i: CARDINAL): BOOLEAN;
  150. (* Positional formal access for call checking (233 on mismatch). *)
  151. PROCEDURE VarParamOk (actual, formal: TypeIndex): BOOLEAN;
  152. (* VAR-formal compatibility: same type, fixed array into open
  153. array with same element, or string literal into open CHAR. *)
  154. (* ---------------- modules / separate compilation (step 4.3) ---------------- *)
  155. (* One compiler session compiles several units into one image:
  156. DEFINITION, its IMPLEMENTATION, and one program (last). Each
  157. unit gets its own scope; imports materialize names. *)
  158. CONST
  159. UnitProg = 0; UnitDef = 1; UnitImpl = 2;
  160. PROCEDURE BeginDef (name: ARRAY OF CHAR): BOOLEAN;
  161. (* Opens a DEFINITION module scope. FALSE on duplicate module. *)
  162. PROCEDURE BeginImpl (name: ARRAY OF CHAR): BOOLEAN;
  163. (* Resumes a DEFINITION's scope for its IMPLEMENTATION.
  164. FALSE when the module is undefined or already implemented. *)
  165. PROCEDURE BeginProg (name: ARRAY OF CHAR): BOOLEAN;
  166. (* Opens the program module's scope. *)
  167. PROCEDURE EndUnit;
  168. (* Returns to the global scope. *)
  169. PROCEDURE CurUnit (): INTEGER;
  170. (* Unit kind currently open (UnitProg/Def/Impl); -1 between units. *)
  171. PROCEDURE CurModule (VAR name: Name);
  172. (* Name of the module currently open ('' between units). *)
  173. PROCEDURE HaveProgram (): BOOLEAN;
  174. (* TRUE once a program module has been opened (a session without
  175. one is an error: nothing to link). *)
  176. PROCEDURE ModKnown (name: ARRAY OF CHAR): BOOLEAN;
  177. PROCEDURE ModDefined (name: ARRAY OF CHAR): BOOLEAN;
  178. PROCEDURE ModImplemented (name: ARRAY OF CHAR): BOOLEAN;
  179. PROCEDURE ImportFrom (mod, name: ARRAY OF CHAR): BOOLEAN;
  180. (* Materializes an exported name from mod into the current scope
  181. (FROM mod IMPORT name). FALSE when mod/name is unknown. *)
  182. PROCEDURE OpaqueBase (name: ARRAY OF CHAR): TypeIndex;
  183. (* If name is an opaque alias (its target still InvalidType),
  184. returns that alias descriptor so the implementation can complete
  185. it via SetTarget; InvalidType otherwise. *)
  186. PROCEDURE QualFind (mod, name: ARRAY OF CHAR): BOOLEAN;
  187. (* TRUE when mod exports name. *)
  188. PROCEDURE QualKind (mod, name: ARRAY OF CHAR): INTEGER;
  189. PROCEDURE QualType (mod, name: ARRAY OF CHAR): TypeIndex;
  190. PROCEDURE QualProcUid (mod, name: ARRAY OF CHAR): CARDINAL;
  191. PROCEDURE QualProcNPar (mod, name: ARRAY OF CHAR): CARDINAL;
  192. PROCEDURE QualParamType (mod, name: ARRAY OF CHAR; i: CARDINAL): TypeIndex;
  193. PROCEDURE QualParamIsVar (mod, name: ARRAY OF CHAR; i: CARDINAL): BOOLEAN;
  194. PROCEDURE QualProcRes (mod, name: ARRAY OF CHAR): TypeIndex;
  195. PROCEDURE Materialize (mod, name: ARRAY OF CHAR): BOOLEAN;
  196. (* FROM-import: clones mod's export into the current scope under
  197. its plain name. FALSE when mod/name is unknown. *)
  198. PROCEDURE MaterializeAlias (mod, name: ARRAY OF CHAR;
  199. VAR alias: Name): BOOLEAN;
  200. (* Qualified access: clones mod's export under a per-module alias
  201. key, so same-named exports of different modules never collide.
  202. The alias key is used for all subsequent lookups (types, uids,
  203. params); the node remembers its base name and module for QBE
  204. symbol emission. *)
  205. PROCEDURE SymBase (name: ARRAY OF CHAR; VAR base: Name): BOOLEAN;
  206. (* Base symbol name of the visible entry (drops any alias prefix). *)
  207. PROCEDURE GlobalRef (name: ARRAY OF CHAR; VAR g: Name): BOOLEAN;
  208. (* "<mod>_<sym>" QBE global-symbol name for a module-level entry;
  209. FALSE when name is not a module-level symbol. *)
  210. (* ---------------- classes (Clarion form, lowering deferred) ---------------- *)
  211. PROCEDURE SetParent (t, p: TypeIndex);
  212. (* Records p as the (single) parent class of t. Multiple parents
  213. are rejected in the grammar with 230. *)
  214. PROCEDURE PushClassScope (t: TypeIndex);
  215. (* Pushes the body scope of class t and records it on t. *)
  216. PROCEDURE MethodExists (t: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  217. (* TRUE if the class scope of t declares name as a procedure. *)
  218. PROCEDURE PushClassMembers (t: TypeIndex): BOOLEAN;
  219. (* Pushes a scope with t's fields (KindField) for method bodies in
  220. CLASS IMPLEMENTATION. FALSE if t is not a class. Method names
  221. are re-entered fresh by each body (copying them would collide);
  222. sibling-method references report 201 until step 4 calls. *)
  223. (* ---------------- type descriptors ---------------- *)
  224. PROCEDURE NewAlias (): TypeIndex;
  225. PROCEDURE NewSub (base: TypeIndex): TypeIndex;
  226. PROCEDURE NewSubR (lo, hi: INTEGER): TypeIndex;
  227. (* Integer subrange [lo..hi] (no base descriptor needed). Bounds
  228. accessors arrive with step 3; the backend cannot lower them yet. *)
  229. PROCEDURE NewEnum (): TypeIndex;
  230. PROCEDURE NewArrayB (elem: TypeIndex; lo, hi: INTEGER): TypeIndex;
  231. (* Bounded array (one dimension; nest for multi-dim). InvalidType
  232. when the table is full. *)
  233. PROCEDURE NewOpenArray (elem: TypeIndex): TypeIndex;
  234. (* Open ARRAY OF formal: 0-based, runtime count in the header.
  235. Only legal for formal parameters (grammar enforces). *)
  236. PROCEDURE BoundBegin;
  237. PROCEDURE BoundAdd (lo, hi: INTEGER): BOOLEAN;
  238. (* Accumulates one index bound pair for the enclosing ArrayType
  239. (max 8 dimensions, FALSE past that). *)
  240. PROCEDURE NestArray (elem: TypeIndex): TypeIndex;
  241. (* Nests the accumulated bounds inside-out around elem. *)
  242. PROCEDURE NewRecord (): TypeIndex;
  243. PROCEDURE NewSet (base: TypeIndex): TypeIndex;
  244. PROCEDURE NewPtr (base: TypeIndex): TypeIndex;
  245. PROCEDURE NewStr (): TypeIndex;
  246. PROCEDURE NewClass (): TypeIndex;
  247. (* Fresh class descriptor (holds fields like a record; methods live
  248. in the class scope). Parent and scope via SetParent/PushClassScope. *)
  249. (* Fresh descriptors; base/elem may be InvalidType. InvalidType is
  250. returned when the table is full. *)
  251. PROCEDURE SetTarget (t, base: TypeIndex);
  252. (* Sets an alias target (TYPE declaration completion). *)
  253. PROCEDURE IntType (): TypeIndex;
  254. PROCEDURE RealType (): TypeIndex;
  255. PROCEDURE CharType (): TypeIndex;
  256. PROCEDURE BoolType (): TypeIndex;
  257. PROCEDURE LongType (): TypeIndex;
  258. (* LONGINT/LONGCARD: 64-bit integer (QBE l). *)
  259. PROCEDURE AddrType (): TypeIndex;
  260. (* ADDRESS: the pointer-sized opaque type (interchangeable with any
  261. pointer for assignment and VAR parameters). *)
  262. PROCEDURE ObjectSize (t: TypeIndex): CARDINAL;
  263. (* Full allocation footprint (arrays 8 + count*element); drives
  264. SYSTEM.SIZE/TSIZE. *)
  265. PROCEDURE ClassOf (t: TypeIndex): INTEGER;
  266. (* Resolves aliases; InvalidType maps to ClInvalid. *)
  267. PROCEDURE IsIntFamily (t: TypeIndex): BOOLEAN;
  268. (* INTEGER, CARDINAL or subrange thereof (Invalid suppresses). *)
  269. PROCEDURE IsLongFamily (t: TypeIndex): BOOLEAN;
  270. (* LONGINT/LONGCARD (QBE l). *)
  271. PROCEDURE SameType (a, b: TypeIndex): BOOLEAN;
  272. (* Same resolved descriptor (Invalid suppresses). *)
  273. PROCEDURE FieldExists (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  274. PROCEDURE FieldType (rec: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
  275. PROCEDURE ArrayElem (t: TypeIndex): TypeIndex;
  276. PROCEDURE IsOpenArray (t: TypeIndex): BOOLEAN;
  277. PROCEDURE ArrayLo (t: TypeIndex): INTEGER;
  278. PROCEDURE ArrayHi (t: TypeIndex): INTEGER;
  279. (* Static bounds (open arrays: lo 0, hi undefined — backend reads
  280. the header instead). InvalidType maps to 0. *)
  281. PROCEDURE ArrayLen (t: TypeIndex): CARDINAL;
  282. (* Static element count, 0 for open/invalid. *)
  283. PROCEDURE ArrayDepth (t: TypeIndex): CARDINAL;
  284. (* Nesting depth (open/fixed levels); 0 for non-arrays. *)
  285. PROCEDURE TypeSize (t: TypeIndex): CARDINAL;
  286. (* Inline footprint in bytes: scalars 4/8, sets words*4, pointers,
  287. open and fixed arrays 8 (descriptor address), records sum of
  288. members. *)
  289. PROCEDURE FieldOffset (rec: TypeIndex; name: ARRAY OF CHAR): INTEGER;
  290. (* Declaration-order byte offset (-1 if absent). Computed lazily. *)
  291. PROCEDURE FieldOwner (name: ARRAY OF CHAR): TypeIndex;
  292. (* Owning record/class of the visible field (InvalidType if none). *)
  293. PROCEDURE FieldCount (rec: TypeIndex): CARDINAL;
  294. PROCEDURE FieldName (rec: TypeIndex; i: CARDINAL; VAR name: Name);
  295. (* Field enumeration for whole-record lowering (order irrelevant). *)
  296. PROCEDURE SubBounds (t: TypeIndex; VAR lo, hi: INTEGER): BOOLEAN;
  297. (* TRUE with the bounds when t resolves to a subrange. *)
  298. PROCEDURE SetBase (t: TypeIndex): TypeIndex;
  299. (* Base type of a set descriptor (InvalidType if none). *)
  300. PROCEDURE SetWords (t: TypeIndex): CARDINAL;
  301. (* Mask words for a set type from its base span (bool 1, char 8,
  302. subrange by bounds); 0 when the base is unsuitable. *)
  303. PROCEDURE SetBaseLo (t: TypeIndex): INTEGER;
  304. (* Base minimum (bool/char 0, subrange lo); 0 when unsuitable. *)
  305. PROCEDURE SetCount (t: TypeIndex): CARDINAL;
  306. (* Base span in values (0 when unsuitable). *)
  307. PROCEDURE PtrBase (t: TypeIndex): TypeIndex;
  308. (* ---------------- predicates used by grammar checks ---------------- *)
  309. (* All return TRUE if either operand is InvalidType (no cascades). *)
  310. PROCEDURE Assignable (src, dst: TypeIndex): BOOLEAN;
  311. (* Assignment compatibility (210). *)
  312. PROCEDURE ArithCheck (l, r: TypeIndex; divmod: BOOLEAN;
  313. VAR res: TypeIndex): BOOLEAN;
  314. (* + - * / (divmod FALSE) or DIV MOD (TRUE); res is result type (211). *)
  315. PROCEDURE UnaryCheck (t: TypeIndex; VAR res: TypeIndex): BOOLEAN;
  316. (* Unary + - (part of 211). *)
  317. PROCEDURE BoolCheck (t: TypeIndex): BOOLEAN;
  318. (* BOOLEAN required: NOT/AND/OR operands (212), conditions (214). *)
  319. PROCEDURE RelCheck (l, r: TypeIndex; op: INTEGER): BOOLEAN;
  320. (* = # <> < <= > >= IN (213/222 chosen by caller via op). *)
  321. PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
  322. (* = # compatibility, also reused for CASE label matching. *)
  323. PROCEDURE InCheck (l, set: TypeIndex): BOOLEAN;
  324. PROCEDURE SetElemCheck (first, elem: TypeIndex): BOOLEAN;
  325. PROCEDURE SetFor (elem: TypeIndex): TypeIndex;
  326. (* Fresh SET OF elem descriptor for set literals. *)
  327. PROCEDURE StrLen (s: ARRAY OF CHAR): CARDINAL;
  328. PROCEDURE ConstInt (q: ARRAY OF CHAR; VAR v: INTEGER): BOOLEAN;
  329. (* Parses a folded integer immediate ("42", "-5", "16") as produced
  330. by NormInt/NegFold. FALSE for temporaries and non-numerics. *)
  331. END SymTab.