SymTab.mod 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  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 PendCount (): CARDINAL;
  127. BEGIN
  128. RETURN nPend
  129. END PendCount;
  130. PROCEDURE PendName (i: CARDINAL; VAR n: Name);
  131. BEGIN
  132. IF i < nPend THEN Assign(n, syms[pend[i]].name)
  133. ELSE n[0] := 0C
  134. END
  135. END PendName;
  136. PROCEDURE FindField (rec: TypeIndex; name: ARRAY OF CHAR): INTEGER;
  137. VAR i : INTEGER;
  138. BEGIN
  139. IF (rec < 0) OR (rec >= VAL(INTEGER, nTypes)) THEN RETURN -1 END;
  140. IF tform[rec] # FRecord THEN RETURN -1 END;
  141. i := tref[rec];
  142. WHILE i # -1 DO
  143. IF Equal(fields[i].name, name) THEN RETURN i END;
  144. i := fields[i].next
  145. END;
  146. RETURN -1
  147. END FindField;
  148. PROCEDURE FieldPending (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  149. BEGIN
  150. IF FindField(rec, name) # -1 THEN RETURN FALSE END;
  151. IF nFields >= MaxFields THEN RETURN FALSE END;
  152. Assign(fields[nFields].name, name);
  153. fields[nFields].typ := InvalidType;
  154. fields[nFields].owner := rec;
  155. fields[nFields].next := tref[rec];
  156. tref[rec] := VAL(INTEGER, nFields);
  157. IF nPendF < MaxPend THEN
  158. pendF[nPendF] := nFields; INC(nPendF)
  159. END;
  160. INC(nFields);
  161. RETURN TRUE
  162. END FieldPending;
  163. PROCEDURE FixPendingF (rec: TypeIndex; t: TypeIndex);
  164. VAR i, j : CARDINAL;
  165. BEGIN
  166. i := 0;
  167. WHILE i < nPendF DO
  168. IF fields[pendF[i]].owner = rec THEN
  169. fields[pendF[i]].typ := t;
  170. (* remove by swap with last *)
  171. j := nPendF - 1;
  172. pendF[i] := pendF[j];
  173. DEC(nPendF)
  174. ELSE
  175. INC(i)
  176. END
  177. END
  178. END FixPendingF;
  179. PROCEDURE Lookup (name: ARRAY OF CHAR): BOOLEAN;
  180. BEGIN
  181. RETURN Find(name) # -1
  182. END Lookup;
  183. PROCEDURE SymType (name: ARRAY OF CHAR): TypeIndex;
  184. VAR idx : INTEGER;
  185. BEGIN
  186. idx := Find(name);
  187. IF idx = -1 THEN RETURN InvalidType END;
  188. RETURN syms[idx].typ
  189. END SymType;
  190. PROCEDURE SetSymType (name: ARRAY OF CHAR; t: TypeIndex);
  191. VAR idx : INTEGER;
  192. BEGIN
  193. idx := Find(name);
  194. IF idx # -1 THEN syms[idx].typ := t END
  195. END SetSymType;
  196. PROCEDURE SymKind (name: ARRAY OF CHAR): INTEGER;
  197. VAR idx : INTEGER;
  198. BEGIN
  199. idx := Find(name);
  200. IF idx = -1 THEN RETURN -1 END;
  201. RETURN syms[idx].kind
  202. END SymKind;
  203. PROCEDURE PushScope;
  204. BEGIN
  205. IF mtop < MaxMarks THEN marks[mtop] := nSyms; INC(mtop) END;
  206. INC(curLev)
  207. END PushScope;
  208. PROCEDURE PopScope;
  209. BEGIN
  210. IF mtop > 0 THEN DEC(mtop); nSyms := marks[mtop] END;
  211. IF curLev > 0 THEN DEC(curLev) END
  212. END PopScope;
  213. (* ---------------- type descriptors ---------------- *)
  214. PROCEDURE NewDesc (form: INTEGER; ref: TypeIndex): TypeIndex;
  215. BEGIN
  216. IF nTypes >= MaxTypes THEN RETURN InvalidType END;
  217. tform[nTypes] := form;
  218. tref[nTypes] := ref;
  219. INC(nTypes);
  220. RETURN VAL(INTEGER, nTypes - 1)
  221. END NewDesc;
  222. PROCEDURE NewAlias (): TypeIndex;
  223. BEGIN
  224. RETURN NewDesc(FAlias, InvalidType)
  225. END NewAlias;
  226. PROCEDURE NewSub (base: TypeIndex): TypeIndex;
  227. BEGIN
  228. RETURN NewDesc(FSub, base)
  229. END NewSub;
  230. PROCEDURE NewEnum (): TypeIndex;
  231. BEGIN
  232. RETURN NewDesc(FEnum, InvalidType)
  233. END NewEnum;
  234. PROCEDURE NewArray (elem: TypeIndex): TypeIndex;
  235. BEGIN
  236. RETURN NewDesc(FArray, elem)
  237. END NewArray;
  238. PROCEDURE NewRecord (): TypeIndex;
  239. BEGIN
  240. RETURN NewDesc(FRecord, -1)
  241. END NewRecord;
  242. PROCEDURE NewSet (base: TypeIndex): TypeIndex;
  243. BEGIN
  244. RETURN NewDesc(FSet, base)
  245. END NewSet;
  246. PROCEDURE NewPtr (base: TypeIndex): TypeIndex;
  247. BEGIN
  248. RETURN NewDesc(FPtr, base)
  249. END NewPtr;
  250. PROCEDURE NewStr (): TypeIndex;
  251. BEGIN
  252. RETURN NewDesc(FStr, InvalidType)
  253. END NewStr;
  254. PROCEDURE SetTarget (t, base: TypeIndex);
  255. BEGIN
  256. IF (t >= 0) & (t < VAL(INTEGER, nTypes)) & (tform[t] = FAlias) THEN
  257. tref[t] := base
  258. END
  259. END SetTarget;
  260. PROCEDURE Resolve (t: TypeIndex): TypeIndex;
  261. VAR n : CARDINAL;
  262. BEGIN
  263. n := 0;
  264. WHILE (n < ResDepth) & (t >= 0) & (t < VAL(INTEGER, nTypes))
  265. & (tform[t] = FAlias) DO
  266. t := tref[t]; INC(n)
  267. END;
  268. IF (t < 0) OR (t >= VAL(INTEGER, nTypes)) THEN
  269. RETURN InvalidType
  270. END;
  271. RETURN t
  272. END Resolve;
  273. PROCEDURE IntType (): TypeIndex;
  274. BEGIN RETURN dInt END IntType;
  275. PROCEDURE RealType (): TypeIndex;
  276. BEGIN RETURN dReal END RealType;
  277. PROCEDURE CharType (): TypeIndex;
  278. BEGIN RETURN dChar END CharType;
  279. PROCEDURE BoolType (): TypeIndex;
  280. BEGIN RETURN dBool END BoolType;
  281. PROCEDURE ClassOf (t: TypeIndex): INTEGER;
  282. VAR r : TypeIndex;
  283. BEGIN
  284. r := Resolve(t);
  285. IF r = InvalidType THEN RETURN ClInvalid END;
  286. CASE tform[r] OF
  287. FInt : RETURN ClInt
  288. | FReal : RETURN ClReal
  289. | FChar : RETURN ClChar
  290. | FBool : RETURN ClBool
  291. | FEnum : RETURN ClEnum
  292. | FArray : RETURN ClArray
  293. | FRecord : RETURN ClRecord
  294. | FSet : RETURN ClSet
  295. | FPtr : RETURN ClPtr
  296. | FStr : RETURN ClStr
  297. | FSub : RETURN ClassOf(tref[r])
  298. ELSE RETURN ClInvalid
  299. END
  300. END ClassOf;
  301. PROCEDURE IsIntFamily (t: TypeIndex): BOOLEAN;
  302. BEGIN
  303. RETURN ClassOf(t) = ClInt
  304. END IsIntFamily;
  305. PROCEDURE SameType (a, b: TypeIndex): BOOLEAN;
  306. BEGIN
  307. IF (a = InvalidType) OR (b = InvalidType) THEN RETURN TRUE END;
  308. RETURN Resolve(a) = Resolve(b)
  309. END SameType;
  310. PROCEDURE FieldExists (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
  311. BEGIN
  312. RETURN FindField(Resolve(rec), name) # -1
  313. END FieldExists;
  314. PROCEDURE FieldType (rec: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
  315. VAR i : INTEGER;
  316. BEGIN
  317. i := FindField(Resolve(rec), name);
  318. IF i = -1 THEN RETURN InvalidType END;
  319. RETURN fields[i].typ
  320. END FieldType;
  321. PROCEDURE ArrayElem (t: TypeIndex): TypeIndex;
  322. VAR r : TypeIndex;
  323. BEGIN
  324. r := Resolve(t);
  325. IF (r = InvalidType) OR (tform[r] # FArray) THEN
  326. RETURN InvalidType
  327. END;
  328. RETURN tref[r]
  329. END ArrayElem;
  330. PROCEDURE PtrBase (t: TypeIndex): TypeIndex;
  331. VAR r : TypeIndex;
  332. BEGIN
  333. r := Resolve(t);
  334. IF (r = InvalidType) OR (tform[r] # FPtr) THEN
  335. RETURN InvalidType
  336. END;
  337. RETURN tref[r]
  338. END PtrBase;
  339. PROCEDURE PushRecord (t: TypeIndex): BOOLEAN;
  340. (* Pushes a scope with t's fields; caller must PopScope afterwards. *)
  341. VAR r, i : INTEGER;
  342. BEGIN
  343. r := Resolve(t);
  344. IF (r < 0) OR (tform[r] # FRecord) THEN RETURN FALSE END;
  345. PushScope;
  346. i := tref[r];
  347. WHILE i # -1 DO
  348. IF Enter(fields[i].name, KindField) THEN
  349. SetSymType(fields[i].name, fields[i].typ)
  350. END;
  351. i := fields[i].next
  352. END;
  353. RETURN TRUE
  354. END PushRecord;
  355. (* ---------------- predicates ---------------- *)
  356. PROCEDURE SetBasesOk (a, b: TypeIndex): BOOLEAN;
  357. (* base compatibility for two SET types *)
  358. BEGIN
  359. IF SameType(a, b) THEN RETURN TRUE END;
  360. IF IsIntFamily(a) & IsIntFamily(b) THEN RETURN TRUE END;
  361. IF (ClassOf(a) = ClChar) & (ClassOf(b) = ClChar) THEN
  362. RETURN TRUE
  363. END;
  364. RETURN FALSE
  365. END SetBasesOk;
  366. PROCEDURE Assignable (src, dst: TypeIndex): BOOLEAN;
  367. VAR rs, rd : TypeIndex;
  368. BEGIN
  369. IF (src = InvalidType) OR (dst = InvalidType) THEN RETURN TRUE END;
  370. rs := Resolve(src); rd := Resolve(dst);
  371. IF rs = rd THEN RETURN TRUE END;
  372. IF (rs = InvalidType) OR (rd = InvalidType) THEN RETURN TRUE END;
  373. IF (tform[rs] = FSet) & (tform[rd] = FSet) THEN
  374. RETURN SetBasesOk(tref[rs], tref[rd])
  375. END;
  376. IF (ClassOf(src) = ClInt) & (ClassOf(dst) = ClInt) THEN
  377. RETURN TRUE
  378. END;
  379. IF (ClassOf(src) = ClInt) & (ClassOf(dst) = ClReal) THEN
  380. RETURN TRUE
  381. END;
  382. IF (ClassOf(src) = ClStr) & (ClassOf(dst) = ClArray) THEN
  383. RETURN TRUE
  384. END;
  385. RETURN FALSE
  386. END Assignable;
  387. PROCEDURE ArithCheck (l, r: TypeIndex; divmod: BOOLEAN;
  388. VAR res: TypeIndex): BOOLEAN;
  389. BEGIN
  390. res := InvalidType;
  391. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  392. IF IsIntFamily(l) & IsIntFamily(r) THEN
  393. res := dInt; RETURN TRUE
  394. END;
  395. IF ~divmod & (ClassOf(l) = ClReal) & (ClassOf(r) = ClReal) THEN
  396. res := dReal; RETURN TRUE
  397. END;
  398. RETURN FALSE
  399. END ArithCheck;
  400. PROCEDURE UnaryCheck (t: TypeIndex; VAR res: TypeIndex): BOOLEAN;
  401. BEGIN
  402. res := InvalidType;
  403. IF t = InvalidType THEN RETURN TRUE END;
  404. IF IsIntFamily(t) THEN res := dInt; RETURN TRUE END;
  405. IF ClassOf(t) = ClReal THEN res := dReal; RETURN TRUE END;
  406. RETURN FALSE
  407. END UnaryCheck;
  408. PROCEDURE BoolCheck (t: TypeIndex): BOOLEAN;
  409. BEGIN
  410. IF t = InvalidType THEN RETURN TRUE END;
  411. RETURN ClassOf(t) = ClBool
  412. END BoolCheck;
  413. PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
  414. VAR rl, rr : TypeIndex;
  415. BEGIN
  416. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  417. IF SameType(l, r) THEN RETURN TRUE END;
  418. IF IsIntFamily(l) & IsIntFamily(r) THEN RETURN TRUE END;
  419. IF (ClassOf(l) = ClReal) & (ClassOf(r) = ClReal) THEN
  420. RETURN TRUE
  421. END;
  422. IF (ClassOf(l) = ClChar) & (ClassOf(r) = ClChar) THEN
  423. RETURN TRUE
  424. END;
  425. IF (ClassOf(l) = ClBool) & (ClassOf(r) = ClBool) THEN
  426. RETURN TRUE
  427. END;
  428. IF (ClassOf(l) = ClStr) & (ClassOf(r) = ClStr) THEN
  429. RETURN TRUE
  430. END;
  431. rl := Resolve(l); rr := Resolve(r);
  432. IF (rl = InvalidType) OR (rr = InvalidType) THEN RETURN TRUE END;
  433. IF (tform[rl] = FSet) & (tform[rr] = FSet) THEN
  434. RETURN SetBasesOk(tref[rl], tref[rr])
  435. END;
  436. RETURN FALSE
  437. END EqCheck;
  438. PROCEDURE OrdCheck (l, r: TypeIndex): BOOLEAN;
  439. BEGIN
  440. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  441. IF IsIntFamily(l) & IsIntFamily(r) THEN RETURN TRUE END;
  442. IF (ClassOf(l) = ClReal) & (ClassOf(r) = ClReal) THEN
  443. RETURN TRUE
  444. END;
  445. IF (ClassOf(l) = ClChar) & (ClassOf(r) = ClChar) THEN
  446. RETURN TRUE
  447. END;
  448. IF (ClassOf(l) = ClEnum) & SameType(l, r) THEN RETURN TRUE END;
  449. RETURN FALSE
  450. END OrdCheck;
  451. PROCEDURE InCheck (l, set: TypeIndex): BOOLEAN;
  452. VAR rs, b : TypeIndex;
  453. BEGIN
  454. IF (l = InvalidType) OR (set = InvalidType) THEN RETURN TRUE END;
  455. rs := Resolve(set);
  456. IF (rs = InvalidType) OR (tform[rs] # FSet) THEN RETURN FALSE END;
  457. b := tref[rs];
  458. IF SameType(l, b) THEN RETURN TRUE END;
  459. IF IsIntFamily(l) & IsIntFamily(b) THEN RETURN TRUE END;
  460. IF (ClassOf(l) = ClChar) & (ClassOf(b) = ClChar) THEN
  461. RETURN TRUE
  462. END;
  463. RETURN FALSE
  464. END InCheck;
  465. PROCEDURE RelCheck (l, r: TypeIndex; op: INTEGER): BOOLEAN;
  466. BEGIN
  467. IF (l = InvalidType) OR (r = InvalidType) THEN RETURN TRUE END;
  468. IF op = OpIn THEN RETURN InCheck(l, r) END;
  469. IF (op = OpEq) OR (op = OpNeq1) OR (op = OpNeq2) THEN
  470. RETURN EqCheck(l, r)
  471. END;
  472. RETURN OrdCheck(l, r)
  473. END RelCheck;
  474. PROCEDURE SetElemCheck (first, elem: TypeIndex): BOOLEAN;
  475. BEGIN
  476. IF (first = InvalidType) OR (elem = InvalidType) THEN
  477. RETURN TRUE
  478. END;
  479. IF SameType(first, elem) THEN RETURN TRUE END;
  480. IF IsIntFamily(first) & IsIntFamily(elem) THEN RETURN TRUE END;
  481. RETURN FALSE
  482. END SetElemCheck;
  483. PROCEDURE SetFor (elem: TypeIndex): TypeIndex;
  484. VAR e : TypeIndex;
  485. BEGIN
  486. e := Resolve(elem);
  487. IF e = InvalidType THEN e := dInt END;
  488. RETURN NewSet(e)
  489. END SetFor;
  490. (* ---------------- init ---------------- *)
  491. PROCEDURE Predef (name: ARRAY OF CHAR; kind: INTEGER; t: TypeIndex);
  492. BEGIN
  493. IF Enter(name, kind) THEN SetSymType(name, t) END
  494. END Predef;
  495. PROCEDURE Init;
  496. BEGIN
  497. nSyms := 0; curLev := 0; mtop := 0;
  498. nPend := 0; nPendF := 0;
  499. nTypes := 0; nFields := 0;
  500. dInt := NewDesc(FInt, InvalidType);
  501. dCard := NewDesc(FInt, InvalidType);
  502. dReal := NewDesc(FReal, InvalidType);
  503. dChar := NewDesc(FChar, InvalidType);
  504. dBool := NewDesc(FBool, InvalidType);
  505. Predef("INTEGER", KindPredef, dInt);
  506. Predef("CARDINAL", KindPredef, dCard);
  507. Predef("SHORTINT", KindPredef, dInt);
  508. Predef("LONGINT", KindPredef, dInt);
  509. Predef("REAL", KindPredef, dReal);
  510. Predef("LONGREAL", KindPredef, dReal);
  511. Predef("CHAR", KindPredef, dChar);
  512. Predef("BOOLEAN", KindPredef, dBool);
  513. Predef("TRUE", KindConst, dBool);
  514. Predef("FALSE", KindConst, dBool);
  515. Predef("NIL", KindConst, InvalidType)
  516. END Init;
  517. (* ---------------- listing ---------------- *)
  518. PROCEDURE WriteKind (kind: INTEGER);
  519. BEGIN
  520. CASE kind OF
  521. KindConst : FileIO.WriteString(FileIO.StdOut, "CONST")
  522. | KindType : FileIO.WriteString(FileIO.StdOut, "TYPE")
  523. | KindVar : FileIO.WriteString(FileIO.StdOut, "VAR")
  524. | KindImport : FileIO.WriteString(FileIO.StdOut, "IMPORT")
  525. | KindModule : FileIO.WriteString(FileIO.StdOut, "MODULE")
  526. | KindPredef : FileIO.WriteString(FileIO.StdOut, "PREDEF")
  527. | KindField : FileIO.WriteString(FileIO.StdOut, "FIELD")
  528. ELSE FileIO.WriteString(FileIO.StdOut, "???")
  529. END
  530. END WriteKind;
  531. PROCEDURE PrintTable;
  532. VAR i : CARDINAL;
  533. BEGIN
  534. FileIO.WriteLn(FileIO.StdOut);
  535. FileIO.WriteString(FileIO.StdOut, "--- Symbol table ---");
  536. FileIO.WriteLn(FileIO.StdOut);
  537. i := 0;
  538. WHILE i < nSyms DO
  539. FileIO.WriteString(FileIO.StdOut, " ");
  540. FileIO.WriteString(FileIO.StdOut, syms[i].name);
  541. FileIO.WriteString(FileIO.StdOut, " : ");
  542. WriteKind(syms[i].kind);
  543. FileIO.WriteString(FileIO.StdOut, " #");
  544. FileIO.WriteInt(FileIO.StdOut, syms[i].typ, 1);
  545. FileIO.WriteLn(FileIO.StdOut);
  546. INC(i)
  547. END
  548. END PrintTable;
  549. BEGIN
  550. Init
  551. END SymTab.