M2comp.atg 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
  1. COMPILER M2comp
  2. (* Step 2 — Coco/R lexer/parser + SymTab semantic analysis (no codegen).
  3. Lexer/scanner and parser are FULLY generated by Coco/R (CR):
  4. M2comp.atg --CR--> M2compS (scanner) + M2compP (parser)
  5. + M2comp (driver from compiler.frm)
  6. Static checks (SymTab): 200 duplicate, 201 undeclared, 202 name
  7. mismatch, 210 bad assignment, 211 arithmetic, 212 boolean operand,
  8. 213 comparison, 214 condition, 215 not a record, 216 unknown field,
  9. 217 not an array, 218 bad index, 219 not a pointer, 220 FOR misuse,
  10. 221 not a type, 222 set mismatch, 223 cyclical type, 224 ordinal
  11. required, 230 unsupported (EXIT outside LOOP, open array outside
  12. formal, FROM-lib import inside PROCEDURE, REAL/STRING CONST in
  13. a DEFINITION), 232 bad RETURN, 233 invalid call. 231 heading/
  14. body mismatch or missing body (step 5, separate compilation).
  15. Kowarsch rules kept from step 1: local MODULEs in Wirth form,
  16. unary minus takes a Factor (3.3), abbreviated arrays (3.1),
  17. no octal B/C (2.1). "~" never added (2.2); "<>" still accepted. *)
  18. IMPORT SymTab, AST;
  19. CHARACTERS
  20. eol = CHR(13) .
  21. letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
  22. digit = "0123456789" .
  23. hexDigit = digit + "ABCDEF" .
  24. noQuote1 = ANY - "'" - eol .
  25. noQuote2 = ANY - '"' - eol .
  26. IGNORE CHR(9) .. CHR(13)
  27. COMMENTS
  28. FROM "(*" TO "*)" NESTED
  29. TOKENS
  30. ident = letter { letter | digit } .
  31. integer = digit { digit }
  32. | digit { digit } CONTEXT("..")
  33. | digit { hexDigit } "H" .
  34. real = digit { digit } "." { digit }
  35. [ "E" [ "+" | "-" ] digit { digit } ] .
  36. string = "'" { noQuote1 } "'"
  37. | '"' { noQuote2 } '"' .
  38. PRODUCTIONS
  39. (* NOTE: Coco/R numbers tokens by first occurrence; M2comp.mod's Msg
  40. table is regenerated from M2comp.err on every build (via
  41. compiler.frm). After grammar edits, rebuild and check that
  42. the messages still name the right tokens. *)
  43. M2comp
  44. = Unit "." .
  45. Unit
  46. = "DEFINITION" DefUnit
  47. | "IMPLEMENTATION" ImplUnit
  48. | Module .
  49. DefUnit (. VAR m1, m2: SymTab.Name;
  50. d, rt: AST.Node;
  51. im, ax, dn: AST.Node; .)
  52. = (. SymTab.SetUnit(SymTab.UnitDef);
  53. d := NIL; .)
  54. "MODULE"
  55. GetIdent<m1> (. IF ~SymTab.BeginDef(m1) THEN
  56. SemError(200) END; .)
  57. ";"
  58. { Import<im, ax> (. d := AST.Append(d, im);
  59. d := AST.Append(d, ax); .) }
  60. { DefDecl<dn> (. d := AST.Append(d, dn); .) }
  61. "END"
  62. GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
  63. SemError(202)
  64. ELSIF ~SymTab.EndDef(m1) THEN
  65. SemError(200) END;
  66. rt := AST.MkModule(m1, d, NIL);
  67. AST.SetRoot(rt);
  68. SymTab.PrintTable;
  69. AST.DumpTree(
  70. AST.GetRoot()); .) .
  71. DefDecl<VAR n: AST.Node> (. VAR cn: AST.Node; .)
  72. = "CONST" (. n := NIL; .)
  73. { ConstDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  74. | "TYPE" (. n := NIL; .)
  75. { TypeDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  76. | "VAR" (. n := NIL; .)
  77. { VarDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  78. | ProcHeading ";" (. n := NIL; .) .
  79. ProcHeading (. VAR m1: SymTab.Name;
  80. rt: SymTab.TypeIndex;
  81. p: AST.Node; .)
  82. = (. rt := SymTab.InvalidType;
  83. p := NIL; .)
  84. "PROCEDURE"
  85. GetIdent<m1> (. IF ~SymTab.EnterHeading(m1) THEN
  86. SemError(200) END; .)
  87. [ FormalParams<p> ]
  88. [ ":"
  89. QualIdent<rt> (. SymTab.SetProcRet(rt);
  90. IF (rt #
  91. SymTab.InvalidType)
  92. & ((SymTab.ClassOf(rt) =
  93. SymTab.ClArray)
  94. OR (SymTab.ClassOf(
  95. rt) =
  96. SymTab.ClRecord)) THEN
  97. SemError(230) END; .) ] .
  98. ImplUnit (. VAR m1, m2: SymTab.Name;
  99. d, bs, rt: AST.Node;
  100. im, ax, dn: AST.Node; .)
  101. = (. SymTab.SetUnit(SymTab.UnitImpl);
  102. d := NIL; bs := NIL; .)
  103. "MODULE"
  104. GetIdent<m1> (. IF ~SymTab.DefExists(m1) THEN
  105. SemError(201)
  106. ELSIF SymTab.ImplDone(m1) THEN
  107. SemError(200)
  108. ELSIF ~SymTab.OpenImpl(m1) THEN
  109. SemError(230) END; .)
  110. ";"
  111. { Import<im, ax> (. d := AST.Append(d, im);
  112. d := AST.Append(d, ax); .) }
  113. { ImplDecl<dn> (. d := AST.Append(d, dn); .) }
  114. [ "BEGIN"
  115. StatSeq<bs> ]
  116. "END"
  117. GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
  118. SemError(202)
  119. ELSIF ~SymTab.EndImpl(m1) THEN
  120. SemError(231) END;
  121. rt := AST.MkModule(m1, d,
  122. AST.MkBlock(NIL, bs));
  123. AST.SetRoot(rt);
  124. SymTab.PrintTable;
  125. AST.DumpTree(
  126. AST.GetRoot()); .) .
  127. ImplDecl<VAR n: AST.Node> (. VAR cn: AST.Node; .)
  128. = "CONST" (. n := NIL; .)
  129. { ConstDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  130. | "TYPE" (. n := NIL; .)
  131. { TypeDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  132. | "VAR" (. n := NIL; .)
  133. { VarDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  134. | ImplProcBody<cn>
  135. ";" (. n := cn; .) .
  136. ImplProcBody<VAR n: AST.Node> (. VAR m1, m2, lib: SymTab.Name;
  137. rt: SymTab.TypeIndex;
  138. p, bd, bs: AST.Node;
  139. pn: INTEGER; .)
  140. = (. rt := SymTab.InvalidType;
  141. p := NIL; .)
  142. "PROCEDURE"
  143. GetIdent<m1> (. SymTab.CurModName(lib);
  144. IF ~SymTab.BeginBody(lib,
  145. m1) THEN
  146. SemError(231) END;
  147. SymTab.OpenProcScope; .)
  148. [ FormalParams<p> ]
  149. [ ":"
  150. QualIdent<rt> (. SymTab.SetProcRet(rt);
  151. IF (rt #
  152. SymTab.InvalidType)
  153. & ((SymTab.ClassOf(rt) =
  154. SymTab.ClArray)
  155. OR (SymTab.ClassOf(
  156. rt) =
  157. SymTab.ClRecord)) THEN
  158. SemError(230) END; .) ]
  159. ";" (. IF ~SymTab.EndBodyHeader() THEN
  160. SemError(231) END;
  161. pn := SymTab.ProcNum(m1); .)
  162. Block<bd, bs> (. n := AST.MkProc(m1, rt, p,
  163. AST.MkBlock(bd, bs));
  164. n^.num := pn; .)
  165. GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
  166. SemError(202) END;
  167. SymTab.CloseProc; .) .
  168. Module (. VAR m1, m2: SymTab.Name;
  169. d, bd, bs, rt: AST.Node;
  170. im, ax: AST.Node; .)
  171. = (. SymTab.SetUnit(SymTab.UnitProg);
  172. d := NIL; .)
  173. "MODULE"
  174. GetIdent<m1>
  175. ";"
  176. { Import<im, ax> (. d := AST.Append(d, im);
  177. d := AST.Append(d, ax); .) }
  178. Block<bd, bs> (. d := AST.Append(d, bd);
  179. rt := AST.MkModule(m1, d,
  180. AST.MkBlock(NIL, bs));
  181. AST.SetRoot(rt); .)
  182. GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
  183. SemError(202) END;
  184. SymTab.PrintTable;
  185. AST.DumpTree(
  186. AST.GetRoot()); .) .
  187. Import<VAR n: AST.Node; VAR ax: AST.Node>
  188. (. VAR mod: SymTab.Name;
  189. h, ah, t1, t2: AST.Node;
  190. m: SymTab.Name;
  191. sesh: BOOLEAN; .)
  192. = (. mod[0] := 0C;
  193. n := NIL; ax := NIL;
  194. sesh := FALSE; .)
  195. [ "FROM"
  196. GetIdent<m> (. IF SymTab.DefExists(m) THEN
  197. IF ~SymTab.ImplDone(m) THEN
  198. SemError(201) END;
  199. IF SymTab.InProc() THEN
  200. SemError(230) END;
  201. mod := m; sesh := TRUE
  202. ELSE
  203. IF ~SymTab.Enter(m,
  204. SymTab.KindImport) THEN
  205. SemError(200) END;
  206. mod := m
  207. END; .) ]
  208. "IMPORT"
  209. ImpName<mod, sesh, h, ah> (. ax := ah; .)
  210. { ","
  211. ImpName<mod, sesh, t1, t2> (. h := AST.Append(h, t1);
  212. ax := AST.Append(ax, t2); .) }
  213. ";" (. n := AST.MkImport(mod, h); .) .
  214. ImpName<mod: SymTab.Name; sesh: BOOLEAN;
  215. VAR h: AST.Node; VAR ah: AST.Node>
  216. (. VAR nm: SymTab.Name;
  217. k: INTEGER;
  218. t: SymTab.TypeIndex;
  219. v: INTEGER;
  220. nd: AST.Node; .)
  221. = GetIdent<nm> (. h := AST.MkImpName(nm);
  222. ah := NIL;
  223. IF sesh THEN
  224. IF SymTab.ExpKind(mod,
  225. nm) < 0 THEN
  226. SemError(201)
  227. ELSIF SymTab.Lookup(nm) THEN
  228. SemError(200)
  229. ELSIF ~SymTab.EnterAlias(
  230. mod, nm) THEN
  231. SemError(230)
  232. ELSE
  233. k := SymTab.SymKind(nm);
  234. IF k =
  235. SymTab.KindVar THEN
  236. t := SymTab.SymType(
  237. nm);
  238. nd := AST.MkVar(nm,
  239. t);
  240. nd^.tag := mod;
  241. ah := nd
  242. ELSIF k =
  243. SymTab.KindConst THEN
  244. t := SymTab.SymType(
  245. nm);
  246. IF SymTab.ExpConstVal(
  247. mod, nm, v) THEN
  248. ah := AST.MkConst(
  249. nm, AST.MkInt(v,
  250. t), t)
  251. ELSE SemError(230)
  252. END
  253. END
  254. END
  255. ELSE
  256. IF SymTab.DefExists(nm) THEN
  257. IF ~SymTab.ImplDone(
  258. nm) THEN
  259. SemError(201) END
  260. ELSIF ~SymTab.Enter(nm,
  261. SymTab.KindImport) THEN
  262. SemError(200) END
  263. END; .) .
  264. GetIdent<VAR n: SymTab.Name>
  265. = ident (. LexName(n); .) .
  266. Block<VAR d: AST.Node; VAR s: AST.Node>
  267. (. VAR dn: AST.Node; .)
  268. = (. d := NIL; s := NIL; .)
  269. { Declaration<dn> (. d := AST.Append(d, dn); .) }
  270. [ "BEGIN"
  271. StatSeq<s> ]
  272. "END" .
  273. Declaration<VAR n: AST.Node> (. VAR cn: AST.Node; .)
  274. = "CONST" (. n := NIL; .)
  275. { ConstDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  276. | "TYPE" (. n := NIL; .)
  277. { TypeDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  278. | "VAR" (. n := NIL; .)
  279. { VarDecl<cn> ";" (. n := AST.Append(n, cn); .) }
  280. | ProcDecl<n>
  281. ";"
  282. | ModuleDecl<n>
  283. ";" .
  284. ConstDecl<VAR n: AST.Node> (. VAR nm: SymTab.Name;
  285. t: SymTab.TypeIndex;
  286. en: AST.Node;
  287. cv: INTEGER;
  288. ok: BOOLEAN; .)
  289. = GetIdent<nm> (. IF ~SymTab.Enter(nm,
  290. SymTab.KindConst)
  291. THEN SemError(200) END; .)
  292. "="
  293. ConstExpr<t, en> (. SymTab.SetSymType(nm, t);
  294. ok := SymTab.ConstFold(en,
  295. cv);
  296. SymTab.NoteConst(nm, cv,
  297. ok);
  298. IF SymTab.InDef()
  299. & ((SymTab.ClassOf(t) =
  300. SymTab.ClReal)
  301. OR (SymTab.ClassOf(
  302. t) =
  303. SymTab.ClStr)) THEN
  304. SemError(230) END;
  305. n := AST.MkConst(nm, en,
  306. t); .) .
  307. ConstExpr<VAR t: SymTab.TypeIndex; VAR e: AST.Node>
  308. (. VAR vD: BOOLEAN; .)
  309. = Expr<t, vD, e> .
  310. TypeDecl<VAR n: AST.Node> (. VAR nm: SymTab.Name;
  311. t0, t1: SymTab.TypeIndex; .)
  312. = GetIdent<nm> (. IF ~SymTab.Enter(nm,
  313. SymTab.KindType)
  314. THEN SemError(200) END;
  315. t0 := SymTab.NewAlias();
  316. SymTab.SetSymType(nm, t0); .)
  317. "="
  318. Type<t1> (. IF t1 = t0 THEN SemError(223);
  319. SymTab.SetTarget(t0,
  320. SymTab.InvalidType)
  321. ELSE SymTab.SetTarget(t0, t1) END;
  322. n := AST.MkTypeDecl(nm,
  323. t1); .) .
  324. VarDecl<VAR n: AST.Node> (. VAR t: SymTab.TypeIndex;
  325. h: AST.Node; .)
  326. = VarIdents<h> ":"
  327. Type<t> (. IF SymTab.IsOpen(t) THEN
  328. SemError(230) END;
  329. AST.SetChainType(h, t);
  330. SymTab.FixPending(t);
  331. n := h; .) .
  332. VarIdents<VAR h: AST.Node> (. VAR nm: SymTab.Name; .)
  333. = GetIdent<nm> (. IF ~SymTab.EnterPending(nm,
  334. SymTab.KindVar)
  335. THEN SemError(200) END;
  336. h := AST.MkVar(nm,
  337. SymTab.InvalidType); .)
  338. { ","
  339. GetIdent<nm> (. IF ~SymTab.EnterPending(nm,
  340. SymTab.KindVar)
  341. THEN SemError(200) END;
  342. h := AST.Append(h,
  343. AST.MkVar(nm,
  344. SymTab.InvalidType)); .) } .
  345. ProcDecl<VAR n: AST.Node> (. VAR m1, m2: SymTab.Name;
  346. rt, ret: SymTab.TypeIndex;
  347. p, bd, bs: AST.Node;
  348. pn: INTEGER; .)
  349. = (. ret := SymTab.InvalidType;
  350. p := NIL; .)
  351. "PROCEDURE"
  352. GetIdent<m1> (. IF ~SymTab.EnterProc(m1) THEN
  353. SemError(200) END;
  354. pn := SymTab.ProcNum(m1);
  355. SymTab.OpenProcScope; .)
  356. [ FormalParams<p> ]
  357. [ ":"
  358. QualIdent<rt> (. ret := rt;
  359. SymTab.SetProcRet(rt);
  360. IF (rt #
  361. SymTab.InvalidType)
  362. & ((SymTab.ClassOf(rt) =
  363. SymTab.ClArray)
  364. OR (SymTab.ClassOf(
  365. rt) =
  366. SymTab.ClRecord)) THEN
  367. SemError(230) END; .) ]
  368. ";"
  369. Block<bd, bs> (. n := AST.MkProc(m1, ret, p,
  370. AST.MkBlock(bd, bs));
  371. n^.num := pn; .)
  372. GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
  373. SemError(202) END;
  374. SymTab.CloseProc; .) .
  375. FormalParams<VAR p: AST.Node> (. VAR ps: AST.Node; .)
  376. = "(" (. p := NIL; .)
  377. [ FPSection<ps> (. p := AST.Append(p, ps); .)
  378. { ";" FPSection<ps> (. p := AST.Append(p, ps); .) } ]
  379. ")" .
  380. FPSection<VAR p: AST.Node> (. VAR isV: BOOLEAN;
  381. t: SymTab.TypeIndex; .)
  382. = (. isV := FALSE; .)
  383. [ "VAR" (. isV := TRUE; .) ]
  384. FPIdents<isV, p> ":"
  385. Type<t> (. IF SymTab.IsOpen(t) & ~isV THEN
  386. SemError(230)
  387. ELSIF ~isV
  388. & (t #
  389. SymTab.InvalidType)
  390. & ((SymTab.ClassOf(t) =
  391. SymTab.ClArray)
  392. OR (SymTab.ClassOf(t) =
  393. SymTab.ClRecord)) THEN
  394. SemError(230) END;
  395. AST.SetChainType(p, t);
  396. IF ~SymTab.FixParamPending(t) THEN
  397. SemError(200) END; .) .
  398. FPIdents<isV: BOOLEAN; VAR p: AST.Node>
  399. (. VAR n: SymTab.Name; .)
  400. = GetIdent<n> (. IF ~SymTab.EnterParamPending(n,
  401. isV) THEN
  402. SemError(200) END;
  403. p := AST.MkParam(n,
  404. SymTab.InvalidType,
  405. isV); .)
  406. { ","
  407. GetIdent<n> (. IF ~SymTab.EnterParamPending(n,
  408. isV) THEN
  409. SemError(200) END;
  410. p := AST.Append(p,
  411. AST.MkParam(n,
  412. SymTab.InvalidType,
  413. isV)); .) } .
  414. ModuleDecl<VAR n: AST.Node> (. VAR m1, m2: SymTab.Name;
  415. d, bd, bs: AST.Node;
  416. im, ax, en: AST.Node; .)
  417. = "MODULE" (* local module, Wirth form *)
  418. (. d := NIL; .)
  419. GetIdent<m1> (. IF ~SymTab.EnterModule(m1) THEN
  420. SemError(200) END; .)
  421. [ Priority ]
  422. ";"
  423. { Import<im, ax> (. d := AST.Append(d, im);
  424. d := AST.Append(d, ax); .) }
  425. [ Export<en> (. d := AST.Append(d, en); .) ]
  426. Block<bd, bs> (. d := AST.Append(d, bd);
  427. n := AST.MkModule(m1, d,
  428. AST.MkBlock(NIL, bs)); .)
  429. GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
  430. SemError(202) END;
  431. IF ~SymTab.ExitModule() THEN
  432. SemError(201) END; .) .
  433. Priority (. VAR t: SymTab.TypeIndex;
  434. vD: BOOLEAN;
  435. en: AST.Node; .)
  436. = "["
  437. Expr<t, vD, en>
  438. "]" .
  439. Export<VAR n: AST.Node> (. VAR nm: SymTab.Name;
  440. h: AST.Node; .)
  441. = "EXPORT"
  442. [ "QUALIFIED" ]
  443. GetIdent<nm> (. IF ~SymTab.ModuleAddExp(nm) THEN
  444. SemError(200) END;
  445. h := AST.MkImpName(nm); .)
  446. { ","
  447. GetIdent<nm> (. IF ~SymTab.ModuleAddExp(nm) THEN
  448. SemError(200) END;
  449. h := AST.Append(h,
  450. AST.MkImpName(nm)); .) }
  451. ";" (. n := AST.MkExport(h); .) .
  452. Type<VAR t: SymTab.TypeIndex>
  453. (. VAR c: CARDINAL;
  454. e, s: SymTab.TypeIndex;
  455. los, his: SymTab.BoundsArr;
  456. fh: AST.Node;
  457. i: CARDINAL; .)
  458. = BoundedBase<t>
  459. | "ARRAY" (* abbreviated form only (3.1);
  460. nested ARRAY OF ARRAY long form
  461. flagged in step 4 sizing *)
  462. (. c := 0; i := 0;
  463. WHILE i <= 7 DO
  464. los[i] := 0;
  465. his[i] := -1;
  466. INC(i)
  467. END; .)
  468. [ IdxList<c, los, his> ]
  469. "OF"
  470. Type<e> (. t := SymTab.WrapArrayB(e, los,
  471. his, c); .)
  472. | "RECORD" (. t := SymTab.NewRecord(); .)
  473. FieldSeq<t, fh>
  474. "END"
  475. | "SET"
  476. "OF"
  477. QualIdent<s> (. IF (s # SymTab.InvalidType)
  478. & (SymTab.ClassOf(s) #
  479. SymTab.ClInt)
  480. & (SymTab.ClassOf(s) #
  481. SymTab.ClChar)
  482. & (SymTab.ClassOf(s) #
  483. SymTab.ClEnum) THEN
  484. SemError(224) END;
  485. t := SymTab.NewSet(s); .)
  486. | "POINTER"
  487. "TO"
  488. Type<e> (. t := SymTab.NewPtr(e); .) .
  489. BoundedBase<VAR t: SymTab.TypeIndex>
  490. (. VAR t1, t2: SymTab.TypeIndex;
  491. vD, vD2: BOOLEAN;
  492. en, en2: AST.Node;
  493. lo, hi: INTEGER; .)
  494. = QualIdent<t>
  495. [ "["
  496. Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
  497. & (SymTab.ClassOf(t1) #
  498. SymTab.ClInt)
  499. & (SymTab.ClassOf(t1) #
  500. SymTab.ClChar)
  501. & (SymTab.ClassOf(t1) #
  502. SymTab.ClEnum) THEN
  503. SemError(224) END; .)
  504. ".."
  505. Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
  506. & (SymTab.ClassOf(t2) #
  507. SymTab.ClInt)
  508. & (SymTab.ClassOf(t2) #
  509. SymTab.ClChar)
  510. & (SymTab.ClassOf(t2) #
  511. SymTab.ClEnum) THEN
  512. SemError(224) END;
  513. IF (t1 = SymTab.InvalidType)
  514. OR (t2 =
  515. SymTab.InvalidType) THEN
  516. t := SymTab.NewSub(t1)
  517. ELSIF SymTab.ConstFold(en,
  518. lo)
  519. & SymTab.ConstFold(en2,
  520. hi) THEN
  521. t := SymTab.NewSubB(t1,
  522. lo, hi)
  523. ELSE
  524. SemError(230);
  525. t := SymTab.NewSub(t1)
  526. END; .)
  527. "]" ]
  528. | "["
  529. Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
  530. & (SymTab.ClassOf(t1) #
  531. SymTab.ClInt)
  532. & (SymTab.ClassOf(t1) #
  533. SymTab.ClChar)
  534. & (SymTab.ClassOf(t1) #
  535. SymTab.ClEnum) THEN
  536. SemError(224) END; .)
  537. ".."
  538. Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
  539. & (SymTab.ClassOf(t2) #
  540. SymTab.ClInt)
  541. & (SymTab.ClassOf(t2) #
  542. SymTab.ClChar)
  543. & (SymTab.ClassOf(t2) #
  544. SymTab.ClEnum) THEN
  545. SemError(224) END;
  546. IF (t1 = SymTab.InvalidType)
  547. OR (t2 =
  548. SymTab.InvalidType) THEN
  549. t := SymTab.NewSub(t1)
  550. ELSIF SymTab.ConstFold(en,
  551. lo)
  552. & SymTab.ConstFold(en2,
  553. hi) THEN
  554. t := SymTab.NewSubB(t1,
  555. lo, hi)
  556. ELSE
  557. SemError(230);
  558. t := SymTab.NewSub(t1)
  559. END; .)
  560. "]" .
  561. IdxList<VAR c: CARDINAL; VAR los, his: SymTab.BoundsArr>
  562. (. VAR s: SymTab.TypeIndex;
  563. lo, hi: INTEGER;
  564. ok: BOOLEAN; .)
  565. = IndexType<s, lo, hi, ok> (. c := 1;
  566. los[0] := lo; his[0] := hi; .)
  567. { "," IndexType<s, lo, hi, ok> (. IF c <= 7 THEN
  568. los[c] := lo;
  569. his[c] := hi
  570. END;
  571. INC(c); .) } .
  572. IndexType<VAR t: SymTab.TypeIndex; VAR lo, hi: INTEGER;
  573. VAR ok: BOOLEAN> (. VAR t1, t2: SymTab.TypeIndex;
  574. vD, vD2: BOOLEAN;
  575. en, en2: AST.Node;
  576. l2, h2: INTEGER; .)
  577. = QualIdent<t> (. ok := SymTab.IndexBounds(t,
  578. lo, hi); .)
  579. [ "["
  580. Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
  581. & (SymTab.ClassOf(t1) #
  582. SymTab.ClInt)
  583. & (SymTab.ClassOf(t1) #
  584. SymTab.ClChar)
  585. & (SymTab.ClassOf(t1) #
  586. SymTab.ClEnum) THEN
  587. SemError(224) END; .)
  588. ".."
  589. Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
  590. & (SymTab.ClassOf(t2) #
  591. SymTab.ClInt)
  592. & (SymTab.ClassOf(t2) #
  593. SymTab.ClChar)
  594. & (SymTab.ClassOf(t2) #
  595. SymTab.ClEnum) THEN
  596. SemError(224) END;
  597. IF (t1 = SymTab.InvalidType)
  598. OR (t2 =
  599. SymTab.InvalidType) THEN
  600. t := SymTab.NewSub(t1)
  601. ELSIF SymTab.ConstFold(en,
  602. l2)
  603. & SymTab.ConstFold(en2,
  604. h2) THEN
  605. t := SymTab.NewSubB(t1,
  606. l2, h2);
  607. lo := l2; hi := h2;
  608. ok := TRUE
  609. ELSE
  610. t := SymTab.NewSub(t1);
  611. ok := FALSE
  612. END; .)
  613. "]" ]
  614. (. IF (t # SymTab.InvalidType)
  615. & ~ok THEN
  616. SemError(230) END; .)
  617. | "["
  618. Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
  619. & (SymTab.ClassOf(t1) #
  620. SymTab.ClInt)
  621. & (SymTab.ClassOf(t1) #
  622. SymTab.ClChar)
  623. & (SymTab.ClassOf(t1) #
  624. SymTab.ClEnum) THEN
  625. SemError(224) END;
  626. ok := FALSE; .)
  627. ".."
  628. Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
  629. & (SymTab.ClassOf(t2) #
  630. SymTab.ClInt)
  631. & (SymTab.ClassOf(t2) #
  632. SymTab.ClChar)
  633. & (SymTab.ClassOf(t2) #
  634. SymTab.ClEnum) THEN
  635. SemError(224) END;
  636. IF (t1 = SymTab.InvalidType)
  637. OR (t2 =
  638. SymTab.InvalidType) THEN
  639. t := SymTab.NewSub(t1)
  640. ELSIF SymTab.ConstFold(en,
  641. lo)
  642. & SymTab.ConstFold(en2,
  643. hi) THEN
  644. t := SymTab.NewSubB(t1,
  645. lo, hi);
  646. ok := TRUE
  647. ELSE
  648. SemError(230);
  649. t := SymTab.NewSub(t1)
  650. END; .)
  651. "]" .
  652. FieldSeq<rt: SymTab.TypeIndex; VAR h: AST.Node>
  653. (. VAR fn: AST.Node; .)
  654. = Field<rt, fn> (. h := fn; .)
  655. { ";"
  656. Field<rt, fn> (. h := AST.Append(h, fn); .) } .
  657. Field<rt: SymTab.TypeIndex; VAR n: AST.Node>
  658. (. VAR et: SymTab.TypeIndex;
  659. h: AST.Node; .)
  660. = (. n := NIL; .)
  661. [ FieldIdents<rt, h> ":"
  662. Type<et> (. AST.SetChainType(h, et);
  663. SymTab.FixPendingF(rt, et);
  664. n := h; .) ] .
  665. FieldIdents<rt: SymTab.TypeIndex; VAR h: AST.Node>
  666. (. VAR nm: SymTab.Name; .)
  667. = GetIdent<nm> (. IF ~SymTab.FieldPending(rt, nm)
  668. THEN SemError(200) END;
  669. h := AST.MkMember(nm,
  670. SymTab.InvalidType); .)
  671. { ","
  672. GetIdent<nm> (. IF ~SymTab.FieldPending(rt, nm)
  673. THEN SemError(200) END;
  674. h := AST.Append(h,
  675. AST.MkMember(nm,
  676. SymTab.InvalidType)); .) } .
  677. QualIdent<VAR t: SymTab.TypeIndex>
  678. (. VAR n, m: SymTab.Name;
  679. modHead: BOOLEAN; .)
  680. = (. modHead := FALSE; .)
  681. GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
  682. SemError(201);
  683. t := SymTab.InvalidType
  684. ELSIF SymTab.SymKind(n)
  685. = SymTab.KindModule THEN
  686. t := SymTab.InvalidType;
  687. modHead := TRUE
  688. ELSIF (SymTab.SymKind(n) #
  689. SymTab.KindType)
  690. & (SymTab.SymKind(n) #
  691. SymTab.KindPredef)
  692. & (SymTab.SymKind(n) #
  693. SymTab.KindImport) THEN
  694. SemError(221);
  695. t := SymTab.InvalidType
  696. ELSE t := SymTab.SymType(n) END; .)
  697. { "."
  698. GetIdent<m> (. IF modHead THEN
  699. modHead := FALSE;
  700. IF SymTab.ExpKind(n, m)
  701. = SymTab.KindType THEN
  702. t := SymTab.ExpType(n, m)
  703. ELSIF SymTab.SelfKind(n, m)
  704. = SymTab.KindType THEN
  705. t := SymTab.SelfType(n, m)
  706. ELSE
  707. IF SymTab.ExpKind(n, m) < 0 THEN
  708. IF SymTab.SelfKind(n, m)
  709. < 0 THEN
  710. SemError(201)
  711. ELSE SemError(221)
  712. END
  713. ELSE SemError(221)
  714. END;
  715. t := SymTab.InvalidType
  716. END
  717. ELSIF t #
  718. SymTab.InvalidType THEN
  719. SemError(221);
  720. t := SymTab.InvalidType
  721. END; .) } .
  722. StatSeq<VAR s: AST.Node> (. VAR st: AST.Node; .)
  723. = Stat<st> (. s := st; .)
  724. { ";"
  725. Stat<st> (. s := AST.Append(s, st); .) } .
  726. Stat<VAR s: AST.Node>
  727. = (. s := NIL; .)
  728. [ AssignOrCall<s>
  729. | IfStat<s>
  730. | WhileStat<s>
  731. | RepeatStat<s>
  732. | LoopStat<s>
  733. | ForStat<s>
  734. | WithStat<s>
  735. | CaseStat<s>
  736. | ReturnStat<s>
  737. | "EXIT" (. IF ~SymTab.InLoop() THEN
  738. SemError(230) END;
  739. s := AST.MkExit(); .) ] .
  740. AssignOrCall<VAR s: AST.Node> (. VAR dt, et: SymTab.TypeIndex;
  741. dk, pn: INTEGER;
  742. ev: BOOLEAN;
  743. nn: CARDINAL;
  744. hadP: BOOLEAN;
  745. dn, en, ah: AST.Node; .)
  746. = Designator<dt, dk, pn, dn>
  747. ( ":="
  748. Expr<et, ev, en> (. IF dt = SymTab.InvalidType THEN
  749. (* cascade *)
  750. ELSIF (dk # SymTab.KindVar)
  751. & (dk # SymTab.KindParam)
  752. & (dk # SymTab.KindVarPar)
  753. & (dk # SymTab.KindField) THEN
  754. SemError(210)
  755. ELSIF ~SymTab.Assignable(et,
  756. dt) THEN
  757. SemError(210) END;
  758. s := AST.MkAssign(dn, en); .)
  759. | (. hadP := FALSE; nn := 0;
  760. ah := NIL;
  761. IF dk = SymTab.KindProc THEN
  762. SymTab.CallBeginNum(pn)
  763. ELSE
  764. SymTab.CallBeginNum(-1)
  765. END;
  766. IF (dk # SymTab.KindProc)
  767. & (dk # -1) THEN
  768. SemError(233) END; .)
  769. [ ActParams<ah, nn> (. hadP := TRUE; .) ]
  770. (. IF ~SymTab.CallEndNum(nn) THEN
  771. SemError(233) END;
  772. s := AST.MkCall(dn, ah, pn); .) ) .
  773. Designator<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
  774. VAR pn: INTEGER; VAR dn: AST.Node>
  775. (. VAR n, m: SymTab.Name;
  776. it, it2: SymTab.TypeIndex;
  777. iv, iv2: BOOLEAN;
  778. ek, sk, p2: INTEGER;
  779. modHead, wasMod: BOOLEAN;
  780. en, en2, ih: AST.Node; .)
  781. = GetIdent<n> (. modHead := FALSE;
  782. IF ~SymTab.Lookup(n) THEN
  783. SemError(201);
  784. t := SymTab.InvalidType;
  785. k := -1; pn := -1
  786. ELSIF SymTab.SymKind(n)
  787. = SymTab.KindModule THEN
  788. t := SymTab.InvalidType;
  789. k := SymTab.KindModule;
  790. pn := -1; modHead := TRUE
  791. ELSE
  792. t := SymTab.SymType(n);
  793. k := SymTab.SymKind(n);
  794. IF k = SymTab.KindProc THEN
  795. pn := SymTab.ProcNum(n)
  796. ELSE pn := -1
  797. END
  798. END;
  799. dn := AST.MkName(n, t);
  800. dn^.aux := k; .)
  801. { "." GetIdent<m> (. wasMod := modHead;
  802. IF modHead THEN
  803. modHead := FALSE;
  804. ek := SymTab.ExpKind(n, m);
  805. sk := SymTab.SelfKind(n, m);
  806. IF ek = SymTab.KindType THEN
  807. t := SymTab.ExpType(n,
  808. m);
  809. k := SymTab.KindType
  810. ELSIF sk =
  811. SymTab.KindType THEN
  812. t := SymTab.SelfType(n,
  813. m);
  814. k := SymTab.KindType
  815. ELSIF ek =
  816. SymTab.KindProc THEN
  817. t := SymTab.ProcRetByNum(
  818. SymTab.ExpProc(
  819. n, m));
  820. k := SymTab.KindProc;
  821. pn := SymTab.ExpProc(
  822. n, m)
  823. ELSIF sk =
  824. SymTab.KindProc THEN
  825. p2 := SymTab.SelfProc(
  826. n, m);
  827. t := SymTab.ProcRetByNum(
  828. p2);
  829. k := SymTab.KindProc;
  830. pn := p2
  831. ELSIF ek >= 0 THEN
  832. t := SymTab.ExpType(n,
  833. m);
  834. k := ek; pn := -1
  835. ELSIF sk >= 0 THEN
  836. t := SymTab.SelfType(n,
  837. m);
  838. k := sk; pn := -1
  839. ELSE
  840. SemError(201);
  841. t := SymTab.InvalidType;
  842. k := -1; pn := -1
  843. END
  844. ELSIF t =
  845. SymTab.InvalidType THEN
  846. (* cascade *)
  847. ELSIF SymTab.ClassOf(t) #
  848. SymTab.ClRecord THEN
  849. SemError(215);
  850. t := SymTab.InvalidType;
  851. k := -1; pn := -1
  852. ELSIF ~SymTab.FieldExists(t,
  853. m) THEN
  854. SemError(216);
  855. t := SymTab.InvalidType;
  856. k := -1; pn := -1
  857. ELSE
  858. t := SymTab.FieldType(t,
  859. m);
  860. k := SymTab.KindField;
  861. pn := -1
  862. END;
  863. dn := AST.MkField(dn, m, t);
  864. dn^.aux := k;
  865. IF wasMod THEN
  866. dn^.tag := n
  867. END; .)
  868. | "[" Expr<it, iv, en> (. IF t = SymTab.InvalidType THEN
  869. (* cascade *)
  870. ELSIF SymTab.ClassOf(t) #
  871. SymTab.ClArray THEN
  872. SemError(217);
  873. t := SymTab.InvalidType;
  874. k := -1; pn := -1
  875. ELSIF (it #
  876. SymTab.InvalidType)
  877. & ~SymTab.IsIntFamily(
  878. it) THEN
  879. SemError(218);
  880. t := SymTab.InvalidType;
  881. k := -1; pn := -1
  882. ELSE t := SymTab.ArrayElem(
  883. t);
  884. pn := -1
  885. END;
  886. ih := en; .)
  887. { "," Expr<it2, iv2, en2> (. IF t = SymTab.InvalidType THEN
  888. (* cascade *)
  889. ELSIF SymTab.ClassOf(t) #
  890. SymTab.ClArray THEN
  891. SemError(217);
  892. t := SymTab.InvalidType;
  893. k := -1; pn := -1
  894. ELSIF (it2 #
  895. SymTab.InvalidType)
  896. & ~SymTab.IsIntFamily(
  897. it2) THEN
  898. SemError(218)
  899. ELSE t := SymTab.ArrayElem(
  900. t) END;
  901. ih := AST.Append(ih, en2); .) }
  902. "]" (. dn := AST.MkIndex(dn, ih,
  903. t);
  904. dn^.aux := k; .)
  905. | "^" (. IF t = SymTab.InvalidType THEN
  906. (* cascade *)
  907. ELSIF SymTab.ClassOf(t) #
  908. SymTab.ClPtr THEN
  909. SemError(219);
  910. t := SymTab.InvalidType;
  911. k := -1; pn := -1
  912. ELSE t := SymTab.PtrBase(t);
  913. pn := -1
  914. END;
  915. dn := AST.MkDeref(dn, t);
  916. dn^.aux := k; .) } .
  917. ActParams<VAR h: AST.Node; VAR n: CARDINAL>
  918. (. VAR at: SymTab.TypeIndex;
  919. av: BOOLEAN;
  920. ae: AST.Node; .)
  921. = "(" (. h := NIL; n := 0; .)
  922. [ Expr<at, av, ae> (. IF ~SymTab.CallActual(at,
  923. av) THEN
  924. SemError(233) END;
  925. h := AST.Append(h, ae);
  926. n := 1; .)
  927. { "," Expr<at, av, ae> (. IF ~SymTab.CallActual(at,
  928. av) THEN
  929. SemError(233) END;
  930. h := AST.Append(h, ae);
  931. INC(n); .) } ]
  932. ")" .
  933. IfStat<VAR s: AST.Node> (. VAR t: SymTab.TypeIndex;
  934. vD: BOOLEAN;
  935. cn, th, el, p: AST.Node; .)
  936. = "IF"
  937. Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
  938. SemError(214) END; .)
  939. "THEN"
  940. StatSeq<th> (. s := AST.MkIf(cn, th, NIL); .)
  941. { "ELSIF"
  942. Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
  943. SemError(214) END; .)
  944. "THEN"
  945. StatSeq<th> (. th := AST.MkIf(cn, th, NIL);
  946. p := s;
  947. WHILE p^.extra # NIL DO
  948. p := p^.extra
  949. END;
  950. p^.extra := th; .) }
  951. [ "ELSE"
  952. StatSeq<el> (. p := s;
  953. WHILE p^.extra # NIL DO
  954. p := p^.extra
  955. END;
  956. p^.extra := el; .) ]
  957. "END" .
  958. WhileStat<VAR s: AST.Node> (. VAR t: SymTab.TypeIndex;
  959. vD: BOOLEAN;
  960. cn, bd: AST.Node; .)
  961. = "WHILE"
  962. Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
  963. SemError(214) END; .)
  964. "DO"
  965. StatSeq<bd> (. s := AST.MkWhile(cn, bd); .)
  966. "END" .
  967. RepeatStat<VAR s: AST.Node> (. VAR t: SymTab.TypeIndex;
  968. vD: BOOLEAN;
  969. cn, bd: AST.Node; .)
  970. = "REPEAT"
  971. StatSeq<bd>
  972. "UNTIL"
  973. Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
  974. SemError(214) END;
  975. s := AST.MkRepeat(bd, cn); .) .
  976. LoopStat<VAR s: AST.Node> (. VAR bd: AST.Node; .)
  977. = "LOOP" (. SymTab.LoopEnter; .)
  978. StatSeq<bd>
  979. "END" (. SymTab.LoopExit;
  980. s := AST.MkLoop(bd); .) .
  981. ForStat<VAR s: AST.Node> (. VAR n: SymTab.Name;
  982. lo, hi, by: SymTab.TypeIndex;
  983. lv, lv2, lv3: BOOLEAN;
  984. ln, hn, bn, bd: AST.Node; .)
  985. = "FOR"
  986. GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
  987. SemError(201)
  988. ELSIF (SymTab.SymKind(n) #
  989. SymTab.KindVar)
  990. & (SymTab.SymKind(n) #
  991. SymTab.KindParam)
  992. & (SymTab.SymKind(n) #
  993. SymTab.KindVarPar)
  994. & (SymTab.SymKind(n) #
  995. SymTab.KindField) THEN
  996. SemError(220)
  997. ELSIF (SymTab.SymType(n) #
  998. SymTab.InvalidType)
  999. & ~SymTab.IsIntFamily(
  1000. SymTab.SymType(n)) THEN
  1001. SemError(220) END; .)
  1002. ":="
  1003. Expr<lo, lv, ln> (. IF (lo # SymTab.InvalidType)
  1004. & ~SymTab.IsIntFamily(lo) THEN
  1005. SemError(220) END; .)
  1006. "TO"
  1007. Expr<hi, lv2, hn> (. IF (hi # SymTab.InvalidType)
  1008. & ~SymTab.IsIntFamily(hi) THEN
  1009. SemError(220) END;
  1010. bn := NIL; .)
  1011. [ "BY"
  1012. Expr<by, lv3, bn> (. IF (by # SymTab.InvalidType)
  1013. & ~SymTab.IsIntFamily(by) THEN
  1014. SemError(220) END; .) ]
  1015. "DO"
  1016. StatSeq<bd> (. s := AST.MkFor(n, ln, hn, bn,
  1017. bd); .)
  1018. "END" .
  1019. WithStat<VAR s: AST.Node> (. VAR dt: SymTab.TypeIndex;
  1020. dk, pn: INTEGER;
  1021. dn, bs: AST.Node;
  1022. pushed: BOOLEAN; .)
  1023. = "WITH"
  1024. Designator<dt, dk, pn, dn> (. pushed := FALSE;
  1025. IF dt = SymTab.InvalidType THEN
  1026. (* cascade *)
  1027. ELSIF SymTab.ClassOf(dt) #
  1028. SymTab.ClRecord THEN
  1029. SemError(215)
  1030. ELSE
  1031. pushed :=
  1032. SymTab.PushRecord(dt);
  1033. IF ~pushed THEN
  1034. SemError(215) END
  1035. END; .)
  1036. "DO"
  1037. StatSeq<bs>
  1038. "END" (. IF pushed THEN
  1039. SymTab.PopScope END;
  1040. s := AST.MkWith(dn, bs); .) .
  1041. CaseStat<VAR s: AST.Node> (. VAR st: SymTab.TypeIndex;
  1042. vD: BOOLEAN;
  1043. se, arms, arm, el: AST.Node; .)
  1044. = (. arms := NIL; el := NIL; .)
  1045. "CASE"
  1046. Expr<st, vD, se> (. IF (st # SymTab.InvalidType)
  1047. & ~SymTab.IsIntFamily(st)
  1048. & (SymTab.ClassOf(st) #
  1049. SymTab.ClChar) THEN
  1050. SemError(213) END; .)
  1051. "OF"
  1052. [ CaseArm<st, arm> (. arms := arm; .)
  1053. { "|" CaseArm<st, arm> (. arms := AST.Append(arms,
  1054. arm); .) } ]
  1055. [ "ELSE"
  1056. StatSeq<el> ]
  1057. "END" (. s := AST.MkCase(se, arms,
  1058. el); .) .
  1059. CaseArm<st: SymTab.TypeIndex; VAR n: AST.Node>
  1060. (. VAR lh, lab, bs: AST.Node; .)
  1061. = CaseLabel<st, lab> (. lh := lab; .)
  1062. { "," CaseLabel<st, lab> (. lh := AST.Append(lh, lab); .) }
  1063. ":" StatSeq<bs> (. n := AST.MkCaseArm(lh, bs); .) .
  1064. CaseLabel<st: SymTab.TypeIndex; VAR n: AST.Node>
  1065. (. VAR t, t2: SymTab.TypeIndex;
  1066. vD, vD2: BOOLEAN;
  1067. en, en2: AST.Node;
  1068. lo, hi: INTEGER; .)
  1069. = ConstExpr<t, en> (. n := NIL;
  1070. IF t = SymTab.InvalidType THEN
  1071. (* cascade *)
  1072. ELSIF ~SymTab.EqCheck(t,
  1073. st) THEN SemError(213)
  1074. ELSIF ~SymTab.ConstFold(en,
  1075. lo) THEN SemError(230)
  1076. ELSE n := AST.MkInt(lo, t)
  1077. END; .)
  1078. [ ".."
  1079. ConstExpr<t2, en2> (. IF (t2 #
  1080. SymTab.InvalidType)
  1081. & ~SymTab.EqCheck(t2,
  1082. st) THEN SemError(213)
  1083. ELSIF ~SymTab.ConstFold(en2,
  1084. hi) THEN SemError(230)
  1085. ELSE n := AST.MkRange(lo,
  1086. hi)
  1087. END; .) ] .
  1088. ReturnStat<VAR s: AST.Node> (. VAR et: SymTab.TypeIndex;
  1089. ev, hasE: BOOLEAN;
  1090. en, e0: AST.Node; .)
  1091. = (. hasE := FALSE; e0 := NIL; .)
  1092. "RETURN"
  1093. [ Expr<et, ev, en> (. hasE := TRUE; e0 := en; .) ]
  1094. (. IF ~SymTab.InProc() THEN SemError(232)
  1095. ELSIF SymTab.InFunction() & ~hasE THEN SemError(232)
  1096. ELSIF ~SymTab.InFunction() & hasE THEN
  1097. SemError(232) END;
  1098. s := AST.MkReturn(e0); .) .
  1099. Expr<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
  1100. VAR e: AST.Node>
  1101. (. VAR t2: SymTab.TypeIndex;
  1102. v2: BOOLEAN;
  1103. op: INTEGER;
  1104. e2: AST.Node; .)
  1105. = SimExpr<t, v, e>
  1106. [ Relation<op> SimExpr<t2, v2, e2>
  1107. (. v := FALSE;
  1108. IF op = SymTab.OpIn THEN
  1109. IF SymTab.InCheck(t, t2) THEN
  1110. t := SymTab.BoolType()
  1111. ELSE SemError(222); t := SymTab.InvalidType END
  1112. ELSE
  1113. IF SymTab.RelCheck(t, t2, op) THEN
  1114. t := SymTab.BoolType()
  1115. ELSE SemError(213); t := SymTab.InvalidType END
  1116. END;
  1117. e := AST.MkBin(op, e, e2, t); .) ] .
  1118. Relation<VAR op: INTEGER>
  1119. = "=" (. op := SymTab.OpEq; .)
  1120. | "#" (. op := SymTab.OpNeq1; .)
  1121. | "<>" (. op := SymTab.OpNeq2; .)
  1122. | "<" (. op := SymTab.OpLt; .)
  1123. | "<=" (. op := SymTab.OpLe; .)
  1124. | ">" (. op := SymTab.OpGt; .)
  1125. | ">=" (. op := SymTab.OpGe; .)
  1126. | "IN" (. op := SymTab.OpIn; .) .
  1127. SimExpr<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
  1128. VAR e: AST.Node>
  1129. (. VAR t2, res2: SymTab.TypeIndex;
  1130. v2: BOOLEAN;
  1131. op: INTEGER;
  1132. e2: AST.Node; .)
  1133. = ( "+" Term<t, v, e> (. IF ~SymTab.UnaryCheck(t,
  1134. res2) THEN
  1135. SemError(211);
  1136. t := SymTab.InvalidType
  1137. ELSE t := res2 END;
  1138. v := FALSE;
  1139. e := AST.MkUn(AST.opPos,
  1140. e, t); .)
  1141. | "-" Fact<t, v, e> (. IF ~SymTab.UnaryCheck(t,
  1142. res2) THEN
  1143. SemError(211);
  1144. t := SymTab.InvalidType
  1145. ELSE t := res2 END;
  1146. v := FALSE;
  1147. e := AST.MkUn(AST.opNeg,
  1148. e, t); .)
  1149. | Term<t, v, e> )
  1150. { AddOp<op> Term<t2, v2, e2>
  1151. (. v := FALSE;
  1152. IF op = SymTab.OpOr THEN
  1153. IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
  1154. t := SymTab.BoolType()
  1155. ELSE SemError(212); t := SymTab.InvalidType END
  1156. ELSE
  1157. IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
  1158. t := res2
  1159. ELSE SemError(211); t := SymTab.InvalidType END
  1160. END;
  1161. e := AST.MkBin(op, e, e2, t); .) } .
  1162. AddOp<VAR op: INTEGER>
  1163. = "+" (. op := SymTab.OpAdd; .)
  1164. | "-" (. op := SymTab.OpSub; .)
  1165. | "OR" (. op := SymTab.OpOr; .) .
  1166. Term<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
  1167. VAR e: AST.Node>
  1168. (. VAR t2, res2: SymTab.TypeIndex;
  1169. v2: BOOLEAN;
  1170. op: INTEGER;
  1171. e2: AST.Node; .)
  1172. = Fact<t, v, e>
  1173. { MulOp<op> Fact<t2, v2, e2>
  1174. (. v := FALSE;
  1175. IF op = SymTab.OpAnd THEN
  1176. IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
  1177. t := SymTab.BoolType()
  1178. ELSE SemError(212); t := SymTab.InvalidType END
  1179. ELSE
  1180. IF SymTab.ArithCheck(t, t2,
  1181. (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
  1182. res2) THEN t := res2
  1183. ELSE SemError(211); t := SymTab.InvalidType END
  1184. END;
  1185. e := AST.MkBin(op, e, e2, t); .) } .
  1186. MulOp<VAR op: INTEGER>
  1187. = "*" (. op := SymTab.OpTimes; .)
  1188. | "/" (. op := SymTab.OpSlash; .)
  1189. | "DIV" (. op := SymTab.OpDiv; .)
  1190. | "MOD" (. op := SymTab.OpMod; .)
  1191. | "AND" (. op := SymTab.OpAnd; .) .
  1192. Fact<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
  1193. VAR e: AST.Node>
  1194. (. VAR s: ARRAY [0 .. 255] OF CHAR;
  1195. t2, et, dt: SymTab.TypeIndex;
  1196. dk, pn: INTEGER;
  1197. nn: CARDINAL;
  1198. hadP, ce, pushed: BOOLEAN;
  1199. ev, v2: BOOLEAN;
  1200. dn, ah, en: AST.Node;
  1201. iv: INTEGER;
  1202. ok: BOOLEAN; .)
  1203. = integer (. LexString(s);
  1204. t := SymTab.IntType();
  1205. v := FALSE;
  1206. ok := AST.ParseInt(s, iv);
  1207. IF ~ok THEN iv := 0 END;
  1208. e := AST.MkInt(iv, t); .)
  1209. | real (. LexString(s);
  1210. t := SymTab.RealType();
  1211. v := FALSE;
  1212. e := AST.MkReal(s, t); .)
  1213. | string (. LexString(s);
  1214. IF SymTab.StrLen(s) <= 3 THEN
  1215. t := SymTab.CharType();
  1216. e := AST.MkChar(
  1217. ORD(s[1]), t)
  1218. ELSE t := SymTab.NewStr();
  1219. e := AST.MkStr(s, t)
  1220. END;
  1221. v := FALSE; .)
  1222. | Designator<dt, dk, pn, dn> (. hadP := FALSE; nn := 0;
  1223. IF dk = SymTab.KindProc THEN
  1224. SymTab.CallBeginNum(pn);
  1225. pushed := TRUE
  1226. ELSE pushed := FALSE
  1227. END; .)
  1228. [ (. IF ~pushed THEN
  1229. SymTab.CallBeginNum(-1);
  1230. pushed := TRUE
  1231. END; .)
  1232. ActParams<ah, nn> (. hadP := TRUE; .) ]
  1233. (. IF pushed THEN
  1234. ce := SymTab.CallEndNum(nn)
  1235. END;
  1236. IF hadP THEN
  1237. v := FALSE;
  1238. IF dk # SymTab.KindProc THEN
  1239. SemError(233);
  1240. t := SymTab.InvalidType
  1241. ELSIF SymTab.ProcRetByNum(
  1242. pn) =
  1243. SymTab.InvalidType THEN
  1244. SemError(233);
  1245. t := SymTab.InvalidType
  1246. ELSIF ~ce THEN
  1247. SemError(233);
  1248. t := SymTab.InvalidType
  1249. ELSE t :=
  1250. SymTab.ProcRetByNum(pn)
  1251. END;
  1252. e := AST.MkCallExpr(dn, ah,
  1253. pn, t)
  1254. ELSE
  1255. IF dk = SymTab.KindProc THEN
  1256. SemError(233);
  1257. t := SymTab.InvalidType;
  1258. v := FALSE;
  1259. e := AST.MkName("?", t)
  1260. ELSE
  1261. t := dt;
  1262. v := (dt #
  1263. SymTab.InvalidType)
  1264. & ((dk =
  1265. SymTab.KindVar)
  1266. OR (dk =
  1267. SymTab.KindParam)
  1268. OR (dk =
  1269. SymTab.KindVarPar)
  1270. OR (dk =
  1271. SymTab.KindField));
  1272. e := dn
  1273. END
  1274. END; .)
  1275. | "(" Expr<et, ev, en> ")" (. t := et; v := FALSE;
  1276. e := en; .)
  1277. | "NOT" Fact<t2, v2, en> (. IF SymTab.BoolCheck(t2) THEN
  1278. t := SymTab.BoolType()
  1279. ELSE SemError(212);
  1280. t := SymTab.InvalidType END;
  1281. v := FALSE;
  1282. e := AST.MkUn(AST.opNot, en,
  1283. t); .) .
  1284. END M2comp.