SymTab.def 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  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. ClProc = 14;
  44. ClUChar = 15;
  45. ClUStr = 16;
  46. (* operator codes for RelCheck *)
  47. OpEq = 0; OpNeq1 = 1; OpNeq2 = 2;
  48. OpLt = 3; OpLe = 4; OpGt = 5; OpGe = 6;
  49. OpIn = 7;
  50. (* operator codes for AddOp / MulOp *)
  51. OpAdd = 0; OpSub = 1; OpOr = 2;
  52. OpTimes = 0; OpSlash = 1; OpDiv = 2; OpMod = 3; OpAnd = 4;
  53. TYPE
  54. Name = ARRAY [0 .. 63] OF CHAR;
  55. TypeIndex = INTEGER;
  56. BoundsArr = ARRAY [0 .. 7] OF INTEGER;
  57. (* Per-dimension bounds for array index lists (grammar locals). *)
  58. (* ---------------- symbols and scopes ---------------- *)
  59. PROCEDURE Init;
  60. (* Clears the table and enters predefined identifiers
  61. (INTEGER, CARDINAL, SHORTINT, LONGINT, SHORTCARD, REAL, LONGREAL,
  62. CHAR, BOOLEAN, TRUE, FALSE, NIL). *)
  63. PROCEDURE Enter (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  64. (* Enters name at the current scope level (type InvalidType).
  65. Returns FALSE on duplicate within the same level. *)
  66. PROCEDURE EnterPending (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  67. (* Like Enter, but remembers the entry for a later FixPending call
  68. (used for VAR identifier lists whose type is parsed afterwards).
  69. Returns FALSE on duplicate (entry not recorded). *)
  70. PROCEDURE FixPending (t: TypeIndex) : BOOLEAN;
  71. (* Assigns type t to all pending entries, clears the buffer, and
  72. returns TRUE. When the current heading resumed a DEFINITION, the
  73. just-typed formals are compared against the snapshot (strict 231):
  74. FALSE = mismatch. *)
  75. PROCEDURE PendCount (): CARDINAL;
  76. (* Number of entries currently waiting for FixPending. *)
  77. PROCEDURE PendName (i: CARDINAL; VAR n: Name);
  78. (* Name of the i-th pending entry (empty string if out of range).
  79. Used by the QBE backend to emit storage for VAR lists whose
  80. type is parsed after the identifiers. *)
  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 SetSymVal (name: ARRAY OF CHAR; v: ARRAY OF CHAR);
  95. (* Stores the literal value text of a CONST for constant folding. *)
  96. PROCEDURE GetSymVal (name: ARRAY OF CHAR; VAR v: ARRAY OF CHAR): BOOLEAN;
  97. (* v := stored literal value text of CONST name; FALSE if none. *)
  98. PROCEDURE Equal (a, b: ARRAY OF CHAR): BOOLEAN;
  99. PROCEDURE PushScope;
  100. PROCEDURE PopScope;
  101. (* WITH statement support: PushRecord pushes a record's fields. *)
  102. PROCEDURE PushRecord (t: TypeIndex): BOOLEAN;
  103. (* Pushes a scope containing t's fields (as KindField). FALSE if t
  104. is not a record type (or invalid). Caller must PopScope after. *)
  105. PROCEDURE PrintTable;
  106. (* ---------------- procedures (headings now, bodies step 4) ---------------- *)
  107. PROCEDURE EnterProc (name: ARRAY OF CHAR): BOOLEAN;
  108. (* Enters a KindProc heading and pushes its parameter scope.
  109. FALSE on duplicate (no scope pushed). Resets result to
  110. InvalidType (proper procedure), clears fwd, empties param chain. *)
  111. PROCEDURE ResumeProc (name: ARRAY OF CHAR): BOOLEAN;
  112. (* Resumes a DEFINITION's procedure heading for its
  113. IMPLEMENTATION body: pushes a fresh body scope, clears the
  114. formal chain (the implementation re-enters its own). Only valid
  115. while an IMPLEMENTATION unit is open. *)
  116. PROCEDURE ReenterProc (name: ARRAY OF CHAR): BOOLEAN;
  117. (* Resumes a FORWARD-marked procedure of this scope for its body
  118. heading: clears fwd, pushes a fresh parameter scope. FALSE
  119. when no such forward heading exists (then 200 applies). *)
  120. PROCEDURE EnterParam (name: ARRAY OF CHAR; isVar: BOOLEAN): BOOLEAN;
  121. (* Enters a KindParam in the heading scope and chains it into the
  122. current procedure's positional param list. FALSE on duplicate. *)
  123. PROCEDURE SetProcRes (t: TypeIndex) : BOOLEAN;
  124. (* Sets the current procedure's result type (InvalidType = none) and
  125. returns TRUE. When the heading resumed a DEFINITION
  126. (ResumeProc), it also performs the strict-231 signature check
  127. (result, formal count, formal types, VAR-ness) and returns the
  128. outcome; FALSE means the implementation does not match. *)
  129. PROCEDURE ProcRes (name: ARRAY OF CHAR): TypeIndex;
  130. (* Result type of the named procedure, InvalidType if absent/none. *)
  131. PROCEDURE MarkFwd;
  132. (* Marks the current procedure FORWARD (body must follow). *)
  133. PROCEDURE MarkVirtual;
  134. (* Marks the current procedure VIRTUAL (dynamically dispatched;
  135. dispatch tables arrive with class lowering). *)
  136. PROCEDURE MarkExternal (link: ARRAY OF CHAR);
  137. (* Marks the current procedure EXTERNAL (no body emitted; calls bind
  138. to the C symbol `link`, or to the procedure's own name if ''). *)
  139. PROCEDURE IsExternal (name: ARRAY OF CHAR): BOOLEAN;
  140. (* TRUE for an EXTERNAL procedure. *)
  141. PROCEDURE DeclareCProc (name: ARRAY OF CHAR): BOOLEAN;
  142. (* Enter name as an intrinsic external C procedure (varargs, no
  143. result): FROM libc IMPORT. *)
  144. PROCEDURE Varargs (name: ARRAY OF CHAR): BOOLEAN;
  145. (* TRUE when the named procedure is a C-varargs intrinsic. *)
  146. PROCEDURE ProcLink (name: ARRAY OF CHAR; VAR link: Name): BOOLEAN;
  147. (* External-procedure query/link lookup (link name of the named
  148. visible procedure). *)
  149. PROCEDURE CloseProc;
  150. (* Pops the current procedure's scope and its proc-stack entry.
  151. Replaces bare PopScope at the end of headings (DefUnit),
  152. FORWARD clauses and bodies. *)
  153. PROCEDURE InProc (): BOOLEAN;
  154. (* TRUE inside a procedure heading/body (RETURN legal). *)
  155. PROCEDURE CurRes (): TypeIndex;
  156. (* Result type of the innermost open procedure,
  157. InvalidType outside procedures or for proper procedures. *)
  158. PROCEDURE ProcDepth (): CARDINAL;
  159. (* Number of open procedure headings/bodies (nesting depth). *)
  160. PROCEDURE ProcDepthOf (name: ARRAY OF CHAR): CARDINAL;
  161. (* Lexical function-nesting depth of the named procedure
  162. (enclosing procedures; 0 = module level). Drives the static-
  163. link walk count at call sites. *)
  164. PROCEDURE ProcUid (name: ARRAY OF CHAR): CARDINAL;
  165. (* Unique id of the named procedure (0 if absent); drives QBE
  166. name mangling so same-named methods never collide. *)
  167. PROCEDURE ProcNPar (name: ARRAY OF CHAR): CARDINAL;
  168. PROCEDURE ParamType (name: ARRAY OF CHAR; i: CARDINAL): TypeIndex;
  169. PROCEDURE ParamIsVar (name: ARRAY OF CHAR; i: CARDINAL): BOOLEAN;
  170. (* Positional formal access for call checking (233 on mismatch). *)
  171. PROCEDURE VarParamOk (actual, formal: TypeIndex): BOOLEAN;
  172. (* VAR-formal compatibility: same type, fixed array into open
  173. array with same element, or string literal into open CHAR. *)
  174. (* ---------------- modules / separate compilation (step 4.3) ---------------- *)
  175. (* One compiler session compiles several units into one image:
  176. DEFINITION, its IMPLEMENTATION, and one program (last). Each
  177. unit gets its own scope; imports materialize names. *)
  178. CONST
  179. UnitProg = 0; UnitDef = 1; UnitImpl = 2;
  180. PROCEDURE BeginDef (name: ARRAY OF CHAR): BOOLEAN;
  181. (* Opens a DEFINITION module scope. FALSE on duplicate module. *)
  182. PROCEDURE BeginImpl (name: ARRAY OF CHAR): BOOLEAN;
  183. (* Resumes a DEFINITION's scope for its IMPLEMENTATION.
  184. FALSE when the module is undefined or already implemented. *)
  185. PROCEDURE BeginProg (name: ARRAY OF CHAR): BOOLEAN;
  186. (* Opens the program module's scope. *)
  187. PROCEDURE EndUnit;
  188. (* Returns to the global scope. *)
  189. PROCEDURE CurUnit (): INTEGER;
  190. (* Unit kind currently open (UnitProg/Def/Impl); -1 between units. *)
  191. PROCEDURE CurModule (VAR name: Name);
  192. (* Name of the module currently open ('' between units). *)
  193. PROCEDURE HaveProgram (): BOOLEAN;
  194. (* TRUE once a program module has been opened (a session without
  195. one is an error: nothing to link). *)
  196. PROCEDURE ModKnown (name: ARRAY OF CHAR): BOOLEAN;
  197. PROCEDURE ModDefined (name: ARRAY OF CHAR): BOOLEAN;
  198. PROCEDURE ModImplemented (name: ARRAY OF CHAR): BOOLEAN;
  199. PROCEDURE ImportFrom (mod, name: ARRAY OF CHAR): BOOLEAN;
  200. (* Materializes an exported name from mod into the current scope
  201. (FROM mod IMPORT name). FALSE when mod/name is unknown. *)
  202. PROCEDURE OpaqueBase (name: ARRAY OF CHAR): TypeIndex;
  203. (* If name is an opaque alias (its target still InvalidType),
  204. returns that alias descriptor so the implementation can complete
  205. it via SetTarget; InvalidType otherwise. *)
  206. PROCEDURE QualFind (mod, name: ARRAY OF CHAR): BOOLEAN;
  207. (* TRUE when mod exports name. *)
  208. PROCEDURE QualKind (mod, name: ARRAY OF CHAR): INTEGER;
  209. PROCEDURE QualType (mod, name: ARRAY OF CHAR): TypeIndex;
  210. PROCEDURE QualProcUid (mod, name: ARRAY OF CHAR): CARDINAL;
  211. PROCEDURE QualProcNPar (mod, name: ARRAY OF CHAR): CARDINAL;
  212. PROCEDURE QualParamType (mod, name: ARRAY OF CHAR; i: CARDINAL): TypeIndex;
  213. PROCEDURE QualParamIsVar (mod, name: ARRAY OF CHAR; i: CARDINAL): BOOLEAN;
  214. PROCEDURE QualProcRes (mod, name: ARRAY OF CHAR): TypeIndex;
  215. PROCEDURE ExportUp (name: ARRAY OF CHAR);
  216. (* Nested-module END: clones the entry `name` from the just-finished
  217. nested scope into the enclosing scope, so a local module's EXPORT
  218. list becomes visible outside it. Must be called before PopScope. *)
  219. PROCEDURE Materialize (mod, name: ARRAY OF CHAR): BOOLEAN;
  220. (* FROM-import: clones mod's export into the current scope under
  221. its plain name. FALSE when mod/name is unknown. *)
  222. PROCEDURE MaterializeAlias (mod, name: ARRAY OF CHAR;
  223. VAR alias: Name): BOOLEAN;
  224. (* Qualified access: clones mod's export under a per-module alias
  225. key, so same-named exports of different modules never collide.
  226. The alias key is used for all subsequent lookups (types, uids,
  227. params); the node remembers its base name and module for QBE
  228. symbol emission. *)
  229. PROCEDURE SymBase (name: ARRAY OF CHAR; VAR base: Name): BOOLEAN;
  230. (* Base symbol name of the visible entry (drops any alias prefix). *)
  231. PROCEDURE GlobalRef (name: ARRAY OF CHAR; VAR g: Name): BOOLEAN;
  232. (* "<mod>_<sym>" QBE global-symbol name for a module-level entry;
  233. FALSE when name is not a module-level symbol. *)
  234. (* ---------------- classes (Clarion form, lowering deferred) ---------------- *)
  235. PROCEDURE EnterThisParam (cls: TypeIndex): BOOLEAN;
  236. (* Enters a method's hidden THIS VAR parameter. *)
  237. PROCEDURE LayoutClass (t: TypeIndex);
  238. (* Computes a class's field offsets / size. *)
  239. PROCEDURE ParentOf (t: TypeIndex): TypeIndex;
  240. (* The single parent class of t (InvalidType when none). *)
  241. PROCEDURE SetParent (t, p: TypeIndex);
  242. (* Records p as the (single) parent class of t. Multiple parents
  243. are rejected in the grammar with 230. *)
  244. PROCEDURE PushClassScope (t: TypeIndex);
  245. (* Pushes the body scope of class t and records it on t. *)
  246. PROCEDURE MethodExists (t: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  247. (* TRUE if the class scope of t declares name as a procedure. *)
  248. PROCEDURE ResumeMethod (ct: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  249. (* Resumes a declared class method for its CLASS IMPLEMENTATION body. *)
  250. PROCEDURE HasVTable (ct: TypeIndex): BOOLEAN;
  251. (* TRUE when the class (or an ancestor) has virtual methods. *)
  252. PROCEDURE VirtSlot (ct: TypeIndex; name: ARRAY OF CHAR): INTEGER;
  253. (* Vtable slot of the method, or -1 when it is not virtual. *)
  254. PROCEDURE IsSubclass (sub, sup: TypeIndex): BOOLEAN;
  255. (* TRUE when sub is sup or inherits (transitively) from sup. *)
  256. PROCEDURE VptrOffset (ct: TypeIndex): INTEGER;
  257. (* Byte offset of the class's vptr field (-1 when it has none). *)
  258. PROCEDURE PushImplClass (ct: TypeIndex);
  259. PROCEDURE PopImplClass;
  260. PROCEDURE CurImplClass (): TypeIndex;
  261. (* The innermost open CLASS IMPLEMENTATION's class (InvalidType none). *)
  262. PROCEDURE VtClassCount (): CARDINAL;
  263. PROCEDURE VtClassAt (k: CARDINAL): TypeIndex;
  264. (* Classes that have a vtable, in build order. *)
  265. PROCEDURE VtCount (ct: TypeIndex): CARDINAL;
  266. PROCEDURE VtName (ct: TypeIndex; k: CARDINAL; VAR name: Name): BOOLEAN;
  267. PROCEDURE VtHasBody (ct: TypeIndex; k: CARDINAL): BOOLEAN;
  268. (* TRUE when slot k's method has an emitted body. *)
  269. PROCEDURE VtUid (ct: TypeIndex; k: CARDINAL): CARDINAL;
  270. (* Virtual-method slot k of ct (inherited slots first). *)
  271. PROCEDURE MethUid (): CARDINAL;
  272. (* uid of the procedure currently being headed (0 when none). *)
  273. PROCEDURE ClassMethodUid (t: TypeIndex; name: ARRAY OF CHAR): CARDINAL;
  274. (* Unique id of method name in class t or an ancestor (0 if none). *)
  275. PROCEDURE ClassMethodNPar (t: TypeIndex; name: ARRAY OF CHAR): CARDINAL;
  276. (* User formal count of the method (the hidden THIS excluded). *)
  277. PROCEDURE ClassMethodRes (t: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
  278. (* Result type of the method (InvalidType if none/absent). *)
  279. PROCEDURE ClassMethodParamType (t: TypeIndex; name: ARRAY OF CHAR;
  280. i: CARDINAL): TypeIndex;
  281. PROCEDURE ClassMethodParamIsVar (t: TypeIndex; name: ARRAY OF CHAR;
  282. i: CARDINAL): BOOLEAN;
  283. (* User formal i of the method (index 0 skips the hidden THIS). *)
  284. PROCEDURE PushClassMembers (t: TypeIndex): BOOLEAN;
  285. (* Pushes a scope with t's fields (KindField) for method bodies in
  286. CLASS IMPLEMENTATION. FALSE if t is not a class. Method names
  287. are re-entered fresh by each body (copying them would collide);
  288. sibling-method references report 201 until step 4 calls. *)
  289. (* ---------------- type descriptors ---------------- *)
  290. PROCEDURE NewAlias (): TypeIndex;
  291. PROCEDURE NewSub (base: TypeIndex): TypeIndex;
  292. PROCEDURE NewSubR (lo, hi: INTEGER): TypeIndex;
  293. (* Integer subrange [lo..hi] (no base descriptor needed). Bounds
  294. accessors arrive with step 3; the backend cannot lower them yet. *)
  295. PROCEDURE NewEnum (): TypeIndex;
  296. PROCEDURE NewArrayB (elem: TypeIndex; lo, hi: INTEGER): TypeIndex;
  297. (* Bounded array (one dimension; nest for multi-dim). InvalidType
  298. when the table is full. *)
  299. PROCEDURE NewOpenArray (elem: TypeIndex): TypeIndex;
  300. (* Open ARRAY OF formal: 0-based, runtime count in the header.
  301. Only legal for formal parameters (grammar enforces). *)
  302. PROCEDURE BoundBegin;
  303. PROCEDURE BoundAdd (lo, hi: INTEGER): BOOLEAN;
  304. (* Accumulates one index bound pair for the enclosing ArrayType
  305. (max 8 dimensions, FALSE past that). *)
  306. PROCEDURE BoundCount (): CARDINAL;
  307. PROCEDURE BoundLo (i: CARDINAL): INTEGER;
  308. PROCEDURE BoundHi (i: CARDINAL): INTEGER;
  309. (* Read back the accumulated bounds (so a caller can snapshot them
  310. before parsing a nested element type that reuses the buffer). *)
  311. PROCEDURE NestArray (elem: TypeIndex): TypeIndex;
  312. (* Nests the accumulated bounds inside-out around elem. *)
  313. PROCEDURE NewRecord (): TypeIndex;
  314. PROCEDURE IsOrdinal (t: TypeIndex): BOOLEAN;
  315. (* integer family / CHAR / UCHAR / BOOLEAN / enumeration. *)
  316. PROCEDURE ResetFields (rec: TypeIndex);
  317. (* Starts a fresh variant branch (drops pending fields, clears layout). *)
  318. PROCEDURE SetVariantTag (rec: TypeIndex; name : ARRAY OF CHAR);
  319. (* Records the variant CASE selector field (by name). *)
  320. PROCEDURE MarkVariant (rec: TypeIndex);
  321. (* Marks rec as having a variant part (overlapping fields). *)
  322. PROCEDURE IsVariant (rec: TypeIndex): BOOLEAN;
  323. (* TRUE when rec has a variant part. *)
  324. PROCEDURE NewSet (base: TypeIndex): TypeIndex;
  325. PROCEDURE NewPtr (base: TypeIndex): TypeIndex;
  326. PROCEDURE NewStr (): TypeIndex;
  327. PROCEDURE NewUStr (): TypeIndex;
  328. (* UString literal type: LONGCARD count + count x UCHAR codepoints. *)
  329. PROCEDURE NewClass (): TypeIndex;
  330. (* Fresh class descriptor (holds fields like a record; methods live
  331. in the class scope). Parent and scope via SetParent/PushClassScope. *)
  332. (* Fresh descriptors; base/elem may be InvalidType. InvalidType is
  333. returned when the table is full. *)
  334. PROCEDURE SetTarget (t, base: TypeIndex);
  335. (* Sets an alias target (TYPE declaration completion). *)
  336. PROCEDURE BeginTypeBlock;
  337. PROCEDURE EndTypeBlock;
  338. (* Delimit a TYPE block so ForwardType is only active inside one. *)
  339. PROCEDURE ForwardType (name: ARRAY OF CHAR): TypeIndex;
  340. (* Inside a TYPE block: if name is not yet declared, enters it as an
  341. unresolved forward alias and returns its type index (completed by
  342. the later TypeItem via SetTarget). InvalidType when the name is
  343. already known or forward references are not permitted. *)
  344. PROCEDURE IsUnresolved (t: TypeIndex): BOOLEAN;
  345. (* TRUE for a forward placeholder whose target is not yet declared. *)
  346. PROCEDURE FwdPending (): CARDINAL;
  347. PROCEDURE FwdInfo (i: CARDINAL; VAR name: Name; VAR unresolved: BOOLEAN);
  348. (* Module-level forward type references: enumerate them at module end
  349. and flag those never completed (undeclared type). *)
  350. PROCEDURE FwdClear;
  351. PROCEDURE FwdVarRef (name: ARRAY OF CHAR; kind: INTEGER;
  352. VAR id: INTEGER; VAR t: TypeIndex): BOOLEAN;
  353. (* Registers a reference to a module-level name used inside a procedure
  354. body before its declaration (forward variable). kind is KindVar
  355. (variable) or KindProc (procedure); id/t identify the placeholder. *)
  356. PROCEDURE FwdVarType (id: INTEGER): TypeIndex;
  357. PROCEDURE FwdVarKind (id: INTEGER): INTEGER;
  358. PROCEDURE IsFwdVar (t: TypeIndex): BOOLEAN;
  359. (* TRUE for a forward-variable placeholder: type checks are lenient. *)
  360. PROCEDURE FwdVarName (id: INTEGER; VAR name: Name);
  361. (* The identifier behind forward reference id (1-based). *)
  362. PROCEDURE FwdVarResolve (id: INTEGER): BOOLEAN;
  363. (* Resolves forward reference id against the module's declarations:
  364. TRUE when the name now exists with the expected kind. *)
  365. PROCEDURE IntType (): TypeIndex;
  366. PROCEDURE UCharType (): TypeIndex;
  367. (* UCHAR: 32-bit Unicode codepoint (QBE w). *)
  368. PROCEDURE RealType (): TypeIndex;
  369. PROCEDURE CharType (): TypeIndex;
  370. PROCEDURE BoolType (): TypeIndex;
  371. PROCEDURE LongType (): TypeIndex;
  372. (* LONGINT/LONGCARD: 64-bit integer (QBE l). *)
  373. PROCEDURE AddrType (): TypeIndex;
  374. (* ADDRESS: the pointer-sized opaque type (interchangeable with any
  375. pointer for assignment and VAR parameters). *)
  376. PROCEDURE ObjectSize (t: TypeIndex): CARDINAL;
  377. (* Full allocation footprint (arrays 8 + count*element); drives
  378. SYSTEM.SIZE/TSIZE. *)
  379. PROCEDURE ClassOf (t: TypeIndex): INTEGER;
  380. (* Resolves aliases; InvalidType maps to ClInvalid. *)
  381. PROCEDURE IsIntFamily (t: TypeIndex): BOOLEAN;
  382. (* INTEGER, CARDINAL or subrange thereof (Invalid suppresses). *)
  383. PROCEDURE IsLongFamily (t: TypeIndex): BOOLEAN;
  384. (* LONGINT/LONGCARD (QBE l). *)
  385. PROCEDURE SameType (a, b: TypeIndex): BOOLEAN;
  386. (* Same resolved descriptor (Invalid suppresses). *)
  387. PROCEDURE FieldExists (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  388. PROCEDURE FieldType (rec: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
  389. PROCEDURE ArrayElem (t: TypeIndex): TypeIndex;
  390. PROCEDURE IsCharArray (t: TypeIndex): BOOLEAN;
  391. (* TRUE for arrays whose elements are CHAR: such arrays reserve one
  392. extra zero byte (index = count) so NUL-scanning works, matching
  393. gm2's NUL-terminated strings. *)
  394. PROCEDURE IsOpenArray (t: TypeIndex): BOOLEAN;
  395. PROCEDURE ArrayLo (t: TypeIndex): INTEGER;
  396. PROCEDURE ArrayHi (t: TypeIndex): INTEGER;
  397. (* Static bounds (open arrays: lo 0, hi undefined — backend reads
  398. the header instead). InvalidType maps to 0. *)
  399. PROCEDURE ArrayLen (t: TypeIndex): CARDINAL;
  400. (* Static element count, 0 for open/invalid. *)
  401. PROCEDURE ArrayDepth (t: TypeIndex): CARDINAL;
  402. (* Nesting depth (open/fixed levels); 0 for non-arrays. *)
  403. PROCEDURE TypeSize (t: TypeIndex): CARDINAL;
  404. (* Inline footprint in bytes: scalars 4/8, sets words*4, pointers,
  405. open and fixed arrays 8 (descriptor address), records sum of
  406. members. *)
  407. PROCEDURE FieldOffset (rec: TypeIndex; name: ARRAY OF CHAR): INTEGER;
  408. (* Declaration-order byte offset (-1 if absent). Computed lazily. *)
  409. PROCEDURE FieldOwner (name: ARRAY OF CHAR): TypeIndex;
  410. (* Owning record/class of the visible field (InvalidType if none). *)
  411. PROCEDURE FieldCount (rec: TypeIndex): CARDINAL;
  412. PROCEDURE FieldName (rec: TypeIndex; i: CARDINAL; VAR name: Name);
  413. (* Field enumeration for whole-record lowering (order irrelevant). *)
  414. PROCEDURE SubBounds (t: TypeIndex; VAR lo, hi: INTEGER): BOOLEAN;
  415. (* TRUE with the bounds when t resolves to a subrange. *)
  416. PROCEDURE SetBase (t: TypeIndex): TypeIndex;
  417. (* Base type of a set descriptor (InvalidType if none). *)
  418. PROCEDURE SetWords (t: TypeIndex): CARDINAL;
  419. (* Mask words for a set type from its base span (bool 1, char 8,
  420. subrange by bounds); 0 when the base is unsuitable. *)
  421. PROCEDURE SetBaseLo (t: TypeIndex): INTEGER;
  422. (* Base minimum (bool/char 0, subrange lo); 0 when unsuitable. *)
  423. PROCEDURE SetCount (t: TypeIndex): CARDINAL;
  424. (* Base span in values (0 when unsuitable). *)
  425. PROCEDURE TypeBounds (t: TypeIndex; VAR lo, hi: INTEGER): BOOLEAN;
  426. (* Ordinal bounds of a type (MIN/MAX): subrange/array, CHAR/UCHAR,
  427. BOOLEAN, enumeration, set base, or the integer family. *)
  428. PROCEDURE SetEnumCount (t: TypeIndex; n: CARDINAL);
  429. (* Records the number of literals of an enumeration type. *)
  430. PROCEDURE EnumCount (t: TypeIndex): CARDINAL;
  431. (* Literal count of an enumeration type (0 when not an enum). *)
  432. PROCEDURE PtrBase (t: TypeIndex): TypeIndex;
  433. (* ---------------- procedure types (step 8.5) ---------------- *)
  434. (* PROCEDURE (params): result as a value type. Values are code
  435. pointers (pointer-sized); calls through them are indirect. Param
  436. lists are collected with ProcTypeBegin/ProcTypeAdd and finalised
  437. by NewProcType (same pattern as array bounds). *)
  438. PROCEDURE NewProcType (res: TypeIndex): TypeIndex;
  439. (* Fresh procedure type (result may be InvalidType, set later). Its
  440. parameters are appended in order with ProcTypeAdd. *)
  441. PROCEDURE ProcTypeAdd (t: TypeIndex; isVar: BOOLEAN; pt: TypeIndex);
  442. PROCEDURE SetProcTypeRes (t: TypeIndex; res: TypeIndex);
  443. PROCEDURE ProcTypeNPar (t: TypeIndex): CARDINAL;
  444. PROCEDURE ProcTypeParamType (t: TypeIndex; i: CARDINAL): TypeIndex;
  445. PROCEDURE ProcTypeParamIsVar (t: TypeIndex; i: CARDINAL): BOOLEAN;
  446. PROCEDURE ProcTypeRes (t: TypeIndex): TypeIndex;
  447. (* Accessors for a procedure type (0/InvalidType when not one). *)
  448. PROCEDURE ProcTypeOf (name: ARRAY OF CHAR): TypeIndex;
  449. (* Builds the procedure type descriptor for procedure name (for using
  450. a procedure as a value). InvalidType if name is not a procedure. *)
  451. (* ---------------- predicates used by grammar checks ---------------- *)
  452. (* All return TRUE if either operand is InvalidType (no cascades). *)
  453. PROCEDURE Assignable (src, dst: TypeIndex): BOOLEAN;
  454. (* Assignment compatibility (210). *)
  455. PROCEDURE ArithCheck (l, r: TypeIndex; divmod: BOOLEAN;
  456. VAR res: TypeIndex): BOOLEAN;
  457. (* + - * / (divmod FALSE) or DIV MOD (TRUE); res is result type (211). *)
  458. PROCEDURE UnaryCheck (t: TypeIndex; VAR res: TypeIndex): BOOLEAN;
  459. (* Unary + - (part of 211). *)
  460. PROCEDURE BoolCheck (t: TypeIndex): BOOLEAN;
  461. (* BOOLEAN required: NOT/AND/OR operands (212), conditions (214). *)
  462. PROCEDURE RelCheck (l, r: TypeIndex; op: INTEGER): BOOLEAN;
  463. (* = # <> < <= > >= IN (213/222 chosen by caller via op). *)
  464. PROCEDURE IsStrType (t: TypeIndex): BOOLEAN;
  465. (* A string literal (ClStr) or a 1-D ARRAY OF CHAR. *)
  466. PROCEDURE UStrCompat (l, r: TypeIndex): BOOLEAN;
  467. (* Both operands are UString literals (U"..."): `+` concatenates. *)
  468. PROCEDURE IsUCharArray (t: TypeIndex): BOOLEAN;
  469. (* A 1-D ARRAY OF UCHAR (a U"..." content-copy destination). *)
  470. PROCEDURE StrCompat (l, r: TypeIndex): BOOLEAN;
  471. (* Both operands are string-compatible (ClStr / 1-D ARRAY OF CHAR):
  472. `=`/`#` compare content via the shim. *)
  473. PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
  474. (* = # compatibility, also reused for CASE label matching. *)
  475. PROCEDURE InCheck (l, set: TypeIndex): BOOLEAN;
  476. (* Membership `l IN set`. *)
  477. PROCEDURE SetElemClassOk (c: INTEGER): BOOLEAN;
  478. (* TRUE for an element class acceptable in a set constructor. *)
  479. PROCEDURE SetElemCheck (first, elem: TypeIndex): BOOLEAN;
  480. PROCEDURE SetFor (elem: TypeIndex): TypeIndex;
  481. (* Fresh SET OF elem descriptor for set literals. *)
  482. PROCEDURE StrLen (s: ARRAY OF CHAR): CARDINAL;
  483. PROCEDURE ConstInt (q: ARRAY OF CHAR; VAR v: INTEGER): BOOLEAN;
  484. (* Parses a folded integer immediate ("42", "-5", "16") as produced
  485. by NormInt/NegFold. FALSE for temporaries and non-numerics. *)
  486. END SymTab.