SimpleQP.mod 33 KB

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