SymTab.mod 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. IMPLEMENTATION MODULE SymTab;
  2. IMPORT FileIO;
  3. CONST
  4. MaxTypes = 256;
  5. MaxFields = 512;
  6. MaxPend = 64;
  7. MaxMarks = 16;
  8. ResDepth = 64;
  9. (* descriptor forms *)
  10. FNone = 0; FAlias = 1; FSub = 2; FEnum = 3; FArray = 4;
  11. FRecord = 5; FSet = 6; FPtr = 7; FStr = 8;
  12. FInt = 9; FReal = 10; FChar = 11; FBool = 12;
  13. TYPE
  14. Symbol = RECORD
  15. name : Name;
  16. kind : INTEGER;
  17. typ : TypeIndex;
  18. lev : CARDINAL;
  19. END;
  20. Field = RECORD
  21. name : Name;
  22. typ : TypeIndex;
  23. owner : TypeIndex;
  24. next : INTEGER; (* index of next field of same owner, -1 = end *)
  25. END;
  26. VAR
  27. syms : ARRAY [0 .. MaxSyms - 1] OF Symbol;
  28. nSyms : CARDINAL;
  29. curLev : CARDINAL;
  30. marks : ARRAY [0 .. MaxMarks - 1] OF CARDINAL;
  31. mtop : CARDINAL;
  32. pend : ARRAY [0 .. MaxPend - 1] OF CARDINAL;
  33. nPend : CARDINAL;
  34. pendF : ARRAY [0 .. MaxPend - 1] OF CARDINAL;
  35. nPendF : CARDINAL;
  36. tform : ARRAY [0 .. MaxTypes - 1] OF INTEGER;
  37. tref : ARRAY [0 .. MaxTypes - 1] OF TypeIndex;
  38. nTypes : CARDINAL;
  39. fields : ARRAY [0 .. MaxFields - 1] OF Field;
  40. nFields : CARDINAL;
  41. dInt, dCard, dReal, dChar, dBool : TypeIndex;
  42. (* ---------------- strings ---------------- *)
  43. PROCEDURE Assign (VAR dest: ARRAY OF CHAR; src: ARRAY OF CHAR);
  44. VAR i : CARDINAL;
  45. BEGIN
  46. i := 0;
  47. WHILE (i < HIGH(dest)) & (src[i] # 0C) DO
  48. dest[i] := src[i]; INC(i)
  49. END;
  50. dest[i] := 0C
  51. END Assign;
  52. PROCEDURE Equal (a, b: ARRAY OF CHAR): BOOLEAN;
  53. VAR i : CARDINAL;
  54. BEGIN
  55. i := 0;
  56. LOOP
  57. IF a[i] # b[i] THEN RETURN FALSE END;
  58. IF a[i] = 0C THEN RETURN TRUE END;
  59. INC(i)
  60. END
  61. END Equal;
  62. PROCEDURE StrLen (s: ARRAY OF CHAR): CARDINAL;
  63. VAR i : CARDINAL;
  64. BEGIN
  65. i := 0;
  66. WHILE (i < HIGH(s)) & (s[i] # 0C) DO INC(i) END;
  67. RETURN i
  68. END StrLen;
  69. (* ---------------- symbols and scopes ---------------- *)
  70. PROCEDURE Find (name: ARRAY OF CHAR): INTEGER;
  71. (* innermost visible index or -1 *)
  72. VAR i : CARDINAL;
  73. BEGIN
  74. i := nSyms;
  75. WHILE i > 0 DO
  76. DEC(i);
  77. IF Equal(syms[i].name, name) THEN RETURN VAL(INTEGER, i) END
  78. END;
  79. RETURN -1
  80. END Find;
  81. PROCEDURE RawEnter (name: ARRAY OF CHAR; kind: INTEGER): INTEGER;
  82. (* index or -1 when full *)
  83. BEGIN
  84. IF nSyms >= MaxSyms THEN RETURN -1 END;
  85. Assign(syms[nSyms].name, name);
  86. syms[nSyms].kind := kind;
  87. syms[nSyms].typ := InvalidType;
  88. syms[nSyms].lev := curLev;
  89. INC(nSyms);
  90. RETURN VAL(INTEGER, nSyms - 1)
  91. END RawEnter;
  92. PROCEDURE DupInLevel (name: ARRAY OF CHAR): BOOLEAN;
  93. VAR i : CARDINAL;
  94. BEGIN
  95. i := nSyms;
  96. WHILE (i > 0) & (syms[i - 1].lev = curLev) DO
  97. DEC(i);
  98. IF Equal(syms[i].name, name) THEN RETURN TRUE END
  99. END;
  100. RETURN FALSE
  101. END DupInLevel;
  102. PROCEDURE Enter (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  103. BEGIN
  104. IF DupInLevel(name) THEN RETURN FALSE END;
  105. RETURN RawEnter(name, kind) # -1
  106. END Enter;
  107. PROCEDURE EnterPending (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
  108. VAR idx : INTEGER;
  109. BEGIN
  110. IF DupInLevel(name) THEN RETURN FALSE END;
  111. idx := RawEnter(name, kind);
  112. IF (idx # -1) & (nPend < MaxPend) THEN
  113. pend[nPend] := VAL(CARDINAL, idx); INC(nPend)
  114. END;
  115. RETURN idx # -1
  116. END EnterPending;
  117. PROCEDURE FixPending (t: TypeIndex);
  118. VAR i : CARDINAL;
  119. BEGIN
  120. i := 0;
  121. WHILE i < nPend DO
  122. syms[pend[i]].typ := t; INC(i)
  123. END;
  124. nPend := 0
  125. END FixPending;
  126. PROCEDURE FindField (rec: TypeIndex; name: ARRAY OF CHAR): INTEGER;
  127. VAR i : INTEGER;
  128. BEGIN
  129. IF (rec < 0) OR (rec >= VAL(INTEGER, nTypes)) THEN RETURN -1 END;
  130. IF tform[rec] # FRecord THEN RETURN -1 END;
  131. i := tref[rec];
  132. WHILE i # -1 DO
  133. IF Equal(fields[i].name, name) THEN RETURN i END;
  134. i := fields[i].next
  135. END;
  136. RETURN -1
  137. END FindField;
  138. PROCEDURE FieldPending (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  139. BEGIN
  140. IF FindField(rec, name) # -1 THEN RETURN FALSE END;
  141. IF nFields >= MaxFields THEN RETURN FALSE END;
  142. Assign(fields[nFields].name, name);
  143. fields[nFields].typ := InvalidType;
  144. fields[nFields].owner := rec;
  145. fields[nFields].next := tref[rec];
  146. tref[rec] := VAL(INTEGER, nFields);
  147. IF nPendF < MaxPend THEN
  148. pendF[nPendF] := nFields; INC(nPendF)
  149. END;
  150. INC(nFields);
  151. RETURN TRUE
  152. END FieldPending;
  153. PROCEDURE FixPendingF (rec: TypeIndex; t: TypeIndex);
  154. VAR i, j : CARDINAL;
  155. BEGIN
  156. i := 0;
  157. WHILE i < nPendF DO
  158. IF fields[pendF[i]].owner = rec THEN
  159. fields[pendF[i]].typ := t;
  160. (* remove by swap with last *)
  161. j := nPendF - 1;
  162. pendF[i] := pendF[j];
  163. DEC(nPendF)
  164. ELSE
  165. INC(i)
  166. END
  167. END
  168. END FixPendingF;
  169. PROCEDURE Lookup (name: ARRAY OF CHAR): BOOLEAN;
  170. BEGIN
  171. RETURN Find(name) # -1
  172. END Lookup;
  173. PROCEDURE SymType (name: ARRAY OF CHAR): TypeIndex;
  174. VAR idx : INTEGER;
  175. BEGIN
  176. idx := Find(name);
  177. IF idx = -1 THEN RETURN InvalidType END;
  178. RETURN syms[idx].typ
  179. END SymType;
  180. PROCEDURE SetSymType (name: ARRAY OF CHAR; t: TypeIndex);
  181. VAR idx : INTEGER;
  182. BEGIN
  183. idx := Find(name);
  184. IF idx # -1 THEN syms[idx].typ := t END
  185. END SetSymType;
  186. PROCEDURE SymKind (name: ARRAY OF CHAR): INTEGER;
  187. VAR idx : INTEGER;
  188. BEGIN
  189. idx := Find(name);
  190. IF idx = -1 THEN RETURN -1 END;
  191. RETURN syms[idx].kind
  192. END SymKind;
  193. PROCEDURE PushScope;
  194. BEGIN
  195. IF mtop < MaxMarks THEN marks[mtop] := nSyms; INC(mtop) END;
  196. INC(curLev)
  197. END PushScope;
  198. PROCEDURE PopScope;
  199. BEGIN
  200. IF mtop > 0 THEN DEC(mtop); nSyms := marks[mtop] END;
  201. IF curLev > 0 THEN DEC(curLev) END
  202. END PopScope;
  203. (* ---------------- type descriptors ---------------- *)
  204. PROCEDURE NewDesc (form: INTEGER; ref: TypeIndex): TypeIndex;
  205. BEGIN
  206. IF nTypes >= MaxTypes THEN RETURN InvalidType END;
  207. tform[nTypes] := form;
  208. tref[nTypes] := ref;
  209. INC(nTypes);
  210. RETURN VAL(INTEGER, nTypes - 1)
  211. END NewDesc;
  212. PROCEDURE NewAlias (): TypeIndex;
  213. BEGIN
  214. RETURN NewDesc(FAlias, InvalidType)
  215. END NewAlias;
  216. PROCEDURE NewSub (base: TypeIndex): TypeIndex;
  217. BEGIN
  218. RETURN NewDesc(FSub, base)
  219. END NewSub;
  220. PROCEDURE NewEnum (): TypeIndex;
  221. BEGIN
  222. RETURN NewDesc(FEnum, InvalidType)
  223. END NewEnum;
  224. PROCEDURE NewArray (elem: TypeIndex): TypeIndex;
  225. BEGIN
  226. RETURN NewDesc(FArray, elem)
  227. END NewArray;
  228. PROCEDURE NewRecord (): TypeIndex;
  229. BEGIN
  230. RETURN NewDesc(FRecord, -1)
  231. END NewRecord;
  232. PROCEDURE NewSet (base: TypeIndex): TypeIndex;
  233. BEGIN
  234. RETURN NewDesc(FSet, base)
  235. END NewSet;
  236. PROCEDURE NewPtr (base: TypeIndex): TypeIndex;
  237. BEGIN
  238. RETURN NewDesc(FPtr, base)
  239. END NewPtr;
  240. PROCEDURE NewStr (): TypeIndex;
  241. BEGIN
  242. RETURN NewDesc(FStr, InvalidType)
  243. END NewStr;
  244. PROCEDURE SetTarget (t, base: TypeIndex);
  245. BEGIN
  246. IF (t >= 0) & (t < VAL(INTEGER, nTypes)) & (tform[t] = FAlias) THEN
  247. tref[t] := base
  248. END
  249. END SetTarget;
  250. PROCEDURE Resolve (t: TypeIndex): TypeIndex;
  251. VAR n : CARDINAL;
  252. BEGIN
  253. n := 0;
  254. WHILE (n < ResDepth) & (t >= 0) & (t < VAL(INTEGER, nTypes))
  255. & (tform[t] = FAlias) DO
  256. t := tref[t]; INC(n)
  257. END;
  258. IF (t < 0) OR (t >= VAL(INTEGER, nTypes)) THEN
  259. RETURN InvalidType
  260. END;
  261. RETURN t
  262. END Resolve;
  263. PROCEDURE IntType (): TypeIndex;
  264. BEGIN RETURN dInt END IntType;
  265. PROCEDURE RealType (): TypeIndex;
  266. BEGIN RETURN dReal END RealType;
  267. PROCEDURE CharType (): TypeIndex;
  268. BEGIN RETURN dChar END CharType;
  269. PROCEDURE BoolType (): TypeIndex;
  270. BEGIN RETURN dBool END BoolType;
  271. PROCEDURE ClassOf (t: TypeIndex): INTEGER;
  272. VAR r : TypeIndex;
  273. BEGIN
  274. r := Resolve(t);
  275. IF r = InvalidType THEN RETURN ClInvalid END;
  276. CASE tform[r] OF
  277. FInt : RETURN ClInt
  278. | FReal : RETURN ClReal
  279. | FChar : RETURN ClChar
  280. | FBool : RETURN ClBool
  281. | FEnum : RETURN ClEnum
  282. | FArray : RETURN ClArray
  283. | FRecord : RETURN ClRecord
  284. | FSet : RETURN ClSet
  285. | FPtr : RETURN ClPtr
  286. | FStr : RETURN ClStr
  287. | FSub : RETURN ClassOf(tref[r])
  288. ELSE RETURN ClInvalid
  289. END
  290. END ClassOf;
  291. PROCEDURE IsIntFamily (t: TypeIndex): BOOLEAN;
  292. BEGIN
  293. RETURN ClassOf(t) = ClInt
  294. END IsIntFamily;
  295. PROCEDURE SameType (a, b: TypeIndex): BOOLEAN;
  296. BEGIN
  297. IF (a = InvalidType) OR (b = InvalidType) THEN RETURN TRUE END;
  298. RETURN Resolve(a) = Resolve(b)
  299. END SameType;
  300. PROCEDURE FieldExists (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  301. BEGIN
  302. RETURN FindField(Resolve(rec), name) # -1
  303. END FieldExists;
  304. PROCEDURE FieldType (rec: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
  305. VAR i : INTEGER;
  306. BEGIN
  307. i := FindField(Resolve(rec), name);
  308. IF i = -1 THEN RETURN InvalidType END;
  309. RETURN fields[i].typ
  310. END FieldType;
  311. PROCEDURE ArrayElem (t: TypeIndex): TypeIndex;
  312. VAR r : TypeIndex;
  313. BEGIN
  314. r := Resolve(t);
  315. IF (r = InvalidType) OR (tform[r] # FArray) THEN
  316. RETURN InvalidType
  317. END;
  318. RETURN tref[r]
  319. END ArrayElem;
  320. PROCEDURE PtrBase (t: TypeIndex): TypeIndex;
  321. VAR r : TypeIndex;
  322. BEGIN
  323. r := Resolve(t);
  324. IF (r = InvalidType) OR (tform[r] # FPtr) THEN
  325. RETURN InvalidType
  326. END;
  327. RETURN tref[r]
  328. END PtrBase;
  329. PROCEDURE PushRecord (t: TypeIndex): BOOLEAN;
  330. (* Pushes a scope with t's fields; caller must PopScope afterwards. *)
  331. VAR r, i : INTEGER;
  332. BEGIN
  333. r := Resolve(t);
  334. IF (r < 0) OR (tform[r] # FRecord) THEN RETURN FALSE END;
  335. PushScope;
  336. i := tref[r];
  337. WHILE i # -1 DO
  338. IF Enter(fields[i].name, KindField) THEN
  339. SetSymType(fields[i].name, fields[i].typ)
  340. END;
  341. i := fields[i].next
  342. END;
  343. RETURN TRUE
  344. END PushRecord;
  345. (* ---------------- predicates ---------------- *)
  346. PROCEDURE SetBasesOk (a, b: TypeIndex): BOOLEAN;
  347. (* base compatibility for two SET types *)
  348. BEGIN
  349. IF SameType(a, b) THEN RETURN TRUE END;
  350. IF IsIntFamily(a) & IsIntFamily(b) THEN RETURN TRUE END;
  351. IF (ClassOf(a) = ClChar) & (ClassOf(b) = ClChar) THEN
  352. RETURN TRUE
  353. END;
  354. RETURN FALSE
  355. END SetBasesOk;
  356. PROCEDURE Assignable (src, dst: TypeIndex): BOOLEAN;
  357. VAR rs, rd : TypeIndex;
  358. BEGIN
  359. IF (src = InvalidType) OR (dst = InvalidType) THEN RETURN TRUE END;
  360. rs := Resolve(src); rd := Resolve(dst);
  361. IF rs = rd THEN RETURN TRUE END;
  362. IF (rs = InvalidType) OR (rd = InvalidType) THEN RETURN TRUE END;
  363. IF (tform[rs] = FSet) & (tform[rd] = FSet) THEN
  364. RETURN SetBasesOk(tref[rs], tref[rd])
  365. END;
  366. IF (ClassOf(src) = ClInt) & (ClassOf(dst) = ClInt) THEN
  367. RETURN TRUE
  368. END;
  369. IF (ClassOf(src) = ClInt) & (ClassOf(dst) = ClReal) THEN
  370. RETURN TRUE
  371. END;
  372. IF (ClassOf(src) = ClStr) & (ClassOf(dst) = ClArray) THEN
  373. RETURN TRUE
  374. END;
  375. RETURN FALSE
  376. END Assignable;
  377. PROCEDURE ArithCheck (l, r: TypeIndex; divmod: BOOLEAN;
  378. VAR res: TypeIndex): BOOLEAN;
  379. BEGIN
  380. res := InvalidType;
  381. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  382. IF IsIntFamily(l) & IsIntFamily(r) THEN
  383. res := dInt; RETURN TRUE
  384. END;
  385. IF ~divmod & (ClassOf(l) = ClReal) & (ClassOf(r) = ClReal) THEN
  386. res := dReal; RETURN TRUE
  387. END;
  388. RETURN FALSE
  389. END ArithCheck;
  390. PROCEDURE UnaryCheck (t: TypeIndex; VAR res: TypeIndex): BOOLEAN;
  391. BEGIN
  392. res := InvalidType;
  393. IF t = InvalidType THEN RETURN TRUE END;
  394. IF IsIntFamily(t) THEN res := dInt; RETURN TRUE END;
  395. IF ClassOf(t) = ClReal THEN res := dReal; RETURN TRUE END;
  396. RETURN FALSE
  397. END UnaryCheck;
  398. PROCEDURE BoolCheck (t: TypeIndex): BOOLEAN;
  399. BEGIN
  400. IF t = InvalidType THEN RETURN TRUE END;
  401. RETURN ClassOf(t) = ClBool
  402. END BoolCheck;
  403. PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
  404. VAR rl, rr : TypeIndex;
  405. BEGIN
  406. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  407. IF SameType(l, r) THEN RETURN TRUE END;
  408. IF IsIntFamily(l) & IsIntFamily(r) THEN RETURN TRUE END;
  409. IF (ClassOf(l) = ClReal) & (ClassOf(r) = ClReal) THEN
  410. RETURN TRUE
  411. END;
  412. IF (ClassOf(l) = ClChar) & (ClassOf(r) = ClChar) THEN
  413. RETURN TRUE
  414. END;
  415. IF (ClassOf(l) = ClBool) & (ClassOf(r) = ClBool) THEN
  416. RETURN TRUE
  417. END;
  418. IF (ClassOf(l) = ClStr) & (ClassOf(r) = ClStr) THEN
  419. RETURN TRUE
  420. END;
  421. rl := Resolve(l); rr := Resolve(r);
  422. IF (rl = InvalidType) OR (rr = InvalidType) THEN RETURN TRUE END;
  423. IF (tform[rl] = FSet) & (tform[rr] = FSet) THEN
  424. RETURN SetBasesOk(tref[rl], tref[rr])
  425. END;
  426. RETURN FALSE
  427. END EqCheck;
  428. PROCEDURE OrdCheck (l, r: TypeIndex): BOOLEAN;
  429. BEGIN
  430. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  431. IF IsIntFamily(l) & IsIntFamily(r) THEN RETURN TRUE END;
  432. IF (ClassOf(l) = ClReal) & (ClassOf(r) = ClReal) THEN
  433. RETURN TRUE
  434. END;
  435. IF (ClassOf(l) = ClChar) & (ClassOf(r) = ClChar) THEN
  436. RETURN TRUE
  437. END;
  438. IF (ClassOf(l) = ClEnum) & SameType(l, r) THEN RETURN TRUE END;
  439. RETURN FALSE
  440. END OrdCheck;
  441. PROCEDURE InCheck (l, set: TypeIndex): BOOLEAN;
  442. VAR rs, b : TypeIndex;
  443. BEGIN
  444. IF (l = InvalidType) OR (set = InvalidType) THEN RETURN TRUE END;
  445. rs := Resolve(set);
  446. IF (rs = InvalidType) OR (tform[rs] # FSet) THEN RETURN FALSE END;
  447. b := tref[rs];
  448. IF SameType(l, b) THEN RETURN TRUE END;
  449. IF IsIntFamily(l) & IsIntFamily(b) THEN RETURN TRUE END;
  450. IF (ClassOf(l) = ClChar) & (ClassOf(b) = ClChar) THEN
  451. RETURN TRUE
  452. END;
  453. RETURN FALSE
  454. END InCheck;
  455. PROCEDURE RelCheck (l, r: TypeIndex; op: INTEGER): BOOLEAN;
  456. BEGIN
  457. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  458. IF op = OpIn THEN RETURN InCheck(l, r) END;
  459. IF (op = OpEq) OR (op = OpNeq1) OR (op = OpNeq2) THEN
  460. RETURN EqCheck(l, r)
  461. END;
  462. RETURN OrdCheck(l, r)
  463. END RelCheck;
  464. PROCEDURE SetElemCheck (first, elem: TypeIndex): BOOLEAN;
  465. BEGIN
  466. IF (first = InvalidType) OR (elem = InvalidType) THEN
  467. RETURN TRUE
  468. END;
  469. IF SameType(first, elem) THEN RETURN TRUE END;
  470. IF IsIntFamily(first) & IsIntFamily(elem) THEN RETURN TRUE END;
  471. RETURN FALSE
  472. END SetElemCheck;
  473. PROCEDURE SetFor (elem: TypeIndex): TypeIndex;
  474. VAR e : TypeIndex;
  475. BEGIN
  476. e := Resolve(elem);
  477. IF e = InvalidType THEN e := dInt END;
  478. RETURN NewSet(e)
  479. END SetFor;
  480. (* ---------------- init ---------------- *)
  481. PROCEDURE Predef (name: ARRAY OF CHAR; kind: INTEGER; t: TypeIndex);
  482. BEGIN
  483. IF Enter(name, kind) THEN SetSymType(name, t) END
  484. END Predef;
  485. PROCEDURE Init;
  486. BEGIN
  487. nSyms := 0; curLev := 0; mtop := 0;
  488. nPend := 0; nPendF := 0;
  489. nTypes := 0; nFields := 0;
  490. dInt := NewDesc(FInt, InvalidType);
  491. dCard := NewDesc(FInt, InvalidType);
  492. dReal := NewDesc(FReal, InvalidType);
  493. dChar := NewDesc(FChar, InvalidType);
  494. dBool := NewDesc(FBool, InvalidType);
  495. Predef("INTEGER", KindPredef, dInt);
  496. Predef("CARDINAL", KindPredef, dCard);
  497. Predef("SHORTINT", KindPredef, dInt);
  498. Predef("LONGINT", KindPredef, dInt);
  499. Predef("REAL", KindPredef, dReal);
  500. Predef("LONGREAL", KindPredef, dReal);
  501. Predef("CHAR", KindPredef, dChar);
  502. Predef("BOOLEAN", KindPredef, dBool);
  503. Predef("TRUE", KindConst, dBool);
  504. Predef("FALSE", KindConst, dBool);
  505. Predef("NIL", KindConst, InvalidType)
  506. END Init;
  507. (* ---------------- listing ---------------- *)
  508. PROCEDURE WriteKind (kind: INTEGER);
  509. BEGIN
  510. CASE kind OF
  511. KindConst : FileIO.WriteString(FileIO.StdOut, "CONST")
  512. | KindType : FileIO.WriteString(FileIO.StdOut, "TYPE")
  513. | KindVar : FileIO.WriteString(FileIO.StdOut, "VAR")
  514. | KindImport : FileIO.WriteString(FileIO.StdOut, "IMPORT")
  515. | KindModule : FileIO.WriteString(FileIO.StdOut, "MODULE")
  516. | KindPredef : FileIO.WriteString(FileIO.StdOut, "PREDEF")
  517. | KindField : FileIO.WriteString(FileIO.StdOut, "FIELD")
  518. ELSE FileIO.WriteString(FileIO.StdOut, "???")
  519. END
  520. END WriteKind;
  521. PROCEDURE PrintTable;
  522. VAR i : CARDINAL;
  523. BEGIN
  524. FileIO.WriteLn(FileIO.StdOut);
  525. FileIO.WriteString(FileIO.StdOut, "--- Symbol table ---");
  526. FileIO.WriteLn(FileIO.StdOut);
  527. i := 0;
  528. WHILE i < nSyms DO
  529. FileIO.WriteString(FileIO.StdOut, " ");
  530. FileIO.WriteString(FileIO.StdOut, syms[i].name);
  531. FileIO.WriteString(FileIO.StdOut, " : ");
  532. WriteKind(syms[i].kind);
  533. FileIO.WriteString(FileIO.StdOut, " #");
  534. FileIO.WriteInt(FileIO.StdOut, syms[i].typ, 1);
  535. FileIO.WriteLn(FileIO.StdOut);
  536. INC(i)
  537. END
  538. END PrintTable;
  539. BEGIN
  540. Init
  541. END SymTab.