M2cP.mod 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  1. IMPLEMENTATION MODULE M2cP;
  2. (* Parser generated by Coco/R - assuming ISO IO library will be available. *)
  3. IMPORT M2cS, FileIO;
  4. IMPORT SymTab, MGen;
  5. CONST
  6. maxT = 66;
  7. minErrDist = 2; (* minimal distance (good tokens) between two errors *)
  8. setsize = 16; (* sets are stored in 16 bits *)
  9. TYPE
  10. SymbolSet = ARRAY [0 .. maxT DIV setsize] OF BITSET;
  11. VAR
  12. symSet: ARRAY [0 .. 4] OF SymbolSet; (*symSet[0] = allSyncSyms*)
  13. errDist: CARDINAL; (* number of symbols recognized since last error *)
  14. sym: CARDINAL; (* current input symbol *)
  15. PROCEDURE SemError (errNo: INTEGER);
  16. BEGIN
  17. IF errDist >= minErrDist THEN
  18. M2cS.Error(errNo, M2cS.line, M2cS.col, M2cS.pos);
  19. END;
  20. errDist := 0;
  21. END SemError;
  22. PROCEDURE SynError (errNo: INTEGER);
  23. BEGIN
  24. IF errDist >= minErrDist THEN
  25. M2cS.Error(errNo, M2cS.nextLine, M2cS.nextCol, M2cS.nextPos);
  26. END;
  27. errDist := 0;
  28. END SynError;
  29. PROCEDURE Get;
  30. VAR
  31. s: ARRAY [0 .. 31] OF CHAR;
  32. BEGIN
  33. REPEAT
  34. M2cS.Get(sym);
  35. IF sym <= maxT THEN
  36. INC(errDist);
  37. ELSE
  38. END;
  39. UNTIL sym <= maxT
  40. END Get;
  41. PROCEDURE In (VAR s: SymbolSet; x: CARDINAL): BOOLEAN;
  42. BEGIN
  43. RETURN x MOD setsize IN s[x DIV setsize];
  44. END In;
  45. PROCEDURE Expect (n: CARDINAL);
  46. BEGIN
  47. IF sym = n THEN Get ELSE SynError(n) END
  48. END Expect;
  49. PROCEDURE ExpectWeak (n, follow: CARDINAL);
  50. BEGIN
  51. IF sym = n
  52. THEN Get
  53. ELSE SynError(n); WHILE ~ In(symSet[follow], sym) DO Get END
  54. END
  55. END ExpectWeak;
  56. PROCEDURE WeakSeparator (n, syFol, repFol: CARDINAL): BOOLEAN;
  57. VAR
  58. s: SymbolSet;
  59. i: CARDINAL;
  60. BEGIN
  61. IF sym = n
  62. THEN Get; RETURN TRUE
  63. ELSIF In(symSet[repFol], sym) THEN RETURN FALSE
  64. ELSE
  65. i := 0;
  66. WHILE i <= maxT DIV setsize DO
  67. s[i] := symSet[0, i] + symSet[syFol, i] + symSet[repFol, i]; INC(i)
  68. END;
  69. SynError(n); WHILE ~ In(s, sym) DO Get END;
  70. RETURN In(symSet[syFol], sym)
  71. END
  72. END WeakSeparator;
  73. PROCEDURE LexName (VAR Lex: ARRAY OF CHAR);
  74. BEGIN
  75. M2cS.GetName(M2cS.pos, M2cS.len, Lex)
  76. END LexName;
  77. PROCEDURE LexString (VAR Lex: ARRAY OF CHAR);
  78. BEGIN
  79. M2cS.GetString(M2cS.pos, M2cS.len, Lex)
  80. END LexString;
  81. PROCEDURE LookAheadName (VAR Lex: ARRAY OF CHAR);
  82. BEGIN
  83. M2cS.GetName(M2cS.nextPos, M2cS.nextLen, Lex)
  84. END LookAheadName;
  85. PROCEDURE LookAheadString (VAR Lex: ARRAY OF CHAR);
  86. BEGIN
  87. M2cS.GetString(M2cS.nextPos, M2cS.nextLen, Lex)
  88. END LookAheadString;
  89. PROCEDURE Successful (): BOOLEAN;
  90. BEGIN
  91. RETURN M2cS.errors = 0
  92. END Successful;
  93. (* ----- FORWARD not needed in multipass compilers
  94. PROCEDURE Elem (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
  95. VAR lx2: MGen.LitStr; VAR hasR: BOOLEAN); FORWARD;
  96. PROCEDURE SetLit (VAR t: SymTab.TypeIndex); FORWARD;
  97. PROCEDURE MulOp (VAR op: INTEGER); FORWARD;
  98. PROCEDURE Fact (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr); FORWARD;
  99. PROCEDURE AddOp (VAR op: INTEGER); FORWARD;
  100. PROCEDURE Term (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr); FORWARD;
  101. PROCEDURE Rel (VAR op: INTEGER); FORWARD;
  102. PROCEDURE SimExpr (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr); FORWARD;
  103. PROCEDURE ByLit (VAR v: INTEGER); FORWARD;
  104. PROCEDURE Labels (sel: SymTab.TypeIndex; tmp: INTEGER; bodyL: INTEGER); FORWARD;
  105. PROCEDURE LabelList (sel: SymTab.TypeIndex; tmp: INTEGER;
  106. VAR lB: INTEGER; VAR lN: INTEGER); FORWARD;
  107. PROCEDURE Case (sel: SymTab.TypeIndex; tmp: INTEGER; endL: INTEGER); FORWARD;
  108. PROCEDURE Design (VAR t: SymTab.TypeIndex; VAR k: INTEGER;
  109. VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr); FORWARD;
  110. PROCEDURE WithStat; FORWARD;
  111. PROCEDURE ForStat; FORWARD;
  112. PROCEDURE LoopStat; FORWARD;
  113. PROCEDURE RepeatStat; FORWARD;
  114. PROCEDURE WhileStat; FORWARD;
  115. PROCEDURE CaseStat; FORWARD;
  116. PROCEDURE IfStat; FORWARD;
  117. PROCEDURE Assign; FORWARD;
  118. PROCEDURE Stat; FORWARD;
  119. PROCEDURE FieldIdents (rt: SymTab.TypeIndex); FORWARD;
  120. PROCEDURE Field (rt: SymTab.TypeIndex); FORWARD;
  121. PROCEDURE FieldSeq (rt: SymTab.TypeIndex); FORWARD;
  122. PROCEDURE Enum (VAR t: SymTab.TypeIndex); FORWARD;
  123. PROCEDURE PointerType (VAR t: SymTab.TypeIndex); FORWARD;
  124. PROCEDURE SetType (VAR t: SymTab.TypeIndex); FORWARD;
  125. PROCEDURE RecordType (VAR t: SymTab.TypeIndex); FORWARD;
  126. PROCEDURE ArrayType (VAR t: SymTab.TypeIndex); FORWARD;
  127. PROCEDURE SimpleType (VAR t: SymTab.TypeIndex); FORWARD;
  128. PROCEDURE QualIdent (VAR t: SymTab.TypeIndex); FORWARD;
  129. PROCEDURE VarIdents; FORWARD;
  130. PROCEDURE Type (VAR t: SymTab.TypeIndex); FORWARD;
  131. PROCEDURE Expr (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr); FORWARD;
  132. PROCEDURE ConstExpr (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr); FORWARD;
  133. PROCEDURE VarDecl; FORWARD;
  134. PROCEDURE TypeDecl; FORWARD;
  135. PROCEDURE ConstDecl; FORWARD;
  136. PROCEDURE StatSeq; FORWARD;
  137. PROCEDURE Declaration; FORWARD;
  138. PROCEDURE ImportList; FORWARD;
  139. PROCEDURE Block; FORWARD;
  140. PROCEDURE Import; FORWARD;
  141. PROCEDURE GetIdent (VAR n: SymTab.Name); FORWARD;
  142. PROCEDURE M2c; FORWARD;
  143. ----- *)
  144. PROCEDURE Elem (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
  145. VAR lx2: MGen.LitStr; VAR hasR: BOOLEAN);
  146. VAR t2: SymTab.TypeIndex;
  147. BEGIN
  148. Expr(t, lx);
  149. hasR := FALSE;
  150. lx2[0] := 0C;;
  151. IF (sym = 19) THEN
  152. Get;
  153. Expr(t2, lx2);
  154. IF ~SymTab.SetElemCheck(t, t2) THEN
  155. SemError(222) END;
  156. hasR := TRUE;;
  157. END;
  158. END Elem;
  159. PROCEDURE SetLit (VAR t: SymTab.TypeIndex);
  160. VAR first, et: SymTab.TypeIndex;
  161. lxE, lxE2: MGen.LitStr;
  162. hasR: BOOLEAN;
  163. BEGIN
  164. Expect(64);
  165. MGen.PushInt(0);
  166. t := SymTab.SetFor(SymTab.IntType());;
  167. IF In(symSet[1], sym) THEN
  168. Elem(et, lxE, lxE2, hasR);
  169. first := et;
  170. t := SymTab.SetFor(et);
  171. IF hasR THEN MGen.FieldMask
  172. ELSE MGen.Power2 END;
  173. MGen.Or;;
  174. WHILE (sym = 10) DO
  175. Get;
  176. Elem(et, lxE, lxE2, hasR);
  177. IF ~SymTab.SetElemCheck(first, et) THEN
  178. SemError(222) END;
  179. IF hasR THEN MGen.FieldMask
  180. ELSE MGen.Power2 END;
  181. MGen.Or;;
  182. END;
  183. END;
  184. Expect(65);
  185. END SetLit;
  186. PROCEDURE MulOp (VAR op: INTEGER);
  187. BEGIN
  188. CASE sym OF
  189. 56 :
  190. Get;
  191. op := SymTab.OpTimes;;
  192. | 57 :
  193. Get;
  194. op := SymTab.OpSlash;;
  195. | 58 :
  196. Get;
  197. op := SymTab.OpDiv;;
  198. | 59 :
  199. Get;
  200. op := SymTab.OpMod;;
  201. | 60 :
  202. Get;
  203. op := SymTab.OpAnd;;
  204. | 61 :
  205. Get;
  206. op := SymTab.OpAnd;;
  207. ELSE SynError(67);
  208. END;
  209. END MulOp;
  210. PROCEDURE Fact (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr);
  211. VAR s: ARRAY [0 .. 255] OF CHAR;
  212. t2, et, dt, st: SymTab.TypeIndex;
  213. dk: INTEGER;
  214. bnF: SymTab.Name;
  215. lxD, lx2: MGen.LitStr;
  216. v: INTEGER;
  217. c: CARDINAL;
  218. b: LONGCARD;
  219. BEGIN
  220. CASE sym OF
  221. 2 :
  222. Get;
  223. LexString(s);
  224. MGen.CopyName(s, lx);
  225. IF MGen.ParseInt(s, v) THEN
  226. MGen.PushInt(v)
  227. ELSIF MGen.ParseCard(s, c) THEN
  228. MGen.PushBits(
  229. VAL(LONGCARD, c))
  230. ELSE MGen.PushInt(0)
  231. END;
  232. t := SymTab.IntType();;
  233. | 3 :
  234. Get;
  235. LexString(s);
  236. MGen.CopyName(s, lx);
  237. IF MGen.ParseReal(s, b) THEN
  238. MGen.PushBits(b)
  239. ELSE MGen.PushBits(0H)
  240. END;
  241. t := SymTab.RealType();;
  242. | 4 :
  243. Get;
  244. LexString(s);
  245. IF SymTab.StrLen(s) <= 3 THEN
  246. t := SymTab.CharType();
  247. MGen.CopyName(s, lx);
  248. MGen.PushInt(
  249. MGen.CharOrd(s))
  250. ELSE t := SymTab.NewStr();
  251. SemError(230);
  252. lx[0] := 0C;
  253. MGen.PushInt(0)
  254. END;;
  255. | 1 :
  256. Design(dt, dk, bnF, TRUE, lxD);
  257. t := dt;
  258. MGen.CopyName(lxD, lx);;
  259. | 21 :
  260. Get;
  261. Expr(et, lx);
  262. Expect(22);
  263. t := et;;
  264. | 62, 63 :
  265. IF (sym = 62) THEN
  266. Get;
  267. ELSE
  268. Get;
  269. END;
  270. Fact(t2, lx2);
  271. lx[0] := 0C;
  272. IF SymTab.BoolCheck(t2) THEN
  273. t := SymTab.BoolType()
  274. ELSE SemError(212);
  275. t := SymTab.InvalidType END;
  276. MGen.Not;;
  277. | 64 :
  278. SetLit(st);
  279. lx[0] := 0C;
  280. t := st;;
  281. ELSE SynError(68);
  282. END;
  283. END Fact;
  284. PROCEDURE AddOp (VAR op: INTEGER);
  285. BEGIN
  286. IF (sym = 54) THEN
  287. Get;
  288. op := SymTab.OpAdd;;
  289. ELSIF (sym = 44) THEN
  290. Get;
  291. op := SymTab.OpSub;;
  292. ELSIF (sym = 55) THEN
  293. Get;
  294. op := SymTab.OpOr;;
  295. ELSE SynError(69);
  296. END;
  297. END AddOp;
  298. PROCEDURE Term (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr);
  299. VAR t2, res2: SymTab.TypeIndex;
  300. op: INTEGER;
  301. lx2: MGen.LitStr;
  302. isR: BOOLEAN;
  303. mt: INTEGER;
  304. BEGIN
  305. Fact(t, lx);
  306. WHILE In(symSet[2], sym) DO
  307. MulOp(op);
  308. Fact(t2, lx2);
  309. lx[0] := 0C;
  310. IF op = SymTab.OpAnd THEN
  311. IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
  312. t := SymTab.BoolType()
  313. ELSE SemError(212); t := SymTab.InvalidType END;
  314. MGen.And
  315. ELSE
  316. IF SymTab.ArithCheck(t, t2,
  317. (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
  318. res2) THEN t := res2
  319. ELSE SemError(211); t := SymTab.InvalidType END;
  320. isR := (t # SymTab.InvalidType)
  321. & (SymTab.ClassOf(t) = SymTab.ClReal);
  322. IF op = SymTab.OpTimes THEN
  323. IF isR THEN MGen.RealMul ELSE MGen.MulU END
  324. ELSIF op = SymTab.OpSlash THEN
  325. IF isR THEN MGen.RealDiv ELSE MGen.DivI END
  326. ELSIF op = SymTab.OpDiv THEN
  327. MGen.DivI
  328. ELSE
  329. mt := MGen.TempGlobal();
  330. MGen.ModI(mt)
  331. END
  332. END;;
  333. END;
  334. END Term;
  335. PROCEDURE Rel (VAR op: INTEGER);
  336. BEGIN
  337. CASE sym OF
  338. 16 :
  339. Get;
  340. op := SymTab.OpEq;;
  341. | 47 :
  342. Get;
  343. op := SymTab.OpNeq1;;
  344. | 48 :
  345. Get;
  346. op := SymTab.OpNeq2;;
  347. | 49 :
  348. Get;
  349. op := SymTab.OpLt;;
  350. | 50 :
  351. Get;
  352. op := SymTab.OpLe;;
  353. | 51 :
  354. Get;
  355. op := SymTab.OpGt;;
  356. | 52 :
  357. Get;
  358. op := SymTab.OpGe;;
  359. | 53 :
  360. Get;
  361. op := SymTab.OpIn;;
  362. ELSE SynError(70);
  363. END;
  364. END Rel;
  365. PROCEDURE SimExpr (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr);
  366. VAR t2, res2: SymTab.TypeIndex;
  367. op: INTEGER;
  368. lx2: MGen.LitStr;
  369. neg, isR: BOOLEAN;
  370. BEGIN
  371. neg := FALSE;;
  372. IF (sym = 44) OR (sym = 54) THEN
  373. IF (sym = 54) THEN
  374. Get;
  375. ELSE
  376. Get;
  377. neg := TRUE;;
  378. END;
  379. END;
  380. Term(t, lx);
  381. IF neg THEN
  382. IF MGen.IsLit(lx) THEN
  383. MGen.NegFold(lx, lx)
  384. ELSE lx[0] := 0C
  385. END;
  386. IF SymTab.ClassOf(t)
  387. = SymTab.ClReal THEN
  388. MGen.NegReal
  389. ELSE MGen.NegInt
  390. END
  391. END;;
  392. WHILE (sym = 44) OR (sym = 54) OR (sym = 55) DO
  393. AddOp(op);
  394. Term(t2, lx2);
  395. lx[0] := 0C;
  396. IF op = SymTab.OpOr THEN
  397. IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
  398. t := SymTab.BoolType()
  399. ELSE SemError(212); t := SymTab.InvalidType END;
  400. MGen.Or
  401. ELSE
  402. IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN t := res2
  403. ELSE SemError(211); t := SymTab.InvalidType END;
  404. isR := (t # SymTab.InvalidType)
  405. & (SymTab.ClassOf(t) = SymTab.ClReal);
  406. IF op = SymTab.OpAdd THEN
  407. IF isR THEN MGen.RealAdd ELSE MGen.Add END
  408. ELSE
  409. IF isR THEN MGen.RealSub ELSE MGen.Sub END
  410. END
  411. END;;
  412. END;
  413. END SimExpr;
  414. PROCEDURE ByLit (VAR v: INTEGER);
  415. VAR s: ARRAY [0 .. 255] OF CHAR;
  416. BEGIN
  417. IF (sym = 2) THEN
  418. Get;
  419. LexString(s);
  420. IF ~MGen.ParseInt(s, v) THEN
  421. v := 1
  422. END;;
  423. ELSIF (sym = 44) THEN
  424. Get;
  425. Expect(2);
  426. LexString(s);
  427. IF MGen.ParseInt(s, v) THEN
  428. v := -v
  429. ELSE v := -1
  430. END;;
  431. ELSE SynError(71);
  432. END;
  433. END ByLit;
  434. PROCEDURE Labels (sel: SymTab.TypeIndex; tmp: INTEGER; bodyL: INTEGER);
  435. VAR t, t2: SymTab.TypeIndex;
  436. lx1, lx2: MGen.LitStr;
  437. ta, tb, chunk: INTEGER;
  438. r, hasRange: BOOLEAN;
  439. BEGIN
  440. ConstExpr(t, lx1);
  441. IF ~SymTab.EqCheck(t, sel) THEN
  442. SemError(213) END;
  443. r := (SymTab.ClassOf(sel)
  444. = SymTab.ClReal)
  445. & (SymTab.ClassOf(t)
  446. = SymTab.ClReal);
  447. ta := MGen.TempGlobal();
  448. MGen.StoreTemp(ta);
  449. hasRange := FALSE;;
  450. IF (sym = 19) THEN
  451. Get;
  452. ConstExpr(t2, lx2);
  453. IF ~SymTab.EqCheck(t2, sel) THEN
  454. SemError(213) END;
  455. tb := MGen.TempGlobal();
  456. MGen.StoreTemp(tb);
  457. hasRange := TRUE;;
  458. END;
  459. IF hasRange THEN
  460. MGen.LoadTemp(tmp);
  461. MGen.LoadTemp(ta);
  462. IF r THEN MGen.RealGe
  463. ELSE MGen.IGe END;
  464. MGen.LoadTemp(tmp);
  465. MGen.LoadTemp(tb);
  466. IF r THEN MGen.RealLe
  467. ELSE MGen.ILe END;
  468. MGen.And
  469. ELSE
  470. MGen.LoadTemp(tmp);
  471. MGen.LoadTemp(ta);
  472. IF r THEN MGen.RealEq
  473. ELSE MGen.Eq END
  474. END;
  475. chunk := MGen.NewLabel();
  476. MGen.Jz(chunk);
  477. MGen.Jmp(bodyL);
  478. MGen.DefLabel(chunk);;
  479. END Labels;
  480. PROCEDURE LabelList (sel: SymTab.TypeIndex; tmp: INTEGER;
  481. VAR lB: INTEGER; VAR lN: INTEGER);
  482. BEGIN
  483. lB := MGen.NewLabel();
  484. lN := MGen.NewLabel();;
  485. Labels(sel, tmp, lB);
  486. WHILE (sym = 10) DO
  487. Get;
  488. Labels(sel, tmp, lB);
  489. END;
  490. MGen.Jmp(lN);;
  491. END LabelList;
  492. PROCEDURE Case (sel: SymTab.TypeIndex; tmp: INTEGER; endL: INTEGER);
  493. VAR lB, lN: INTEGER;
  494. BEGIN
  495. IF In(symSet[1], sym) THEN
  496. LabelList(sel, tmp, lB, lN);
  497. Expect(17);
  498. MGen.DefLabel(lB);;
  499. StatSeq;
  500. MGen.Jmp(endL);
  501. MGen.DefLabel(lN);;
  502. END;
  503. END Case;
  504. PROCEDURE Design (VAR t: SymTab.TypeIndex; VAR k: INTEGER;
  505. VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr);
  506. VAR n, m: SymTab.Name;
  507. it: SymTab.TypeIndex;
  508. lxI: MGen.LitStr;
  509. cls: INTEGER;
  510. BEGIN
  511. GetIdent(n);
  512. MGen.CopyName(n, bn);
  513. lx[0] := 0C;
  514. IF ~SymTab.Lookup(n) THEN
  515. SemError(201);
  516. t := SymTab.InvalidType; k := -1;
  517. IF doLoad THEN
  518. MGen.PushInt(0)
  519. END
  520. ELSE
  521. t := SymTab.SymType(n);
  522. k := SymTab.SymKind(n);
  523. IF k = SymTab.KindConst THEN
  524. IF SymTab.Equal(n, "TRUE") THEN
  525. t := SymTab.BoolType();
  526. MGen.CopyName("TRUE", lx);
  527. IF doLoad THEN
  528. MGen.PushInt(1)
  529. END
  530. ELSIF SymTab.Equal(n,
  531. "FALSE") THEN
  532. t := SymTab.BoolType();
  533. MGen.CopyName("FALSE", lx);
  534. IF doLoad THEN
  535. MGen.PushInt(0)
  536. END
  537. ELSE
  538. cls :=
  539. SymTab.ClassOf(t);
  540. IF (t #
  541. SymTab.InvalidType)
  542. & (cls # SymTab.ClStr)
  543. & ((cls = SymTab.ClInt)
  544. OR (cls = SymTab.ClReal)
  545. OR (cls = SymTab.ClBool)
  546. OR (cls = SymTab.ClChar)
  547. OR (cls
  548. = SymTab.ClEnum)) THEN
  549. IF doLoad THEN
  550. MGen.LoadVar(n)
  551. END
  552. ELSIF doLoad THEN
  553. MGen.PushInt(0)
  554. END
  555. END
  556. ELSIF k = SymTab.KindVar THEN
  557. cls := SymTab.ClassOf(t);
  558. IF (cls = SymTab.ClInt)
  559. OR (cls = SymTab.ClReal)
  560. OR (cls = SymTab.ClBool)
  561. OR (cls = SymTab.ClChar)
  562. OR (cls
  563. = SymTab.ClEnum)
  564. OR (cls
  565. = SymTab.ClSet) THEN
  566. IF doLoad THEN
  567. MGen.LoadVar(n)
  568. END
  569. ELSE SemError(230);
  570. IF doLoad THEN
  571. MGen.PushInt(0)
  572. END
  573. END
  574. ELSE
  575. IF doLoad THEN
  576. MGen.PushInt(0)
  577. END;
  578. IF k = SymTab.KindField THEN
  579. IF ~MGen.NoSup() THEN
  580. SemError(230)
  581. END
  582. ELSIF k
  583. = SymTab.KindImport THEN
  584. SemError(230)
  585. END
  586. END
  587. END;;
  588. WHILE (sym = 7) OR (sym = 18) OR (sym = 46) DO
  589. IF (sym = 7) THEN
  590. Get;
  591. lx[0] := 0C;;
  592. GetIdent(m);
  593. IF t = SymTab.InvalidType THEN
  594. ELSIF SymTab.ClassOf(t) #
  595. SymTab.ClRecord THEN
  596. SemError(215);
  597. t := SymTab.InvalidType
  598. ELSIF ~SymTab.FieldExists(t, m) THEN
  599. SemError(216);
  600. t := SymTab.InvalidType
  601. ELSE t := SymTab.FieldType(t, m);
  602. SemError(230)
  603. END;
  604. IF doLoad THEN
  605. MGen.Drop; MGen.PushInt(0)
  606. END;;
  607. ELSIF (sym = 18) THEN
  608. Get;
  609. Expr(it, lxI);
  610. MGen.Drop;
  611. IF t = SymTab.InvalidType THEN
  612. ELSIF SymTab.ClassOf(t) #
  613. SymTab.ClArray THEN
  614. SemError(217);
  615. t := SymTab.InvalidType
  616. ELSIF (it #
  617. SymTab.InvalidType)
  618. & ~SymTab.IsIntFamily(it) THEN
  619. SemError(218);
  620. t := SymTab.InvalidType
  621. ELSE t :=
  622. SymTab.ArrayElem(t);
  623. SemError(230)
  624. END;
  625. IF doLoad THEN
  626. MGen.Drop; MGen.PushInt(0)
  627. END;;
  628. WHILE (sym = 10) DO
  629. Get;
  630. Expr(it, lxI);
  631. MGen.Drop;
  632. IF (it # SymTab.InvalidType)
  633. & ~SymTab.IsIntFamily(it) THEN
  634. SemError(218) END;;
  635. END;
  636. Expect(20);
  637. ELSE
  638. Get;
  639. lx[0] := 0C;
  640. IF t = SymTab.InvalidType THEN
  641. ELSIF SymTab.ClassOf(t) #
  642. SymTab.ClPtr THEN
  643. SemError(219);
  644. t := SymTab.InvalidType
  645. ELSE t := SymTab.PtrBase(t);
  646. SemError(230)
  647. END;
  648. IF doLoad THEN
  649. MGen.Drop; MGen.PushInt(0)
  650. END;;
  651. END;
  652. END;
  653. END Design;
  654. PROCEDURE WithStat;
  655. VAR dt: SymTab.TypeIndex;
  656. dk: INTEGER;
  657. bnW: SymTab.Name;
  658. lxW: MGen.LitStr;
  659. pushed: BOOLEAN;
  660. BEGIN
  661. Expect(45);
  662. Design(dt, dk, bnW, FALSE, lxW);
  663. pushed := FALSE;
  664. IF dt # SymTab.InvalidType THEN
  665. pushed :=
  666. SymTab.PushRecord(dt);
  667. IF ~pushed THEN
  668. SemError(215)
  669. END
  670. END;
  671. IF pushed THEN
  672. MGen.NoSupEnter;
  673. SemError(230)
  674. END;;
  675. Expect(38);
  676. StatSeq;
  677. Expect(12);
  678. IF pushed THEN
  679. SymTab.PopScope;
  680. MGen.NoSupExit
  681. END;;
  682. END WithStat;
  683. PROCEDURE ForStat;
  684. VAR n, lv: SymTab.Name;
  685. lo, hi: SymTab.TypeIndex;
  686. lxLo, lxHi: MGen.LitStr;
  687. byV, ht: INTEGER;
  688. lTop, lChk, lEnd: INTEGER;
  689. neg: BOOLEAN;
  690. BEGIN
  691. Expect(42);
  692. GetIdent(n);
  693. IF ~SymTab.Lookup(n) THEN
  694. SemError(201)
  695. ELSIF (SymTab.SymKind(n) #
  696. SymTab.KindVar)
  697. & (SymTab.SymKind(n) #
  698. SymTab.KindField) THEN
  699. SemError(220)
  700. ELSIF (SymTab.SymType(n) #
  701. SymTab.InvalidType)
  702. & ~SymTab.IsIntFamily(
  703. SymTab.SymType(n)) THEN
  704. SemError(220) END;
  705. MGen.CopyName(n, lv);;
  706. Expect(30);
  707. Expr(lo, lxLo);
  708. IF (lo # SymTab.InvalidType)
  709. & ~SymTab.IsIntFamily(lo) THEN
  710. SemError(220) END;
  711. MGen.StoreVar(lv);;
  712. Expect(28);
  713. Expr(hi, lxHi);
  714. IF (hi # SymTab.InvalidType)
  715. & ~SymTab.IsIntFamily(hi) THEN
  716. SemError(220) END;
  717. ht := MGen.TempGlobal();
  718. MGen.StoreTemp(ht);
  719. byV := 1; neg := FALSE;;
  720. IF (sym = 43) THEN
  721. Get;
  722. ByLit(byV);
  723. neg := byV < 0;;
  724. END;
  725. Expect(38);
  726. lTop := MGen.NewLabel();
  727. lChk := MGen.NewLabel();
  728. lEnd := MGen.NewLabel();
  729. MGen.Jmp(lChk);
  730. MGen.DefLabel(lTop);;
  731. StatSeq;
  732. Expect(12);
  733. MGen.LoadVar(lv);
  734. MGen.PushInt(byV);
  735. MGen.Add;
  736. MGen.StoreVar(lv);
  737. MGen.DefLabel(lChk);
  738. MGen.LoadVar(lv);
  739. MGen.LoadTemp(ht);
  740. IF neg THEN MGen.IGe
  741. ELSE MGen.ILe END;
  742. MGen.Jz(lEnd);
  743. MGen.Jmp(lTop);
  744. MGen.DefLabel(lEnd);;
  745. END ForStat;
  746. PROCEDURE LoopStat;
  747. VAR topL, exitL: INTEGER;
  748. BEGIN
  749. Expect(41);
  750. topL := MGen.NewLabel();
  751. exitL := MGen.NewLabel();
  752. MGen.DefLabel(topL);
  753. MGen.PushLoop(exitL);;
  754. StatSeq;
  755. Expect(12);
  756. MGen.Jmp(topL);
  757. MGen.DefLabel(exitL);
  758. MGen.PopLoop;;
  759. END LoopStat;
  760. PROCEDURE RepeatStat;
  761. VAR t: SymTab.TypeIndex;
  762. lxC: MGen.LitStr;
  763. topL: INTEGER;
  764. BEGIN
  765. Expect(39);
  766. topL := MGen.NewLabel();
  767. MGen.DefLabel(topL);;
  768. StatSeq;
  769. Expect(40);
  770. Expr(t, lxC);
  771. IF ~SymTab.BoolCheck(t) THEN
  772. SemError(214) END;
  773. MGen.Jz(topL);;
  774. END RepeatStat;
  775. PROCEDURE WhileStat;
  776. VAR t: SymTab.TypeIndex;
  777. lxC: MGen.LitStr;
  778. topL, endL: INTEGER;
  779. BEGIN
  780. Expect(37);
  781. topL := MGen.NewLabel();
  782. endL := MGen.NewLabel();
  783. MGen.DefLabel(topL);;
  784. Expr(t, lxC);
  785. IF ~SymTab.BoolCheck(t) THEN
  786. SemError(214) END;
  787. MGen.Jz(endL);;
  788. Expect(38);
  789. StatSeq;
  790. Expect(12);
  791. MGen.Jmp(topL);
  792. MGen.DefLabel(endL);;
  793. END WhileStat;
  794. PROCEDURE CaseStat;
  795. VAR st: SymTab.TypeIndex;
  796. lxS: MGen.LitStr;
  797. tmp, endL: INTEGER;
  798. BEGIN
  799. Expect(35);
  800. Expr(st, lxS);
  801. tmp := MGen.TempGlobal();
  802. MGen.StoreTemp(tmp);
  803. endL := MGen.NewLabel();;
  804. Expect(24);
  805. Case(st, tmp, endL);
  806. WHILE (sym = 36) DO
  807. Get;
  808. Case(st, tmp, endL);
  809. END;
  810. IF (sym = 34) THEN
  811. Get;
  812. StatSeq;
  813. END;
  814. Expect(12);
  815. MGen.DefLabel(endL);;
  816. END CaseStat;
  817. PROCEDURE IfStat;
  818. VAR t: SymTab.TypeIndex;
  819. lxC: MGen.LitStr;
  820. elseL, endL: INTEGER;
  821. hasElse: BOOLEAN;
  822. BEGIN
  823. Expect(31);
  824. Expr(t, lxC);
  825. IF ~SymTab.BoolCheck(t) THEN
  826. SemError(214) END;
  827. elseL := MGen.NewLabel();
  828. endL := MGen.NewLabel();
  829. MGen.Jz(elseL);
  830. hasElse := FALSE;;
  831. Expect(32);
  832. StatSeq;
  833. WHILE (sym = 33) DO
  834. Get;
  835. MGen.Jmp(endL);
  836. MGen.DefLabel(elseL);;
  837. Expr(t, lxC);
  838. IF ~SymTab.BoolCheck(t) THEN
  839. SemError(214) END;
  840. elseL := MGen.NewLabel();
  841. MGen.Jz(elseL);;
  842. Expect(32);
  843. StatSeq;
  844. END;
  845. IF (sym = 34) THEN
  846. Get;
  847. MGen.Jmp(endL);
  848. MGen.DefLabel(elseL);
  849. hasElse := TRUE;;
  850. StatSeq;
  851. END;
  852. Expect(12);
  853. IF ~hasElse THEN
  854. MGen.DefLabel(elseL)
  855. END;
  856. MGen.DefLabel(endL);;
  857. END IfStat;
  858. PROCEDURE Assign;
  859. VAR dt, et: SymTab.TypeIndex;
  860. dk: INTEGER;
  861. bn: SymTab.Name;
  862. lxe, lxD: MGen.LitStr;
  863. isR, conv: BOOLEAN;
  864. BEGIN
  865. Design(dt, dk, bn, FALSE, lxD);
  866. Expect(30);
  867. Expr(et, lxe);
  868. IF (dt # SymTab.InvalidType)
  869. & (dk # SymTab.KindVar)
  870. & (dk # SymTab.KindField)
  871. & (dk # SymTab.KindImport) THEN
  872. SemError(210)
  873. ELSIF ~SymTab.Assignable(et, dt) THEN
  874. SemError(210) END;
  875. IF dk = SymTab.KindImport THEN
  876. SemError(230)
  877. END;
  878. isR := (dt # SymTab.InvalidType)
  879. & (SymTab.ClassOf(dt)
  880. = SymTab.ClReal);
  881. conv := isR
  882. & SymTab.IsIntFamily(et);
  883. IF dk = SymTab.KindVar THEN
  884. IF conv THEN
  885. MGen.IntToReal;
  886. END;
  887. MGen.StoreVar(bn)
  888. ELSE MGen.Drop
  889. END;;
  890. END Assign;
  891. PROCEDURE Stat;
  892. VAR lx: INTEGER;
  893. BEGIN
  894. IF In(symSet[3], sym) THEN
  895. CASE sym OF
  896. 1 :
  897. Assign;
  898. | 31 :
  899. IfStat;
  900. | 35 :
  901. CaseStat;
  902. | 37 :
  903. WhileStat;
  904. | 39 :
  905. RepeatStat;
  906. | 41 :
  907. LoopStat;
  908. | 42 :
  909. ForStat;
  910. | 45 :
  911. WithStat;
  912. | 29 :
  913. Get;
  914. IF MGen.TopLoop(lx) THEN
  915. MGen.Jmp(lx)
  916. ELSE SemError(230) END;;
  917. END;
  918. END;
  919. END Stat;
  920. PROCEDURE FieldIdents (rt: SymTab.TypeIndex);
  921. VAR n: SymTab.Name;
  922. BEGIN
  923. GetIdent(n);
  924. IF ~SymTab.FieldPending(rt, n)
  925. THEN SemError(200) END;
  926. WHILE (sym = 10) DO
  927. Get;
  928. GetIdent(n);
  929. IF ~SymTab.FieldPending(rt, n)
  930. THEN SemError(200) END;
  931. END;
  932. END FieldIdents;
  933. PROCEDURE Field (rt: SymTab.TypeIndex);
  934. VAR et: SymTab.TypeIndex;
  935. BEGIN
  936. IF (sym = 1) THEN
  937. FieldIdents(rt);
  938. Expect(17);
  939. Type(et);
  940. SymTab.FixPendingF(rt, et);;
  941. END;
  942. END Field;
  943. PROCEDURE FieldSeq (rt: SymTab.TypeIndex);
  944. BEGIN
  945. Field(rt);
  946. WHILE (sym = 6) DO
  947. Get;
  948. Field(rt);
  949. END;
  950. END FieldSeq;
  951. PROCEDURE Enum (VAR t: SymTab.TypeIndex);
  952. VAR n: SymTab.Name;
  953. ord: INTEGER;
  954. BEGIN
  955. Expect(21);
  956. t := SymTab.NewEnum();
  957. ord := 0;;
  958. GetIdent(n);
  959. IF ~SymTab.Enter(n,
  960. SymTab.KindConst)
  961. THEN SemError(200) END;
  962. SymTab.SetSymType(n, t);
  963. MGen.DeclConstInt(n, ord);
  964. INC(ord);;
  965. WHILE (sym = 10) DO
  966. Get;
  967. GetIdent(n);
  968. IF ~SymTab.Enter(n,
  969. SymTab.KindConst)
  970. THEN SemError(200) END;
  971. SymTab.SetSymType(n, t);
  972. MGen.DeclConstInt(n, ord);
  973. INC(ord);;
  974. END;
  975. Expect(22);
  976. END Enum;
  977. PROCEDURE PointerType (VAR t: SymTab.TypeIndex);
  978. VAR b: SymTab.TypeIndex;
  979. BEGIN
  980. Expect(27);
  981. Expect(28);
  982. Type(b);
  983. t := SymTab.NewPtr(b);;
  984. END PointerType;
  985. PROCEDURE SetType (VAR t: SymTab.TypeIndex);
  986. VAR s: SymTab.TypeIndex;
  987. BEGIN
  988. Expect(26);
  989. Expect(24);
  990. SimpleType(s);
  991. IF (s # SymTab.InvalidType)
  992. & (SymTab.ClassOf(s) #
  993. SymTab.ClInt)
  994. & (SymTab.ClassOf(s) #
  995. SymTab.ClChar)
  996. & (SymTab.ClassOf(s) #
  997. SymTab.ClEnum) THEN
  998. SemError(224) END;
  999. t := SymTab.NewSet(s);;
  1000. END SetType;
  1001. PROCEDURE RecordType (VAR t: SymTab.TypeIndex);
  1002. BEGIN
  1003. Expect(25);
  1004. t := SymTab.NewRecord();;
  1005. FieldSeq(t);
  1006. Expect(12);
  1007. END RecordType;
  1008. PROCEDURE ArrayType (VAR t: SymTab.TypeIndex);
  1009. VAR s, s2, e: SymTab.TypeIndex;
  1010. BEGIN
  1011. Expect(23);
  1012. SimpleType(s);
  1013. IF (s # SymTab.InvalidType)
  1014. & (SymTab.ClassOf(s) #
  1015. SymTab.ClInt)
  1016. & (SymTab.ClassOf(s) #
  1017. SymTab.ClChar)
  1018. & (SymTab.ClassOf(s) #
  1019. SymTab.ClEnum) THEN
  1020. SemError(224) END;;
  1021. WHILE (sym = 10) DO
  1022. Get;
  1023. SimpleType(s2);
  1024. IF (s2 # SymTab.InvalidType)
  1025. & (SymTab.ClassOf(s2) #
  1026. SymTab.ClInt)
  1027. & (SymTab.ClassOf(s2) #
  1028. SymTab.ClChar)
  1029. & (SymTab.ClassOf(s2) #
  1030. SymTab.ClEnum) THEN
  1031. SemError(224) END;;
  1032. END;
  1033. Expect(24);
  1034. Type(e);
  1035. t := SymTab.NewArray(e);;
  1036. END ArrayType;
  1037. PROCEDURE SimpleType (VAR t: SymTab.TypeIndex);
  1038. VAR t1, t2: SymTab.TypeIndex;
  1039. lx1, lx2: MGen.LitStr;
  1040. BEGIN
  1041. IF (sym = 1) THEN
  1042. QualIdent(t);
  1043. IF (sym = 18) THEN
  1044. Get;
  1045. MGen.NoEmitEnter;;
  1046. ConstExpr(t1, lx1);
  1047. IF (t1 # SymTab.InvalidType)
  1048. & (SymTab.ClassOf(t1) #
  1049. SymTab.ClInt)
  1050. & (SymTab.ClassOf(t1) #
  1051. SymTab.ClChar)
  1052. & (SymTab.ClassOf(t1) #
  1053. SymTab.ClEnum) THEN
  1054. SemError(224) END;;
  1055. Expect(19);
  1056. ConstExpr(t2, lx2);
  1057. IF (t2 # SymTab.InvalidType)
  1058. & (SymTab.ClassOf(t2) #
  1059. SymTab.ClInt)
  1060. & (SymTab.ClassOf(t2) #
  1061. SymTab.ClChar)
  1062. & (SymTab.ClassOf(t2) #
  1063. SymTab.ClEnum) THEN
  1064. SemError(224) END;;
  1065. Expect(20);
  1066. t := SymTab.NewSub(t1);
  1067. MGen.NoEmitExit;;
  1068. END;
  1069. ELSIF (sym = 18) THEN
  1070. Get;
  1071. MGen.NoEmitEnter;;
  1072. ConstExpr(t1, lx1);
  1073. IF (t1 # SymTab.InvalidType)
  1074. & (SymTab.ClassOf(t1) #
  1075. SymTab.ClInt)
  1076. & (SymTab.ClassOf(t1) #
  1077. SymTab.ClChar)
  1078. & (SymTab.ClassOf(t1) #
  1079. SymTab.ClEnum) THEN
  1080. SemError(224) END;;
  1081. Expect(19);
  1082. ConstExpr(t2, lx2);
  1083. IF (t2 # SymTab.InvalidType)
  1084. & (SymTab.ClassOf(t2) #
  1085. SymTab.ClInt)
  1086. & (SymTab.ClassOf(t2) #
  1087. SymTab.ClChar)
  1088. & (SymTab.ClassOf(t2) #
  1089. SymTab.ClEnum) THEN
  1090. SemError(224) END;;
  1091. Expect(20);
  1092. t := SymTab.NewSub(t1);
  1093. MGen.NoEmitExit;;
  1094. ELSIF (sym = 21) THEN
  1095. Enum(t);
  1096. ELSE SynError(72);
  1097. END;
  1098. END SimpleType;
  1099. PROCEDURE QualIdent (VAR t: SymTab.TypeIndex);
  1100. VAR n, m: SymTab.Name;
  1101. BEGIN
  1102. GetIdent(n);
  1103. IF ~SymTab.Lookup(n) THEN
  1104. SemError(201);
  1105. t := SymTab.InvalidType
  1106. ELSIF (SymTab.SymKind(n) #
  1107. SymTab.KindType)
  1108. & (SymTab.SymKind(n) #
  1109. SymTab.KindPredef)
  1110. & (SymTab.SymKind(n) #
  1111. SymTab.KindImport) THEN
  1112. SemError(221);
  1113. t := SymTab.InvalidType
  1114. ELSE t := SymTab.SymType(n) END;;
  1115. WHILE (sym = 7) DO
  1116. Get;
  1117. GetIdent(m);
  1118. t := SymTab.InvalidType;;
  1119. END;
  1120. END QualIdent;
  1121. PROCEDURE VarIdents;
  1122. VAR n: SymTab.Name;
  1123. BEGIN
  1124. GetIdent(n);
  1125. IF ~SymTab.EnterPending(n,
  1126. SymTab.KindVar)
  1127. THEN SemError(200) END;
  1128. WHILE (sym = 10) DO
  1129. Get;
  1130. GetIdent(n);
  1131. IF ~SymTab.EnterPending(n,
  1132. SymTab.KindVar)
  1133. THEN SemError(200) END;
  1134. END;
  1135. END VarIdents;
  1136. PROCEDURE Type (VAR t: SymTab.TypeIndex);
  1137. BEGIN
  1138. IF (sym = 1) OR (sym = 18) OR (sym = 21) THEN
  1139. SimpleType(t);
  1140. ELSIF (sym = 23) THEN
  1141. ArrayType(t);
  1142. ELSIF (sym = 25) THEN
  1143. RecordType(t);
  1144. ELSIF (sym = 26) THEN
  1145. SetType(t);
  1146. ELSIF (sym = 27) THEN
  1147. PointerType(t);
  1148. ELSE SynError(73);
  1149. END;
  1150. END Type;
  1151. PROCEDURE Expr (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr);
  1152. VAR t2: SymTab.TypeIndex;
  1153. tc, op: INTEGER;
  1154. lx2: MGen.LitStr;
  1155. r: BOOLEAN;
  1156. BEGIN
  1157. SimExpr(t, lx);
  1158. IF In(symSet[4], sym) THEN
  1159. Rel(op);
  1160. SimExpr(t2, lx2);
  1161. lx[0] := 0C;
  1162. IF op = SymTab.OpIn THEN
  1163. IF SymTab.InCheck(t, t2) THEN
  1164. t := SymTab.BoolType();
  1165. MGen.BitIn
  1166. ELSE SemError(222);
  1167. t := SymTab.InvalidType;
  1168. MGen.Drop; MGen.Drop; MGen.PushInt(0)
  1169. END
  1170. ELSE
  1171. tc := SymTab.ClassOf(t);
  1172. IF SymTab.RelCheck(t, t2, op) THEN
  1173. t := SymTab.BoolType()
  1174. ELSE SemError(213); t := SymTab.InvalidType END;
  1175. IF t # SymTab.InvalidType THEN
  1176. r := tc = SymTab.ClReal;
  1177. IF r THEN
  1178. IF op = SymTab.OpEq THEN MGen.RealEq
  1179. ELSIF (op = SymTab.OpNeq1)
  1180. OR (op = SymTab.OpNeq2) THEN MGen.RealNe
  1181. ELSIF op = SymTab.OpLt THEN MGen.RealLt
  1182. ELSIF op = SymTab.OpLe THEN MGen.RealLe
  1183. ELSIF op = SymTab.OpGt THEN MGen.RealGt
  1184. ELSE MGen.RealGe END
  1185. ELSE
  1186. IF op = SymTab.OpEq THEN MGen.Eq
  1187. ELSIF (op = SymTab.OpNeq1)
  1188. OR (op = SymTab.OpNeq2) THEN MGen.Neq
  1189. ELSIF op = SymTab.OpLt THEN MGen.ILt
  1190. ELSIF op = SymTab.OpLe THEN MGen.ILe
  1191. ELSIF op = SymTab.OpGt THEN MGen.IGt
  1192. ELSE MGen.IGe END
  1193. END
  1194. ELSE MGen.Drop; MGen.Drop; MGen.PushInt(0)
  1195. END
  1196. END;;
  1197. END;
  1198. END Expr;
  1199. PROCEDURE ConstExpr (VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr);
  1200. BEGIN
  1201. Expr(t, lx);
  1202. END ConstExpr;
  1203. PROCEDURE VarDecl;
  1204. VAR t: SymTab.TypeIndex;
  1205. i: CARDINAL;
  1206. nm: SymTab.Name;
  1207. cls: INTEGER;
  1208. BEGIN
  1209. VarIdents;
  1210. Expect(17);
  1211. Type(t);
  1212. cls := SymTab.ClassOf(t);
  1213. IF (cls # SymTab.ClInt)
  1214. & (cls # SymTab.ClReal)
  1215. & (cls # SymTab.ClBool)
  1216. & (cls # SymTab.ClChar)
  1217. & (cls # SymTab.ClEnum)
  1218. & (cls # SymTab.ClSet) THEN
  1219. SemError(230)
  1220. END;
  1221. i := 0;
  1222. WHILE i < SymTab.PendCount() DO
  1223. SymTab.PendName(i, nm);
  1224. MGen.DeclVar(nm);
  1225. INC(i)
  1226. END;
  1227. SymTab.FixPending(t);;
  1228. END VarDecl;
  1229. PROCEDURE TypeDecl;
  1230. VAR n: SymTab.Name;
  1231. t0, t1: SymTab.TypeIndex;
  1232. BEGIN
  1233. GetIdent(n);
  1234. IF ~SymTab.Enter(n, SymTab.KindType)
  1235. THEN SemError(200) END;
  1236. t0 := SymTab.NewAlias();
  1237. SymTab.SetSymType(n, t0);;
  1238. Expect(16);
  1239. Type(t1);
  1240. IF t1 = t0 THEN SemError(223);
  1241. SymTab.SetTarget(t0,
  1242. SymTab.InvalidType)
  1243. ELSE SymTab.SetTarget(t0, t1) END;;
  1244. END TypeDecl;
  1245. PROCEDURE ConstDecl;
  1246. VAR n: SymTab.Name;
  1247. t: SymTab.TypeIndex;
  1248. lx: MGen.LitStr;
  1249. cls: INTEGER;
  1250. BEGIN
  1251. GetIdent(n);
  1252. IF ~SymTab.Enter(n, SymTab.KindConst)
  1253. THEN SemError(200) END;
  1254. Expect(16);
  1255. MGen.NoEmitEnter;;
  1256. ConstExpr(t, lx);
  1257. SymTab.SetSymType(n, t);
  1258. cls := SymTab.ClassOf(t);
  1259. IF cls = SymTab.ClStr THEN
  1260. SemError(230)
  1261. ELSIF ~MGen.IsLit(lx) THEN
  1262. SemError(230)
  1263. END;
  1264. MGen.DeclConst(n, lx, t);
  1265. MGen.NoEmitExit;;
  1266. END ConstDecl;
  1267. PROCEDURE StatSeq;
  1268. BEGIN
  1269. Stat;
  1270. WHILE (sym = 6) DO
  1271. Get;
  1272. Stat;
  1273. END;
  1274. END StatSeq;
  1275. PROCEDURE Declaration;
  1276. BEGIN
  1277. IF (sym = 13) THEN
  1278. Get;
  1279. WHILE (sym = 1) DO
  1280. ConstDecl;
  1281. Expect(6);
  1282. END;
  1283. ELSIF (sym = 14) THEN
  1284. Get;
  1285. WHILE (sym = 1) DO
  1286. TypeDecl;
  1287. Expect(6);
  1288. END;
  1289. ELSIF (sym = 15) THEN
  1290. Get;
  1291. WHILE (sym = 1) DO
  1292. VarDecl;
  1293. Expect(6);
  1294. END;
  1295. ELSE SynError(74);
  1296. END;
  1297. END Declaration;
  1298. PROCEDURE ImportList;
  1299. VAR n: SymTab.Name;
  1300. BEGIN
  1301. GetIdent(n);
  1302. IF ~SymTab.Enter(n, SymTab.KindImport)
  1303. THEN SemError(200) END;
  1304. WHILE (sym = 10) DO
  1305. Get;
  1306. GetIdent(n);
  1307. IF ~SymTab.Enter(n, SymTab.KindImport)
  1308. THEN SemError(200) END;
  1309. END;
  1310. END ImportList;
  1311. PROCEDURE Block;
  1312. BEGIN
  1313. WHILE (sym = 13) OR (sym = 14) OR (sym = 15) DO
  1314. Declaration;
  1315. END;
  1316. IF (sym = 11) THEN
  1317. Get;
  1318. MGen.BeginBody;;
  1319. StatSeq;
  1320. END;
  1321. Expect(12);
  1322. END Block;
  1323. PROCEDURE Import;
  1324. VAR n: SymTab.Name;
  1325. BEGIN
  1326. IF (sym = 8) THEN
  1327. Get;
  1328. GetIdent(n);
  1329. IF ~SymTab.Enter(n, SymTab.KindImport)
  1330. THEN SemError(200) END;
  1331. Expect(9);
  1332. ImportList;
  1333. Expect(6);
  1334. ELSIF (sym = 9) THEN
  1335. Get;
  1336. ImportList;
  1337. Expect(6);
  1338. ELSE SynError(75);
  1339. END;
  1340. END Import;
  1341. PROCEDURE GetIdent (VAR n: SymTab.Name);
  1342. BEGIN
  1343. Expect(1);
  1344. LexName(n);;
  1345. END GetIdent;
  1346. PROCEDURE M2c;
  1347. VAR m1, m2: SymTab.Name;
  1348. BEGIN
  1349. Expect(5);
  1350. GetIdent(m1);
  1351. SymTab.Init; MGen.OpenModule(m1);
  1352. IF ~SymTab.Enter(m1, SymTab.KindModule)
  1353. THEN SemError(200) END;
  1354. Expect(6);
  1355. WHILE (sym = 8) OR (sym = 9) DO
  1356. Import;
  1357. END;
  1358. Block;
  1359. GetIdent(m2);
  1360. IF ~SymTab.Equal(m1, m2)
  1361. THEN SemError(202) END;
  1362. Expect(7);
  1363. MGen.EndModule;
  1364. SymTab.PrintTable;;
  1365. END M2c;
  1366. PROCEDURE Parse;
  1367. BEGIN
  1368. M2cS.Reset; Get;
  1369. M2c;
  1370. END Parse;
  1371. BEGIN
  1372. errDist := minErrDist;
  1373. symSet[ 0, 0] := BITSET{0};
  1374. symSet[ 0, 1] := BITSET{};
  1375. symSet[ 0, 2] := BITSET{};
  1376. symSet[ 0, 3] := BITSET{};
  1377. symSet[ 0, 4] := BITSET{};
  1378. symSet[ 1, 0] := BITSET{1, 2, 3, 4};
  1379. symSet[ 1, 1] := BITSET{5};
  1380. symSet[ 1, 2] := BITSET{12};
  1381. symSet[ 1, 3] := BITSET{6, 14, 15};
  1382. symSet[ 1, 4] := BITSET{0};
  1383. symSet[ 2, 0] := BITSET{};
  1384. symSet[ 2, 1] := BITSET{};
  1385. symSet[ 2, 2] := BITSET{};
  1386. symSet[ 2, 3] := BITSET{8, 9, 10, 11, 12, 13};
  1387. symSet[ 2, 4] := BITSET{};
  1388. symSet[ 3, 0] := BITSET{1};
  1389. symSet[ 3, 1] := BITSET{13, 15};
  1390. symSet[ 3, 2] := BITSET{3, 5, 7, 9, 10, 13};
  1391. symSet[ 3, 3] := BITSET{};
  1392. symSet[ 3, 4] := BITSET{};
  1393. symSet[ 4, 0] := BITSET{};
  1394. symSet[ 4, 1] := BITSET{0};
  1395. symSet[ 4, 2] := BITSET{15};
  1396. symSet[ 4, 3] := BITSET{0, 1, 2, 3, 4, 5};
  1397. symSet[ 4, 4] := BITSET{};
  1398. END M2cP.