M2c.atg 124 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162
  1. COMPILER M2c
  2. (* Modula-2 program modules with procedures and composites, MC64 backend
  3. (see MGen for details).
  4. - program module only, no DEFINITION / IMPLEMENTATION split
  5. - local MODULEs (single-file, no nesting): EXPORT of VARs, CONSTs,
  6. TYPEs and procedures (value/VAR params, functions, open array
  7. formals with fixed actuals); use as M.x / M.P(args); optional
  8. BEGIN..END init bodies run at startup in declaration order;
  9. no PRIORITY
  10. - procedures: declarations (nested), value and VAR parameters,
  11. functions with RETURN, recursion, FORWARD headings;
  12. no procedure types/variables, no cones
  13. - composites (Phase 3): fixed ARRAYs (bounds, 1D/multi-D indexing,
  14. unchecked, byte-packed CHAR/BOOLEAN), RECORDs (field offsets,
  15. .field, WITH incl. nested), SETs (+ union, - difference,
  16. * intersection, inclusive .. ranges), POINTERs (NEW/DISPOSE via
  17. VM ALLOCATE, ^, NIL), strings (ARRAY OF CHAR literal assign).
  18. Open arrays deferred; whole array/record copy deferred except
  19. string literals; VAR actuals must be simple (no a[i]/p^/fields
  20. as VAR actuals, 233); value composite params rejected (230);
  21. composite function returns rejected (unchecked, avoid wrong LEAVE).
  22. - statements: assignment, procedure call, IF, CASE, WHILE,
  23. REPEAT, LOOP/EXIT, FOR, WITH, RETURN, NEW, DISPOSE
  24. - symbol table (SymTab) with static type checking: error codes
  25. 200/201/202 and 210-224 (as before), plus 231 (procedure
  26. forward mismatch or missing body), 232 (bad RETURN), 233
  27. (invalid procedure call); same lenient rules (single pass,
  28. declare-before-use, except POINTER bases may be same-scope
  29. aliases with structural pointer compatibility in Assignable;
  30. INTEGER, CARDINAL and subranges form one
  31. integer family; no mixed INTEGER/REAL arithmetic; INTEGER
  32. assigns to REAL; 1-character literal is CHAR; InvalidType
  33. suppresses follow-on errors)
  34. - backend (MGen): single-module MC64 image <ModName>.MC4,
  35. runnable with mcint. Procedures take table entries 1..N
  36. (0 = module body), run with ENTER frames, called via ED
  37. (global), EC (directly nested) or EE (display walk); actuals
  38. evaluate left-to-right into temps, then push reversed.
  39. Lowered: scalar + composite globals/frame vars (multi-slot,
  40. byte sizes, field/element offsets), CONST literals,
  41. SET masks with literals/ranges/IN/=/#/+-/*; full scalar +
  42. composite expressions (scaled indexing via IdxScale, field
  43. via FieldAdd, deref via 41H/60H, byte ops 0DH/1DH for CHAR);
  44. control flow via E0/E1 jumps; composite assign via
  45. StoreIndir0/StoreByte (scalar elems) and copy_block (strings).
  46. The rest parses and type-checks
  47. but gets error 230: open arrays, whole array/record copy
  48. (except string literals), value composite params/returns,
  49. non-literal CONST expressions and BY steps,
  50. EXIT outside LOOP, imported names used as values.
  51. - test convention (the language has no I/O): a global
  52. VAR ExitCode : INTEGER;
  53. is printed as decimal + CRLF through an embedded helper;
  54. without it the program just ends.
  55. - known semantic edges: INTEGER DIV/MOD truncate toward zero;
  56. CARDINAL past MAXINT compares as signed; AND/OR are eager;
  57. REAL widens to binary64; unchecked ARRAY indexing (no DA/DB);
  58. NIL dereference reads 0 (no static check, no VM trap yet);
  59. CHAR/BOOLEAN arrays byte-packed (1 byte/elem, slots over-
  60. allocated 8x); at most 64 procedures, 64 actuals
  61. per call, 16 names per FP-section, 8-deep nested calls,
  62. 8-deep WITH, 1024 slots max per type. *)
  63. IMPORT SymTab, MGen;
  64. CHARACTERS
  65. eol = CHR(13) .
  66. letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
  67. digit = "0123456789" .
  68. hexDigit = digit + "ABCDEF" .
  69. noQuote1 = ANY - "'" - eol .
  70. noQuote2 = ANY - '"' - eol .
  71. IGNORE CHR(9) .. CHR(13)
  72. COMMENTS
  73. FROM "(*" TO "*)" NESTED
  74. TOKENS
  75. ident = letter { letter | digit } .
  76. integer = digit { digit }
  77. | digit { digit } CONTEXT("..")
  78. | digit { hexDigit } "H" .
  79. real = digit { digit } "." { digit }
  80. [ "E" [ "+" | "-" ] digit { digit } ] .
  81. string = "'" { noQuote1 } "'"
  82. | '"' { noQuote2 } '"' .
  83. PRODUCTIONS
  84. M2c (. VAR m1, m2: SymTab.Name; .)
  85. = "MODULE"
  86. GetIdent<m1> (. SymTab.Init; MGen.OpenModule(m1);
  87. IF ~SymTab.Enter(m1, SymTab.KindModule)
  88. THEN SemError(200) END .)
  89. ";"
  90. { Import } Block<FALSE> GetIdent<m2>
  91. (. IF ~SymTab.Equal(m1, m2)
  92. THEN SemError(202) END .)
  93. "." (. IF SymTab.AnyForward() THEN
  94. SemError(231)
  95. END;
  96. MGen.EndModule;
  97. SymTab.PrintTable; .) .
  98. Import (. VAR n: SymTab.Name; .)
  99. = "FROM"
  100. GetIdent<n> (. IF ~SymTab.Enter(n, SymTab.KindImport)
  101. THEN SemError(200) END .)
  102. "IMPORT"
  103. ImportList ";"
  104. | "IMPORT"
  105. ImportList ";" .
  106. ImportList (. VAR n: SymTab.Name; .)
  107. = GetIdent<n> (. IF ~SymTab.Enter(n, SymTab.KindImport)
  108. THEN SemError(200) END .)
  109. { ","
  110. GetIdent<n> (. IF ~SymTab.Enter(n, SymTab.KindImport)
  111. THEN SemError(200) END .) } .
  112. Block <isProc: BOOLEAN> (. VAR began: BOOLEAN; .)
  113. = (. began := FALSE; .)
  114. { Declaration }
  115. [ "BEGIN" (. began := TRUE;
  116. IF isProc THEN
  117. MGen.ProcEntry(
  118. SymTab.CurProc(),
  119. SymTab.ProcNLocals())
  120. ELSE MGen.BeginBody
  121. END; .)
  122. StatSeq ]
  123. "END" (. IF isProc THEN
  124. IF ~began THEN
  125. MGen.ProcEntry(
  126. SymTab.CurProc(),
  127. SymTab.ProcNLocals())
  128. END;
  129. IF SymTab.InFunction() THEN
  130. MGen.PushInt(0)
  131. END;
  132. MGen.Leave(SymTab.CurNPar(),
  133. SymTab.InFunction())
  134. END; .) .
  135. Declaration = "CONST"
  136. {
  137. ConstDecl ";" }
  138. | "TYPE"
  139. {
  140. TypeDecl ";" }
  141. | "VAR"
  142. {
  143. VarDecl ";" }
  144. | ProcedureDecl ";"
  145. | ModuleDecl ";" .
  146. ConstDecl (. VAR n: SymTab.Name;
  147. t: SymTab.TypeIndex;
  148. lx: MGen.LitStr;
  149. cls: INTEGER; .)
  150. = GetIdent<n> (. IF ~SymTab.Enter(n, SymTab.KindConst)
  151. THEN SemError(200) END .)
  152. "=" (. MGen.NoEmitEnter; .)
  153. ConstExpr<t, lx> (. SymTab.SetSymType(n, t);
  154. cls := SymTab.ClassOf(t);
  155. IF cls = SymTab.ClStr THEN
  156. SemError(230)
  157. ELSIF ~MGen.IsLit(lx) THEN
  158. SemError(230)
  159. END;
  160. MGen.DeclConst(n, lx, t);
  161. MGen.NoEmitExit; .) .
  162. ConstExpr <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr>
  163. (. VAR vD: BOOLEAN;
  164. vnD: SymTab.Name; .)
  165. = Expr<t, lx, vD, vnD> .
  166. TypeDecl (. VAR n: SymTab.Name;
  167. t0, t1: SymTab.TypeIndex; .)
  168. = GetIdent<n> (. IF ~SymTab.Enter(n, SymTab.KindType)
  169. THEN SemError(200) END;
  170. t0 := SymTab.NewAlias();
  171. SymTab.SetSymType(n, t0); .)
  172. "="
  173. Type<t1> (. IF t1 = t0 THEN SemError(223);
  174. SymTab.SetTarget(t0,
  175. SymTab.InvalidType)
  176. ELSE SymTab.SetTarget(t0, t1) END; .) .
  177. VarDecl (. VAR t: SymTab.TypeIndex;
  178. i: CARDINAL;
  179. nm: SymTab.Name;
  180. cls: INTEGER;
  181. sl: CARDINAL; .)
  182. = VarIdents ":"
  183. Type<t> (. cls := SymTab.ClassOf(t);
  184. IF (cls # SymTab.ClInt)
  185. & (cls # SymTab.ClReal)
  186. & (cls # SymTab.ClBool)
  187. & (cls # SymTab.ClChar)
  188. & (cls # SymTab.ClEnum)
  189. & (cls # SymTab.ClSet)
  190. & (cls # SymTab.ClArray)
  191. & (cls # SymTab.ClRecord)
  192. & (cls # SymTab.ClPtr) THEN
  193. SemError(230)
  194. END;
  195. sl := SymTab.TypeSlots(t);
  196. IF sl = 0 THEN
  197. SemError(230);
  198. sl := 1
  199. END;
  200. i := 0;
  201. WHILE i < SymTab.PendCount() DO
  202. SymTab.PendName(i, nm);
  203. IF SymTab.SymDepth(nm) = 0 THEN
  204. MGen.DeclVarSized(nm, sl)
  205. END;
  206. INC(i)
  207. END;
  208. SymTab.FixPending(t); .) .
  209. VarIdents (. VAR n: SymTab.Name; .)
  210. = GetIdent<n> (. IF ~SymTab.EnterPending(n,
  211. SymTab.KindVar)
  212. THEN SemError(200) END .)
  213. { ","
  214. GetIdent<n> (. IF ~SymTab.EnterPending(n,
  215. SymTab.KindVar)
  216. THEN SemError(200) END .) } .
  217. ProcedureDecl (. VAR n, m: SymTab.Name;
  218. rt: SymTab.TypeIndex;
  219. hasR, ok: BOOLEAN;
  220. endL: INTEGER; .)
  221. = "PROCEDURE" (. hasR := FALSE; .)
  222. GetIdent<n> (. IF SymTab.IsForward(n) THEN
  223. SymTab.ReuseProc(n)
  224. ELSIF ~SymTab.EnterProc(n) THEN
  225. SemError(200)
  226. END;
  227. SymTab.OpenProcScope;
  228. endL := MGen.NewLabel();
  229. MGen.Jmp(endL); .)
  230. [ "(" FormalParams ")" ]
  231. [ ":" QualIdent<rt> (. hasR := TRUE; .) ]
  232. (. IF hasR THEN
  233. ok := SymTab.SetProcRet(rt)
  234. ELSE
  235. ok := SymTab.SetProcRet(
  236. SymTab.InvalidType)
  237. END;
  238. IF ~ok THEN SemError(231) END;
  239. IF ~SymTab.VerifyProc() THEN
  240. SemError(231)
  241. END; .)
  242. ";"
  243. ( Block<TRUE> GetIdent<m> (. IF ~SymTab.Equal(n, m) THEN
  244. SemError(202) END;
  245. MGen.DefLabel(endL);
  246. SymTab.CloseProc; .)
  247. | "FORWARD" (. SymTab.SetForward;
  248. SymTab.CloseProc;
  249. MGen.DefLabel(endL); .) ) .
  250. ModuleDecl (. VAR n, m, e: SymTab.Name;
  251. noMod, enterOk,
  252. hasInit: BOOLEAN;
  253. initL, initN: INTEGER; .)
  254. = "MODULE" (. noMod := SymTab.InProc()
  255. OR SymTab.InModule();
  256. enterOk := FALSE;
  257. hasInit := FALSE; .)
  258. GetIdent<n> (. IF noMod THEN
  259. SemError(230)
  260. ELSIF ~SymTab.EnterModule(n) THEN
  261. SemError(200)
  262. ELSE
  263. enterOk := TRUE
  264. END; .)
  265. [ "EXPORT"
  266. GetIdent<e> (. IF ~noMod & enterOk THEN
  267. IF ~SymTab.ModuleAddExp(e) THEN
  268. SemError(200)
  269. END
  270. END; .)
  271. { "," GetIdent<e> (. IF ~noMod & enterOk THEN
  272. IF ~SymTab.ModuleAddExp(e) THEN
  273. SemError(200)
  274. END
  275. END; .) } ]
  276. ";"
  277. { Declaration }
  278. [ "BEGIN" (. hasInit := TRUE;
  279. IF ~noMod & enterOk THEN
  280. initL := MGen.NewLabel();
  281. MGen.Jmp(initL);
  282. initN := MGen.ModInitBegin();
  283. IF initN < 0 THEN
  284. SemError(230)
  285. END
  286. END; .)
  287. StatSeq ]
  288. "END"
  289. GetIdent<m> (. IF ~SymTab.Equal(n, m) THEN
  290. SemError(202)
  291. END;
  292. IF hasInit & ~noMod & enterOk THEN
  293. MGen.ModInitEnd(initN);
  294. MGen.DefLabel(initL)
  295. END;
  296. IF ~noMod & enterOk THEN
  297. IF ~SymTab.ExitModule() THEN
  298. SemError(201)
  299. END
  300. END; .) .
  301. FormalParams = FPSection { ";" FPSection } .
  302. FPSection (. VAR isV: BOOLEAN;
  303. nn, i: CARDINAL;
  304. pn: ARRAY [0 .. 15] OF SymTab.Name;
  305. n: SymTab.Name;
  306. t: SymTab.TypeIndex; .)
  307. = (. isV := FALSE; nn := 0; .)
  308. [ "VAR" (. isV := TRUE; .) ]
  309. GetIdent<n> (. IF nn <= HIGH(pn) THEN
  310. MGen.CopyName(n, pn[nn])
  311. END;
  312. INC(nn); .)
  313. { "," GetIdent<n> (. IF nn <= HIGH(pn) THEN
  314. MGen.CopyName(n, pn[nn])
  315. END;
  316. INC(nn); .) }
  317. ":" Type<t> (. IF ~isV
  318. & (t # SymTab.InvalidType)
  319. & (SymTab.TypeSlots(t) > 1) THEN
  320. SemError(230)
  321. END;
  322. i := 0;
  323. WHILE i < nn DO
  324. IF i <= HIGH(pn) THEN
  325. IF ~SymTab.EnterParam(
  326. pn[i], isV, t) THEN
  327. SemError(200)
  328. END
  329. END;
  330. INC(i)
  331. END; .) .
  332. QualIdent <VAR t: SymTab.TypeIndex>
  333. (. VAR n, m: SymTab.Name; .)
  334. = GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
  335. SemError(201);
  336. t := SymTab.InvalidType
  337. ELSIF SymTab.SymKind(n)
  338. = SymTab.KindModule THEN
  339. t := SymTab.InvalidType
  340. ELSIF (SymTab.SymKind(n) #
  341. SymTab.KindType)
  342. & (SymTab.SymKind(n) #
  343. SymTab.KindPredef)
  344. & (SymTab.SymKind(n) #
  345. SymTab.KindImport) THEN
  346. SemError(221);
  347. t := SymTab.InvalidType
  348. ELSE t := SymTab.SymType(n) END; .)
  349. { "."
  350. GetIdent<m> (. IF SymTab.SymKind(n)
  351. = SymTab.KindModule THEN
  352. IF SymTab.ExpKind(n, m)
  353. = SymTab.KindType THEN
  354. t := SymTab.ExpType(n, m)
  355. ELSIF SymTab.SelfKind(n, m)
  356. = SymTab.KindType THEN
  357. t := SymTab.SymType(m)
  358. ELSE
  359. IF SymTab.ExpKind(n, m) < 0 THEN
  360. IF SymTab.SelfKind(n, m) < 0 THEN
  361. SemError(201)
  362. ELSE SemError(221)
  363. END
  364. ELSE SemError(221)
  365. END;
  366. t := SymTab.InvalidType
  367. END
  368. ELSE
  369. t := SymTab.InvalidType
  370. END; .) } .
  371. (* Types: ProcedureType removed; subrange factored for LL(1) *)
  372. Type <VAR t: SymTab.TypeIndex>
  373. = SimpleType<t> | ArrayType<t> | RecordType<t>
  374. | SetType<t> | PointerType<t> .
  375. SimpleType <VAR t: SymTab.TypeIndex>
  376. (. VAR t1, t2: SymTab.TypeIndex;
  377. lx1, lx2: MGen.LitStr;
  378. vD: BOOLEAN;
  379. vnD: SymTab.Name;
  380. loI, hiI: INTEGER;
  381. lok, hik: BOOLEAN; .)
  382. = QualIdent<t> [ "["
  383. (. MGen.NoEmitEnter; lok := FALSE; hik := FALSE;
  384. loI := 0; hiI := -1; .)
  385. ConstExpr<t1, lx1> (. IF (t1 # SymTab.InvalidType)
  386. & (SymTab.ClassOf(t1) #
  387. SymTab.ClInt)
  388. & (SymTab.ClassOf(t1) #
  389. SymTab.ClChar)
  390. & (SymTab.ClassOf(t1) #
  391. SymTab.ClEnum) THEN
  392. SemError(224) END; .)
  393. ".."
  394. ConstExpr<t2, lx2> (. IF (t2 # SymTab.InvalidType)
  395. & (SymTab.ClassOf(t2) #
  396. SymTab.ClInt)
  397. & (SymTab.ClassOf(t2) #
  398. SymTab.ClChar)
  399. & (SymTab.ClassOf(t2) #
  400. SymTab.ClEnum) THEN
  401. SemError(224) END; .)
  402. "]"
  403. (. IF (t1 # SymTab.InvalidType)
  404. & (t2 # SymTab.InvalidType) THEN
  405. IF MGen.IsLit(lx1) THEN
  406. IF SymTab.ClassOf(t1)
  407. = SymTab.ClChar THEN
  408. loI := MGen.CharOrd(lx1);
  409. lok := TRUE
  410. ELSIF MGen.ParseInt(lx1, loI) THEN
  411. lok := TRUE
  412. END
  413. END;
  414. IF MGen.IsLit(lx2) THEN
  415. IF SymTab.ClassOf(t2)
  416. = SymTab.ClChar THEN
  417. hiI := MGen.CharOrd(lx2);
  418. hik := TRUE
  419. ELSIF MGen.ParseInt(lx2, hiI) THEN
  420. hik := TRUE
  421. END
  422. END
  423. END;
  424. IF lok & hik THEN
  425. t := SymTab.NewSubB(t1, loI, hiI)
  426. ELSE
  427. t := SymTab.NewSub(t1);
  428. IF (t1 # SymTab.InvalidType)
  429. & (t2 # SymTab.InvalidType) THEN
  430. SemError(230)
  431. END
  432. END;
  433. MGen.NoEmitExit; .) ]
  434. | "[" (. MGen.NoEmitEnter; lok := FALSE;
  435. hik := FALSE; loI := 0; hiI := -1; .)
  436. ConstExpr<t1, lx1> (. IF (t1 # SymTab.InvalidType)
  437. & (SymTab.ClassOf(t1) #
  438. SymTab.ClInt)
  439. & (SymTab.ClassOf(t1) #
  440. SymTab.ClChar)
  441. & (SymTab.ClassOf(t1) #
  442. SymTab.ClEnum) THEN
  443. SemError(224) END; .)
  444. ".."
  445. ConstExpr<t2, lx2> (. IF (t2 # SymTab.InvalidType)
  446. & (SymTab.ClassOf(t2) #
  447. SymTab.ClInt)
  448. & (SymTab.ClassOf(t2) #
  449. SymTab.ClChar)
  450. & (SymTab.ClassOf(t2) #
  451. SymTab.ClEnum) THEN
  452. SemError(224) END; .)
  453. "]" (. IF (t1 # SymTab.InvalidType)
  454. & (t2 # SymTab.InvalidType) THEN
  455. IF MGen.IsLit(lx1) THEN
  456. IF SymTab.ClassOf(t1)
  457. = SymTab.ClChar THEN
  458. loI := MGen.CharOrd(lx1);
  459. lok := TRUE
  460. ELSIF MGen.ParseInt(lx1,
  461. loI) THEN
  462. lok := TRUE
  463. END
  464. END;
  465. IF MGen.IsLit(lx2) THEN
  466. IF SymTab.ClassOf(t2)
  467. = SymTab.ClChar THEN
  468. hiI := MGen.CharOrd(lx2);
  469. hik := TRUE
  470. ELSIF MGen.ParseInt(lx2,
  471. hiI) THEN
  472. hik := TRUE
  473. END
  474. END
  475. END;
  476. IF lok & hik THEN
  477. t := SymTab.NewSubB(t1, loI, hiI)
  478. ELSE
  479. t := SymTab.NewSub(t1);
  480. IF (t1 # SymTab.InvalidType)
  481. & (t2 # SymTab.InvalidType) THEN
  482. SemError(230)
  483. END
  484. END;
  485. MGen.NoEmitExit; .)
  486. | Enum<t> .
  487. Enum <VAR t: SymTab.TypeIndex>
  488. (. VAR n: SymTab.Name;
  489. ord: INTEGER; .)
  490. = "(" (. t := SymTab.NewEnum();
  491. ord := 0; .)
  492. GetIdent<n> (. IF ~SymTab.Enter(n,
  493. SymTab.KindConst)
  494. THEN SemError(200) END;
  495. SymTab.SetSymType(n, t);
  496. SymTab.EnumAdd(t);
  497. MGen.DeclConstInt(n, ord);
  498. INC(ord); .)
  499. { ","
  500. GetIdent<n> (. IF ~SymTab.Enter(n,
  501. SymTab.KindConst)
  502. THEN SemError(200) END;
  503. SymTab.SetSymType(n, t);
  504. SymTab.EnumAdd(t);
  505. MGen.DeclConstInt(n, ord);
  506. INC(ord); .) }
  507. ")" .
  508. ArrayType <VAR t: SymTab.TypeIndex>
  509. (. VAR s, s2, e: SymTab.TypeIndex;
  510. idx: ARRAY [0 .. 7] OF
  511. SymTab.TypeIndex;
  512. nc, kk: CARDINAL;
  513. loA, hiA: INTEGER;
  514. isOpenA: BOOLEAN; .)
  515. = "ARRAY"
  516. [ SimpleType<s> (. IF (s # SymTab.InvalidType)
  517. & (SymTab.ClassOf(s) #
  518. SymTab.ClInt)
  519. & (SymTab.ClassOf(s) #
  520. SymTab.ClChar)
  521. & (SymTab.ClassOf(s) #
  522. SymTab.ClEnum) THEN
  523. SemError(224) END;
  524. nc := 0; isOpenA := FALSE;
  525. idx[nc] := s; INC(nc); .)
  526. { ","
  527. SimpleType<s2> (. IF (s2 # SymTab.InvalidType)
  528. & (SymTab.ClassOf(s2) #
  529. SymTab.ClInt)
  530. & (SymTab.ClassOf(s2) #
  531. SymTab.ClChar)
  532. & (SymTab.ClassOf(s2) #
  533. SymTab.ClEnum) THEN
  534. SemError(224) END;
  535. IF nc <= HIGH(idx) THEN
  536. idx[nc] := s2; INC(nc)
  537. END; .) }
  538. | (. nc := 0; isOpenA := TRUE; .) ]
  539. "OF"
  540. Type<e> (. IF isOpenA THEN
  541. t := SymTab.NewOpen(e)
  542. ELSE
  543. t := e;
  544. kk := nc;
  545. WHILE kk > 0 DO
  546. DEC(kk);
  547. loA := SymTab.TypeLo(idx[kk]);
  548. hiA := SymTab.TypeHi(idx[kk]);
  549. IF SymTab.TypeLen(idx[kk]) = 0 THEN
  550. IF idx[kk]
  551. # SymTab.InvalidType THEN
  552. SemError(230)
  553. END;
  554. loA := 0; hiA := -1
  555. END;
  556. t := SymTab.NewArrayB(t,
  557. loA, hiA)
  558. END
  559. END; .) .
  560. RecordType <VAR t: SymTab.TypeIndex>
  561. = "RECORD" (. t := SymTab.NewRecord(); .)
  562. FieldSeq<t>
  563. "END" .
  564. FieldSeq <rt: SymTab.TypeIndex>
  565. = Field<rt> { ";"
  566. Field<rt> } .
  567. Field <rt: SymTab.TypeIndex>
  568. (. VAR et: SymTab.TypeIndex; .)
  569. = [ FieldIdents<rt> ":"
  570. Type<et> (. IF (et # SymTab.InvalidType)
  571. & SymTab.IsOpen(et) THEN
  572. SemError(230)
  573. END;
  574. SymTab.FixPendingF(rt, et); .) ] .
  575. FieldIdents <rt: SymTab.TypeIndex>
  576. (. VAR n: SymTab.Name; .)
  577. = GetIdent<n> (. IF ~SymTab.FieldPending(rt, n)
  578. THEN SemError(200) END .)
  579. { ","
  580. GetIdent<n> (. IF ~SymTab.FieldPending(rt, n)
  581. THEN SemError(200) END .) } .
  582. SetType <VAR t: SymTab.TypeIndex>
  583. (. VAR s: SymTab.TypeIndex; .)
  584. = "SET"
  585. "OF"
  586. SimpleType<s> (. IF (s # SymTab.InvalidType)
  587. & (SymTab.ClassOf(s) #
  588. SymTab.ClInt)
  589. & (SymTab.ClassOf(s) #
  590. SymTab.ClChar)
  591. & (SymTab.ClassOf(s) #
  592. SymTab.ClEnum) THEN
  593. SemError(224) END;
  594. t := SymTab.NewSet(s); .) .
  595. PointerType <VAR t: SymTab.TypeIndex>
  596. (. VAR b: SymTab.TypeIndex; .)
  597. = "POINTER"
  598. "TO"
  599. Type<b> (. t := SymTab.NewPtr(b); .) .
  600. (* Statements: RETURN added; calls via AssignOrCall *)
  601. StatSeq = Stat { ";"
  602. Stat } .
  603. Stat (. VAR lx: INTEGER; .)
  604. = [ AssignOrCall | IfStat | CaseStat | WhileStat
  605. | RepeatStat | LoopStat | ForStat | WithStat | ReturnStat
  606. | NewStat | DispStat | WriteIntStat | WriteStrStat
  607. | "EXIT" (. IF MGen.TopLoop(lx) THEN
  608. MGen.Jmp(lx)
  609. ELSE SemError(230) END; .) ] .
  610. AssignOrCall (. VAR dt, et: SymTab.TypeIndex;
  611. dk: INTEGER;
  612. bn: SymTab.Name;
  613. lxD, lxe: MGen.LitStr;
  614. vE: BOOLEAN;
  615. vnE: SymTab.Name;
  616. sfx: BOOLEAN;
  617. okC: BOOLEAN;
  618. isR, conv,
  619. storable, pushedDst,
  620. pushedFld: BOOLEAN;
  621. dstBytes, srcBytes: CARDINAL;
  622. elemDt: SymTab.TypeIndex;
  623. modBare: INTEGER; .)
  624. = (. sfx := FALSE; pushedDst := FALSE;
  625. pushedFld := FALSE; .)
  626. DesignHead<dt, dk, bn, FALSE, lxD>
  627. DesignTail<dt, dk, bn, FALSE, lxD, sfx>
  628. ( ":="
  629. (. storable :=
  630. (dk = SymTab.KindVar)
  631. OR (dk = SymTab.KindParam)
  632. OR (dk = SymTab.KindVarPar);
  633. IF (dk = SymTab.KindField)
  634. & (~sfx)
  635. & (dt # SymTab.InvalidType) THEN
  636. MGen.WithAddr(bn);
  637. pushedFld := TRUE
  638. END;
  639. IF storable & ~sfx
  640. & (dt # SymTab.InvalidType)
  641. & ((SymTab.ClassOf(dt)
  642. = SymTab.ClArray)
  643. OR (SymTab.ClassOf(dt)
  644. = SymTab.ClRecord)) THEN
  645. MGen.PushAddr(bn);
  646. pushedDst := TRUE
  647. ELSIF ((dk = SymTab.KindVar)
  648. OR (dk
  649. = SymTab.KindParam)
  650. OR (dk
  651. = SymTab.KindVarPar)
  652. OR (dk
  653. = SymTab.KindField))
  654. & sfx
  655. & (dt # SymTab.InvalidType)
  656. & ((SymTab.ClassOf(dt)
  657. = SymTab.ClArray)
  658. OR (SymTab.ClassOf(dt)
  659. = SymTab.ClRecord)) THEN
  660. pushedDst := TRUE
  661. END;
  662. IF storable & ~sfx
  663. & ~pushedDst THEN
  664. IF (dt # SymTab.InvalidType)
  665. & (SymTab.TypeSlots(dt)
  666. > 1) THEN
  667. ELSE MGen.StoreSetup(bn)
  668. END
  669. END; .)
  670. Expr<et, lxe, vE, vnE> (. IF (dt # SymTab.InvalidType)
  671. & (dk # SymTab.KindVar)
  672. & (dk # SymTab.KindParam)
  673. & (dk # SymTab.KindVarPar)
  674. & (dk # SymTab.KindField)
  675. & (dk # SymTab.KindImport) THEN
  676. SemError(210)
  677. ELSIF pushedDst THEN
  678. IF et = SymTab.InvalidType THEN
  679. MGen.Drop; MGen.Drop
  680. ELSIF (SymTab.ClassOf(dt)
  681. = SymTab.ClArray)
  682. & (SymTab.ClassOf(
  683. SymTab.ArrayElem(dt))
  684. = SymTab.ClChar)
  685. & (SymTab.ClassOf(et)
  686. = SymTab.ClStr) THEN
  687. srcBytes :=
  688. MGen.StrLenOf(lxe) + 1;
  689. dstBytes :=
  690. SymTab.TypeSlots(dt) * 8;
  691. IF srcBytes > dstBytes THEN
  692. SemError(210);
  693. MGen.Drop; MGen.Drop
  694. ELSE
  695. MGen.PushBytes(srcBytes);
  696. MGen.CopyBlock
  697. END
  698. ELSIF ~SymTab.Assignable(et,
  699. dt) THEN
  700. SemError(210);
  701. MGen.Drop; MGen.Drop
  702. ELSE
  703. dstBytes :=
  704. SymTab.TypeSlots(dt) * 8;
  705. MGen.PushBytes(dstBytes);
  706. MGen.CopyBlock
  707. END
  708. ELSIF pushedFld THEN
  709. IF et = SymTab.InvalidType THEN
  710. MGen.Drop; MGen.Drop
  711. ELSIF (SymTab.TypeSlots(dt) > 1) THEN
  712. IF (SymTab.ClassOf(dt)
  713. = SymTab.ClArray)
  714. & (SymTab.ClassOf(
  715. SymTab.ArrayElem(dt))
  716. = SymTab.ClChar)
  717. & (SymTab.ClassOf(et)
  718. = SymTab.ClStr) THEN
  719. srcBytes :=
  720. MGen.StrLenOf(lxe) + 1;
  721. dstBytes :=
  722. SymTab.TypeSlots(dt) * 8;
  723. IF srcBytes > dstBytes THEN
  724. SemError(210);
  725. MGen.Drop; MGen.Drop
  726. ELSE
  727. MGen.PushBytes(srcBytes);
  728. MGen.CopyBlock
  729. END
  730. ELSIF ~SymTab.Assignable(et,
  731. dt) THEN
  732. SemError(210);
  733. MGen.Drop; MGen.Drop
  734. ELSE
  735. dstBytes :=
  736. SymTab.TypeSlots(dt) * 8;
  737. MGen.PushBytes(dstBytes);
  738. MGen.CopyBlock
  739. END
  740. ELSE
  741. IF ~SymTab.Assignable(et,
  742. dt) THEN
  743. SemError(210);
  744. MGen.Drop; MGen.Drop
  745. ELSE
  746. isR :=
  747. (SymTab.ClassOf(dt)
  748. = SymTab.ClReal);
  749. conv := isR
  750. & SymTab.IsIntFamily(et);
  751. IF conv THEN
  752. MGen.IntToReal
  753. END;
  754. IF (SymTab.ClassOf(dt)
  755. = SymTab.ClChar)
  756. OR (SymTab.ClassOf(dt)
  757. = SymTab.ClBool) THEN
  758. MGen.StoreByte
  759. ELSE MGen.StoreIndir0
  760. END
  761. END
  762. END
  763. ELSIF (dt # SymTab.InvalidType)
  764. & ~sfx
  765. & (SymTab.TypeSlots(dt) > 1) THEN
  766. IF ~SymTab.Assignable(et, dt) THEN
  767. SemError(210)
  768. ELSE SemError(230)
  769. END
  770. ELSIF ~SymTab.Assignable(et, dt) THEN
  771. SemError(210) END;
  772. IF dk = SymTab.KindImport THEN
  773. SemError(230)
  774. END;
  775. isR := (dt # SymTab.InvalidType)
  776. & ~pushedDst
  777. & ~pushedFld
  778. & (SymTab.ClassOf(dt)
  779. = SymTab.ClReal);
  780. conv := isR
  781. & SymTab.IsIntFamily(et);
  782. IF pushedDst THEN
  783. ELSIF pushedFld THEN
  784. ELSIF (dt # SymTab.InvalidType)
  785. & sfx THEN
  786. IF conv THEN
  787. MGen.IntToReal
  788. END;
  789. IF (SymTab.ClassOf(dt)
  790. = SymTab.ClChar)
  791. OR (SymTab.ClassOf(dt)
  792. = SymTab.ClBool) THEN
  793. MGen.StoreByte
  794. ELSE MGen.StoreIndir0
  795. END
  796. ELSIF storable & ~sfx THEN
  797. IF (dt # SymTab.InvalidType)
  798. & (SymTab.TypeSlots(dt)
  799. > 1) THEN
  800. MGen.Drop
  801. ELSE
  802. IF conv THEN
  803. MGen.IntToReal
  804. END;
  805. MGen.StoreFinish(bn)
  806. END
  807. ELSE MGen.Drop
  808. END; .)
  809. | CallTail<bn, lxD, sfx, FALSE, okC, FALSE>
  810. | (. IF (SymTab.SymKind(bn)
  811. = SymTab.KindModule)
  812. & sfx
  813. & (SymTab.StrLen(lxD) > 0) THEN
  814. modBare := SymTab.ExpProc(bn,
  815. lxD);
  816. IF modBare < 0 THEN
  817. IF SymTab.ExpKind(bn,
  818. lxD) # -1 THEN
  819. SemError(233)
  820. END
  821. ELSIF SymTab.ProcNParByNum(
  822. modBare) # 0 THEN
  823. SemError(233)
  824. ELSE
  825. MGen.CallProc(modBare);
  826. IF SymTab.ProcRetByNum(
  827. modBare)
  828. # SymTab.InvalidType THEN
  829. MGen.Drop
  830. END
  831. END
  832. ELSE
  833. MGen.ActBegin(bn);
  834. IF MGen.ActEnd(bn, FALSE,
  835. FALSE) # 0 THEN
  836. SemError(233)
  837. END
  838. END; .) ) .
  839. CallTail <pn: SymTab.Name; exp: SymTab.Name; sfx: BOOLEAN;
  840. inExpr: BOOLEAN; VAR ok: BOOLEAN; hasDead: BOOLEAN>
  841. (. VAR t: SymTab.TypeIndex;
  842. lx: MGen.LitStr;
  843. v: BOOLEAN;
  844. vn: SymTab.Name;
  845. isModP: BOOLEAN;
  846. modPNum: INTEGER;
  847. modErr: BOOLEAN; .)
  848. = "(" (. ok := FALSE; modErr := FALSE;
  849. isModP :=
  850. (SymTab.SymKind(pn)
  851. = SymTab.KindModule)
  852. & sfx
  853. & (SymTab.StrLen(exp) > 0);
  854. IF hasDead THEN MGen.Drop END;
  855. IF isModP THEN
  856. modPNum := SymTab.ExpProc(pn,
  857. exp);
  858. IF (modPNum < 0)
  859. & (SymTab.SelfKind(pn,
  860. exp)
  861. = SymTab.KindProc) THEN
  862. modPNum :=
  863. SymTab.ProcNum(exp)
  864. END;
  865. IF modPNum < 0 THEN
  866. IF SymTab.ExpKind(pn,
  867. exp) # -1 THEN
  868. SemError(233)
  869. END;
  870. modErr := TRUE
  871. ELSIF inExpr
  872. & (SymTab.ProcRetByNum(
  873. modPNum)
  874. = SymTab.InvalidType)
  875. THEN
  876. SemError(233);
  877. modErr := TRUE
  878. END;
  879. MGen.ActBeginNum(modPNum)
  880. ELSE
  881. MGen.ActBegin(pn)
  882. END; .)
  883. [ Expr<t, lx, v, vn> (. IF isModP THEN
  884. IF ~modErr
  885. & (MGen.ActValue(t, v, vn)
  886. # 0) THEN
  887. SemError(233);
  888. modErr := TRUE
  889. END
  890. ELSIF MGen.ActValue(t, v, vn) # 0 THEN
  891. SemError(233)
  892. END; .)
  893. { "," Expr<t, lx, v, vn> (. IF isModP THEN
  894. IF ~modErr
  895. & (MGen.ActValue(t, v, vn)
  896. # 0) THEN
  897. SemError(233);
  898. modErr := TRUE
  899. END
  900. ELSIF MGen.ActValue(t, v, vn) # 0 THEN
  901. SemError(233)
  902. END; .) } ]
  903. ")" (. IF isModP THEN
  904. IF ~modErr THEN
  905. IF MGen.ActEndNum(modPNum,
  906. inExpr) # 0 THEN
  907. SemError(233)
  908. ELSE ok := TRUE
  909. END
  910. END
  911. ELSIF MGen.ActEnd(pn, sfx,
  912. inExpr) # 0
  913. THEN SemError(233)
  914. ELSE ok := TRUE
  915. END; .) .
  916. IfStat (. VAR t: SymTab.TypeIndex;
  917. lxC: MGen.LitStr;
  918. vC: BOOLEAN;
  919. vnC: SymTab.Name;
  920. elseL, endL: INTEGER;
  921. hasElse: BOOLEAN; .)
  922. = "IF"
  923. Expr<t, lxC, vC, vnC> (. IF ~SymTab.BoolCheck(t) THEN
  924. SemError(214) END;
  925. elseL := MGen.NewLabel();
  926. endL := MGen.NewLabel();
  927. MGen.Jz(elseL);
  928. hasElse := FALSE; .)
  929. "THEN"
  930. StatSeq
  931. { "ELSIF" (. MGen.Jmp(endL);
  932. MGen.DefLabel(elseL); .)
  933. Expr<t, lxC, vC, vnC> (. IF ~SymTab.BoolCheck(t) THEN
  934. SemError(214) END;
  935. elseL := MGen.NewLabel();
  936. MGen.Jz(elseL); .)
  937. "THEN"
  938. StatSeq }
  939. [ "ELSE" (. MGen.Jmp(endL);
  940. MGen.DefLabel(elseL);
  941. hasElse := TRUE; .)
  942. StatSeq ]
  943. "END" (. IF ~hasElse THEN
  944. MGen.DefLabel(elseL)
  945. END;
  946. MGen.DefLabel(endL); .) .
  947. CaseStat (. VAR st: SymTab.TypeIndex;
  948. lxS: MGen.LitStr;
  949. vS: BOOLEAN;
  950. vnS: SymTab.Name;
  951. tmp, endL: INTEGER; .)
  952. = "CASE"
  953. Expr<st, lxS, vS, vnS> (. tmp := MGen.TempGlobal();
  954. MGen.StoreTemp(tmp);
  955. endL := MGen.NewLabel(); .)
  956. "OF"
  957. Case<st, tmp, endL> { "|"
  958. Case<st, tmp, endL> }
  959. [ "ELSE"
  960. StatSeq ]
  961. "END" (. MGen.DefLabel(endL); .) .
  962. Case <sel: SymTab.TypeIndex; tmp: INTEGER; endL: INTEGER>
  963. (. VAR lB, lN: INTEGER; .)
  964. = [ LabelList<sel, tmp, lB, lN> ":" (. MGen.DefLabel(lB); .)
  965. StatSeq (. MGen.Jmp(endL);
  966. MGen.DefLabel(lN); .) ] .
  967. LabelList <sel: SymTab.TypeIndex; tmp: INTEGER;
  968. VAR lB: INTEGER; VAR lN: INTEGER>
  969. = (. lB := MGen.NewLabel();
  970. lN := MGen.NewLabel(); .)
  971. Labels<sel, tmp, lB> { ","
  972. Labels<sel, tmp, lB> }
  973. (. MGen.Jmp(lN); .) .
  974. Labels <sel: SymTab.TypeIndex; tmp: INTEGER; bodyL: INTEGER>
  975. (. VAR t, t2: SymTab.TypeIndex;
  976. lx1, lx2: MGen.LitStr;
  977. v1, v2: BOOLEAN;
  978. vn1, vn2: SymTab.Name;
  979. ta, tb, chunk: INTEGER;
  980. r, hasRange: BOOLEAN; .)
  981. = ConstExpr<t, lx1> (. IF ~SymTab.EqCheck(t, sel) THEN
  982. SemError(213) END;
  983. r := (SymTab.ClassOf(sel)
  984. = SymTab.ClReal)
  985. & (SymTab.ClassOf(t)
  986. = SymTab.ClReal);
  987. ta := MGen.TempGlobal();
  988. MGen.StoreTemp(ta);
  989. hasRange := FALSE; .)
  990. [ ".."
  991. ConstExpr<t2, lx2> (. IF ~SymTab.EqCheck(t2, sel) THEN
  992. SemError(213) END;
  993. tb := MGen.TempGlobal();
  994. MGen.StoreTemp(tb);
  995. hasRange := TRUE; .) ]
  996. (. IF hasRange THEN
  997. MGen.LoadTemp(tmp);
  998. MGen.LoadTemp(ta);
  999. IF r THEN MGen.RealGe
  1000. ELSE MGen.IGe END;
  1001. MGen.LoadTemp(tmp);
  1002. MGen.LoadTemp(tb);
  1003. IF r THEN MGen.RealLe
  1004. ELSE MGen.ILe END;
  1005. MGen.And
  1006. ELSE
  1007. MGen.LoadTemp(tmp);
  1008. MGen.LoadTemp(ta);
  1009. IF r THEN MGen.RealEq
  1010. ELSE MGen.Eq END
  1011. END;
  1012. chunk := MGen.NewLabel();
  1013. MGen.Jz(chunk);
  1014. MGen.Jmp(bodyL);
  1015. MGen.DefLabel(chunk); .) .
  1016. WhileStat (. VAR t: SymTab.TypeIndex;
  1017. lxC: MGen.LitStr;
  1018. vC: BOOLEAN;
  1019. vnC: SymTab.Name;
  1020. topL, endL: INTEGER; .)
  1021. = "WHILE" (. topL := MGen.NewLabel();
  1022. endL := MGen.NewLabel();
  1023. MGen.DefLabel(topL); .)
  1024. Expr<t, lxC, vC, vnC> (. IF ~SymTab.BoolCheck(t) THEN
  1025. SemError(214) END;
  1026. MGen.Jz(endL); .)
  1027. "DO"
  1028. StatSeq
  1029. "END" (. MGen.Jmp(topL);
  1030. MGen.DefLabel(endL); .) .
  1031. RepeatStat (. VAR t: SymTab.TypeIndex;
  1032. lxC: MGen.LitStr;
  1033. vC: BOOLEAN;
  1034. vnC: SymTab.Name;
  1035. topL: INTEGER; .)
  1036. = "REPEAT" (. topL := MGen.NewLabel();
  1037. MGen.DefLabel(topL); .)
  1038. StatSeq
  1039. "UNTIL"
  1040. Expr<t, lxC, vC, vnC> (. IF ~SymTab.BoolCheck(t) THEN
  1041. SemError(214) END;
  1042. MGen.Jz(topL); .) .
  1043. LoopStat (. VAR topL, exitL: INTEGER; .)
  1044. = "LOOP" (. topL := MGen.NewLabel();
  1045. exitL := MGen.NewLabel();
  1046. MGen.DefLabel(topL);
  1047. MGen.PushLoop(exitL); .)
  1048. StatSeq
  1049. "END" (. MGen.Jmp(topL);
  1050. MGen.DefLabel(exitL);
  1051. MGen.PopLoop; .) .
  1052. ForStat (. VAR n, lv: SymTab.Name;
  1053. fk: INTEGER;
  1054. lo, hi: SymTab.TypeIndex;
  1055. lxLo, lxHi: MGen.LitStr;
  1056. vLo, vHi: BOOLEAN;
  1057. vnLo, vnHi: SymTab.Name;
  1058. byV, ht: INTEGER;
  1059. lTop, lChk, lEnd: INTEGER;
  1060. neg, storable: BOOLEAN; .)
  1061. = "FOR"
  1062. GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
  1063. SemError(201);
  1064. fk := -1
  1065. ELSIF (SymTab.SymKind(n) #
  1066. SymTab.KindVar)
  1067. & (SymTab.SymKind(n) #
  1068. SymTab.KindParam)
  1069. & (SymTab.SymKind(n) #
  1070. SymTab.KindVarPar)
  1071. & (SymTab.SymKind(n) #
  1072. SymTab.KindField) THEN
  1073. SemError(220);
  1074. fk := -1
  1075. ELSIF (SymTab.SymType(n) #
  1076. SymTab.InvalidType)
  1077. & ~SymTab.IsIntFamily(
  1078. SymTab.SymType(n)) THEN
  1079. SemError(220);
  1080. fk := -1
  1081. ELSE
  1082. fk := SymTab.SymKind(n)
  1083. END;
  1084. MGen.CopyName(n, lv);
  1085. storable := (fk = SymTab.KindVar)
  1086. OR (fk = SymTab.KindParam)
  1087. OR (fk = SymTab.KindVarPar);
  1088. IF storable THEN
  1089. MGen.StoreSetup(lv)
  1090. END; .)
  1091. ":="
  1092. Expr<lo, lxLo, vLo, vnLo> (. IF (lo # SymTab.InvalidType)
  1093. & ~SymTab.IsIntFamily(lo) THEN
  1094. SemError(220) END;
  1095. IF storable THEN
  1096. MGen.StoreFinish(lv)
  1097. ELSE MGen.Drop
  1098. END; .)
  1099. "TO"
  1100. Expr<hi, lxHi, vHi, vnHi> (. IF (hi # SymTab.InvalidType)
  1101. & ~SymTab.IsIntFamily(hi) THEN
  1102. SemError(220) END;
  1103. ht := MGen.TempGlobal();
  1104. MGen.StoreTemp(ht);
  1105. byV := 1; neg := FALSE; .)
  1106. [ "BY"
  1107. ByLit<byV> (. neg := byV < 0; .) ]
  1108. "DO" (. lTop := MGen.NewLabel();
  1109. lChk := MGen.NewLabel();
  1110. lEnd := MGen.NewLabel();
  1111. MGen.Jmp(lChk);
  1112. MGen.DefLabel(lTop); .)
  1113. StatSeq
  1114. "END" (. MGen.PushVar(lv);
  1115. MGen.PushInt(byV);
  1116. MGen.Add;
  1117. IF storable THEN
  1118. MGen.StoreFinish(lv)
  1119. ELSE MGen.Drop
  1120. END;
  1121. MGen.DefLabel(lChk);
  1122. MGen.PushVar(lv);
  1123. MGen.LoadTemp(ht);
  1124. IF neg THEN MGen.IGe
  1125. ELSE MGen.ILe END;
  1126. MGen.Jz(lEnd);
  1127. MGen.Jmp(lTop);
  1128. MGen.DefLabel(lEnd); .) .
  1129. ByLit <VAR v: INTEGER> (. VAR s: ARRAY [0 .. 255] OF CHAR; .)
  1130. = integer (. LexString(s);
  1131. IF ~MGen.ParseInt(s, v) THEN
  1132. v := 1
  1133. END; .)
  1134. | "-" integer (. LexString(s);
  1135. IF MGen.ParseInt(s, v) THEN
  1136. v := -v
  1137. ELSE v := -1
  1138. END; .) .
  1139. WithStat (. VAR dt: SymTab.TypeIndex;
  1140. dk: INTEGER;
  1141. bnW: SymTab.Name;
  1142. lxW: MGen.LitStr;
  1143. sfxW: BOOLEAN;
  1144. pushed: BOOLEAN; .)
  1145. = "WITH"
  1146. DesignHead<dt, dk, bnW, FALSE, lxW>
  1147. DesignTail<dt, dk, bnW, FALSE, lxW, sfxW>
  1148. (. pushed := FALSE;
  1149. IF dt = SymTab.InvalidType THEN
  1150. IF sfxW THEN MGen.Drop END
  1151. ELSIF SymTab.ClassOf(dt)
  1152. # SymTab.ClRecord THEN
  1153. SemError(215);
  1154. IF sfxW THEN MGen.Drop END
  1155. ELSE
  1156. IF ~sfxW THEN
  1157. IF (dk
  1158. = SymTab.KindVar)
  1159. OR (dk
  1160. = SymTab.KindParam)
  1161. OR (dk
  1162. = SymTab.KindVarPar) THEN
  1163. MGen.PushAddr(bnW)
  1164. ELSIF dk
  1165. = SymTab.KindField THEN
  1166. MGen.WithAddr(bnW)
  1167. ELSE MGen.PushInt(0)
  1168. END
  1169. END;
  1170. MGen.WithEnter(dt);
  1171. pushed :=
  1172. SymTab.PushRecord(dt);
  1173. IF ~pushed THEN
  1174. SemError(215)
  1175. END
  1176. END; .)
  1177. "DO"
  1178. StatSeq
  1179. "END" (. IF pushed THEN
  1180. SymTab.PopScope;
  1181. MGen.WithExit
  1182. END; .) .
  1183. ReturnStat (. VAR t: SymTab.TypeIndex;
  1184. lx: MGen.LitStr;
  1185. v: BOOLEAN;
  1186. vn: SymTab.Name;
  1187. hasE, doRet, conv: BOOLEAN; .)
  1188. = "RETURN" (. hasE := FALSE; .)
  1189. [ Expr<t, lx, v, vn> (. hasE := TRUE;
  1190. doRet := FALSE;
  1191. IF ~SymTab.InProc() THEN
  1192. SemError(232)
  1193. ELSIF ~SymTab.InFunction() THEN
  1194. SemError(232)
  1195. ELSIF ~SymTab.Assignable(
  1196. t, SymTab.CurRet()) THEN
  1197. SemError(232)
  1198. ELSE doRet := TRUE
  1199. END;
  1200. conv := doRet
  1201. & SymTab.IsIntFamily(t)
  1202. & (SymTab.ClassOf(
  1203. SymTab.CurRet())
  1204. = SymTab.ClReal);
  1205. IF doRet THEN
  1206. IF conv THEN
  1207. MGen.IntToReal
  1208. END;
  1209. MGen.Leave(
  1210. SymTab.CurNPar(), TRUE)
  1211. ELSE MGen.Drop
  1212. END; .) ]
  1213. (. IF ~hasE THEN
  1214. IF ~SymTab.InProc() THEN
  1215. SemError(232)
  1216. ELSIF SymTab.InFunction() THEN
  1217. SemError(232)
  1218. ELSE MGen.Leave(
  1219. SymTab.CurNPar(), FALSE)
  1220. END
  1221. END; .) .
  1222. NewStat (. VAR dt: SymTab.TypeIndex;
  1223. dk: INTEGER;
  1224. bnN: SymTab.Name;
  1225. lxN: MGen.LitStr;
  1226. sfxN: BOOLEAN;
  1227. baseT: SymTab.TypeIndex;
  1228. slN: CARDINAL; .)
  1229. = "NEW"
  1230. "(" DesignHead<dt, dk, bnN, FALSE, lxN>
  1231. DesignTail<dt, dk, bnN, FALSE, lxN, sfxN>
  1232. ")" (. IF dt = SymTab.InvalidType THEN
  1233. IF sfxN THEN MGen.Drop END
  1234. ELSIF SymTab.ClassOf(dt)
  1235. # SymTab.ClPtr THEN
  1236. SemError(219);
  1237. IF sfxN THEN MGen.Drop END
  1238. ELSE
  1239. baseT := SymTab.PtrBase(dt);
  1240. slN := SymTab.TypeSlots(baseT);
  1241. IF slN = 0 THEN
  1242. SemError(230);
  1243. slN := 1
  1244. END;
  1245. IF ~sfxN THEN
  1246. IF (dk = SymTab.KindVar)
  1247. OR (dk
  1248. = SymTab.KindParam)
  1249. OR (dk
  1250. = SymTab.KindVarPar) THEN
  1251. MGen.PushAddr(bnN)
  1252. ELSIF dk
  1253. = SymTab.KindField THEN
  1254. MGen.WithAddr(bnN)
  1255. ELSE MGen.PushInt(0)
  1256. END
  1257. END;
  1258. MGen.PushBytes(slN * 8);
  1259. MGen.AllocOp
  1260. END; .) .
  1261. DispStat (. VAR dt: SymTab.TypeIndex;
  1262. dk: INTEGER;
  1263. bnD: SymTab.Name;
  1264. lxD: MGen.LitStr;
  1265. sfxD: BOOLEAN;
  1266. baseT: SymTab.TypeIndex;
  1267. slD: CARDINAL; .)
  1268. = "DISPOSE"
  1269. "(" DesignHead<dt, dk, bnD, FALSE, lxD>
  1270. DesignTail<dt, dk, bnD, FALSE, lxD, sfxD>
  1271. ")" (. IF dt = SymTab.InvalidType THEN
  1272. IF sfxD THEN MGen.Drop END
  1273. ELSIF SymTab.ClassOf(dt)
  1274. # SymTab.ClPtr THEN
  1275. SemError(219);
  1276. IF sfxD THEN MGen.Drop END
  1277. ELSE
  1278. baseT := SymTab.PtrBase(dt);
  1279. slD := SymTab.TypeSlots(baseT);
  1280. IF slD = 0 THEN
  1281. SemError(230);
  1282. slD := 1
  1283. END;
  1284. IF ~sfxD THEN
  1285. IF (dk = SymTab.KindVar)
  1286. OR (dk
  1287. = SymTab.KindParam)
  1288. OR (dk
  1289. = SymTab.KindVarPar) THEN
  1290. MGen.PushAddr(bnD)
  1291. ELSIF dk
  1292. = SymTab.KindField THEN
  1293. MGen.WithAddr(bnD)
  1294. ELSE MGen.PushInt(0)
  1295. END
  1296. END;
  1297. MGen.PushBytes(slD * 8);
  1298. MGen.DeallocOp
  1299. END; .) .
  1300. WriteIntStat (. VAR t: SymTab.TypeIndex;
  1301. lx: MGen.LitStr;
  1302. v: BOOLEAN;
  1303. vn: SymTab.Name; .)
  1304. = "WriteInt"
  1305. "(" Expr<t, lx, v, vn> ")" (. IF t = SymTab.InvalidType THEN
  1306. MGen.Drop
  1307. ELSIF ~SymTab.IsIntFamily(t) THEN
  1308. SemError(210);
  1309. MGen.Drop
  1310. ELSE
  1311. MGen.CallPrint
  1312. END; .) .
  1313. WriteStrStat (. VAR t: SymTab.TypeIndex;
  1314. lx: MGen.LitStr;
  1315. v: BOOLEAN;
  1316. vn: SymTab.Name; .)
  1317. = "WriteString"
  1318. "(" Expr<t, lx, v, vn> ")" (. IF t = SymTab.InvalidType THEN
  1319. MGen.Drop
  1320. ELSIF (SymTab.ClassOf(t)
  1321. = SymTab.ClStr) THEN
  1322. MGen.PushInt(1);
  1323. MGen.SysCall
  1324. ELSIF (SymTab.ClassOf(t)
  1325. = SymTab.ClArray)
  1326. & (SymTab.ClassOf(
  1327. SymTab.ArrayElem(t))
  1328. = SymTab.ClChar) THEN
  1329. MGen.PushInt(1);
  1330. MGen.SysCall
  1331. ELSE
  1332. SemError(210);
  1333. MGen.Drop
  1334. END; .) .
  1335. (* Expressions: Designator without ActualParameters (calls use
  1336. CallTail). Each expression synthesizes its SymTab type in t,
  1337. the source text in lx for single literals ("" otherwise), and
  1338. whether it is a plain variable (v/vn) for VAR actuals.
  1339. Values travel on the MC64 stack. *)
  1340. DesignHead <VAR t: SymTab.TypeIndex; VAR k: INTEGER;
  1341. VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr>
  1342. (. VAR n: SymTab.Name;
  1343. cls: INTEGER; .)
  1344. = GetIdent<n> (. MGen.CopyName(n, bn);
  1345. lx[0] := 0C;
  1346. IF ~SymTab.Lookup(n) THEN
  1347. SemError(201);
  1348. t := SymTab.InvalidType; k := -1;
  1349. IF doLoad THEN
  1350. MGen.PushInt(0)
  1351. END
  1352. ELSE
  1353. t := SymTab.SymType(n);
  1354. k := SymTab.SymKind(n);
  1355. IF k = SymTab.KindConst THEN
  1356. IF SymTab.Equal(n, "TRUE") THEN
  1357. t := SymTab.BoolType();
  1358. MGen.CopyName("TRUE", lx);
  1359. IF doLoad THEN
  1360. MGen.PushInt(1)
  1361. END
  1362. ELSIF SymTab.Equal(n,
  1363. "FALSE") THEN
  1364. t := SymTab.BoolType();
  1365. MGen.CopyName("FALSE", lx);
  1366. IF doLoad THEN
  1367. MGen.PushInt(0)
  1368. END
  1369. ELSE
  1370. cls :=
  1371. SymTab.ClassOf(t);
  1372. IF (t #
  1373. SymTab.InvalidType)
  1374. & (cls # SymTab.ClStr)
  1375. & ((cls = SymTab.ClInt)
  1376. OR (cls = SymTab.ClReal)
  1377. OR (cls = SymTab.ClBool)
  1378. OR (cls = SymTab.ClChar)
  1379. OR (cls
  1380. = SymTab.ClEnum)) THEN
  1381. IF doLoad THEN
  1382. MGen.LoadVar(n)
  1383. END
  1384. ELSIF doLoad THEN
  1385. MGen.PushInt(0)
  1386. END
  1387. END
  1388. ELSIF (k = SymTab.KindVar)
  1389. OR (k = SymTab.KindParam)
  1390. OR (k
  1391. = SymTab.KindVarPar) THEN
  1392. cls := SymTab.ClassOf(t);
  1393. IF (cls = SymTab.ClInt)
  1394. OR (cls = SymTab.ClReal)
  1395. OR (cls = SymTab.ClBool)
  1396. OR (cls = SymTab.ClChar)
  1397. OR (cls
  1398. = SymTab.ClEnum)
  1399. OR (cls
  1400. = SymTab.ClSet)
  1401. OR (cls
  1402. = SymTab.ClPtr) THEN
  1403. IF doLoad THEN
  1404. MGen.PushVar(n)
  1405. END
  1406. ELSIF (cls
  1407. = SymTab.ClArray)
  1408. OR (cls
  1409. = SymTab.ClRecord) THEN
  1410. IF doLoad THEN
  1411. MGen.PushAddr(n)
  1412. END
  1413. ELSIF t
  1414. = SymTab.InvalidType THEN
  1415. IF doLoad THEN
  1416. MGen.PushInt(0)
  1417. END
  1418. ELSE SemError(230);
  1419. IF doLoad THEN
  1420. MGen.PushInt(0)
  1421. END
  1422. END
  1423. ELSE
  1424. IF doLoad THEN
  1425. IF k = SymTab.KindField THEN
  1426. MGen.WithAddr(n);
  1427. cls := SymTab.ClassOf(t);
  1428. IF (t
  1429. = SymTab.InvalidType)
  1430. OR (cls
  1431. = SymTab.ClArray)
  1432. OR (cls
  1433. = SymTab.ClRecord) THEN
  1434. ELSE
  1435. IF (cls
  1436. = SymTab.ClChar)
  1437. OR (cls
  1438. = SymTab.ClBool) THEN
  1439. MGen.LoadByte
  1440. ELSE MGen.LoadIndir
  1441. END
  1442. END
  1443. ELSE MGen.PushInt(0)
  1444. END
  1445. END;
  1446. IF k = SymTab.KindField THEN
  1447. ELSIF k
  1448. = SymTab.KindImport THEN
  1449. SemError(230)
  1450. END
  1451. END
  1452. END; .) .
  1453. DesignTail <VAR t: SymTab.TypeIndex; VAR k: INTEGER;
  1454. VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr;
  1455. VAR sfx: BOOLEAN>
  1456. (. VAR m: SymTab.Name;
  1457. it: SymTab.TypeIndex;
  1458. lxI: MGen.LitStr;
  1459. vI: BOOLEAN;
  1460. vnI: SymTab.Name;
  1461. loA: INTEGER;
  1462. elemT: SymTab.TypeIndex;
  1463. esl, ebytes: CARDINAL;
  1464. firstT: BOOLEAN;
  1465. clsI: INTEGER;
  1466. sk: INTEGER;
  1467. qM: SymTab.Name; .)
  1468. = (. sfx := FALSE; .)
  1469. { "." (. firstT := ~sfx;
  1470. sfx := TRUE; lx[0] := 0C;
  1471. IF ~doLoad & firstT THEN
  1472. IF (k = SymTab.KindVar)
  1473. OR (k = SymTab.KindParam)
  1474. OR (k
  1475. = SymTab.KindVarPar) THEN
  1476. MGen.PushAddr(bn)
  1477. ELSIF k
  1478. = SymTab.KindField THEN
  1479. MGen.WithAddr(bn)
  1480. ELSIF k
  1481. = SymTab.KindModule THEN
  1482. ELSE MGen.PushInt(0)
  1483. END
  1484. END; .)
  1485. GetIdent<m> (. IF (k = SymTab.KindModule) THEN
  1486. IF SymTab.ExpKind(bn, m) = -1 THEN
  1487. sk := SymTab.SelfKind(bn, m);
  1488. IF sk = SymTab.KindProc THEN
  1489. MGen.CopyName(m, lx);
  1490. t := SymTab.InvalidType;
  1491. IF doLoad THEN
  1492. MGen.Drop; MGen.PushInt(0)
  1493. ELSIF firstT THEN
  1494. ELSE MGen.Drop
  1495. END
  1496. ELSIF sk # -1 THEN
  1497. t := SymTab.SymType(m);
  1498. k := sk;
  1499. SymTab.SelfQual(m, qM);
  1500. IF doLoad THEN
  1501. MGen.Drop;
  1502. MGen.GlobalAddr(qM)
  1503. ELSE
  1504. IF firstT THEN
  1505. ELSE MGen.Drop
  1506. END;
  1507. MGen.GlobalAddr(qM)
  1508. END
  1509. ELSE
  1510. SemError(201);
  1511. MGen.CopyName(m, lx);
  1512. t := SymTab.InvalidType;
  1513. IF doLoad THEN
  1514. MGen.Drop; MGen.PushInt(0)
  1515. ELSIF firstT THEN
  1516. ELSE MGen.Drop
  1517. END
  1518. END
  1519. ELSIF SymTab.ExpKind(bn, m)
  1520. = SymTab.KindProc THEN
  1521. MGen.CopyName(m, lx);
  1522. t := SymTab.InvalidType;
  1523. IF doLoad THEN
  1524. MGen.Drop; MGen.PushInt(0)
  1525. ELSIF firstT THEN
  1526. ELSE MGen.Drop
  1527. END
  1528. ELSE
  1529. t := SymTab.ExpType(bn, m);
  1530. k := SymTab.ExpKind(bn, m);
  1531. SymTab.ExpQual(bn, m, qM);
  1532. IF doLoad THEN
  1533. MGen.Drop;
  1534. MGen.GlobalAddr(qM)
  1535. ELSE
  1536. IF firstT THEN
  1537. ELSE MGen.Drop
  1538. END;
  1539. MGen.GlobalAddr(qM)
  1540. END
  1541. END
  1542. ELSIF t = SymTab.InvalidType THEN
  1543. IF ~doLoad & firstT THEN
  1544. MGen.Drop
  1545. ELSIF doLoad THEN
  1546. MGen.Drop; MGen.PushInt(0)
  1547. END
  1548. ELSIF SymTab.ClassOf(t) #
  1549. SymTab.ClRecord THEN
  1550. SemError(215);
  1551. t := SymTab.InvalidType;
  1552. IF doLoad THEN
  1553. MGen.Drop; MGen.PushInt(0)
  1554. ELSIF firstT THEN
  1555. MGen.Drop
  1556. END
  1557. ELSIF ~SymTab.FieldExists(t, m) THEN
  1558. SemError(216);
  1559. t := SymTab.InvalidType;
  1560. IF doLoad THEN
  1561. MGen.Drop; MGen.PushInt(0)
  1562. ELSIF firstT THEN
  1563. MGen.Drop
  1564. END
  1565. ELSE
  1566. loA := SymTab.FieldOffset(t, m);
  1567. elemT := SymTab.FieldType(t, m);
  1568. IF loA < 0 THEN
  1569. SemError(216);
  1570. t := SymTab.InvalidType;
  1571. IF doLoad THEN
  1572. MGen.Drop; MGen.PushInt(0)
  1573. ELSIF firstT THEN
  1574. MGen.Drop
  1575. END
  1576. ELSE
  1577. MGen.FieldAdd(
  1578. VAL(CARDINAL, loA));
  1579. t := elemT
  1580. END
  1581. END; .)
  1582. | "[" (. firstT := ~sfx;
  1583. sfx := TRUE; lx[0] := 0C;
  1584. IF ~doLoad & firstT THEN
  1585. IF (k = SymTab.KindVar)
  1586. OR (k = SymTab.KindParam)
  1587. OR (k
  1588. = SymTab.KindVarPar) THEN
  1589. MGen.PushAddr(bn)
  1590. ELSIF k
  1591. = SymTab.KindField THEN
  1592. MGen.WithAddr(bn)
  1593. ELSE MGen.PushInt(0)
  1594. END
  1595. END; .)
  1596. Expr<it, lxI, vI, vnI> (. IF t = SymTab.InvalidType THEN
  1597. MGen.Drop;
  1598. IF doLoad THEN
  1599. MGen.Drop; MGen.PushInt(0)
  1600. ELSE
  1601. IF ~firstT THEN
  1602. ELSE MGen.Drop
  1603. END
  1604. END
  1605. ELSIF SymTab.ClassOf(t) #
  1606. SymTab.ClArray THEN
  1607. SemError(217);
  1608. t := SymTab.InvalidType;
  1609. MGen.Drop;
  1610. IF doLoad THEN
  1611. MGen.Drop; MGen.PushInt(0)
  1612. ELSE
  1613. IF ~firstT THEN
  1614. ELSE MGen.Drop
  1615. END
  1616. END
  1617. ELSE
  1618. clsI := SymTab.ClassOf(it);
  1619. IF (it
  1620. # SymTab.InvalidType)
  1621. & (clsI # SymTab.ClInt)
  1622. & (clsI # SymTab.ClChar)
  1623. & (clsI # SymTab.ClEnum)
  1624. & (clsI
  1625. # SymTab.ClBool) THEN
  1626. SemError(218);
  1627. t := SymTab.InvalidType;
  1628. MGen.Drop;
  1629. IF doLoad THEN
  1630. MGen.Drop; MGen.PushInt(0)
  1631. ELSE
  1632. IF ~firstT THEN
  1633. ELSE MGen.Drop
  1634. END
  1635. END
  1636. ELSE
  1637. loA := SymTab.ArrayLo(t);
  1638. elemT := SymTab.ArrayElem(t);
  1639. esl := SymTab.TypeSlots(elemT);
  1640. IF esl = 0 THEN
  1641. SemError(230);
  1642. esl := 1
  1643. END;
  1644. IF (SymTab.ClassOf(elemT)
  1645. = SymTab.ClChar)
  1646. OR (SymTab.ClassOf(elemT)
  1647. = SymTab.ClBool) THEN
  1648. ebytes := 1
  1649. ELSE ebytes := esl * 8
  1650. END;
  1651. MGen.IdxScale(loA, ebytes);
  1652. t := elemT
  1653. END
  1654. END; .)
  1655. { ","
  1656. Expr<it, lxI, vI, vnI> (. IF t = SymTab.InvalidType THEN
  1657. MGen.Drop;
  1658. IF doLoad THEN
  1659. MGen.Drop; MGen.PushInt(0);
  1660. t := SymTab.InvalidType
  1661. END
  1662. ELSIF SymTab.ClassOf(t) #
  1663. SymTab.ClArray THEN
  1664. SemError(217);
  1665. t := SymTab.InvalidType;
  1666. MGen.Drop;
  1667. IF doLoad THEN
  1668. MGen.Drop; MGen.PushInt(0)
  1669. END
  1670. ELSE
  1671. clsI := SymTab.ClassOf(it);
  1672. IF (it
  1673. # SymTab.InvalidType)
  1674. & (clsI # SymTab.ClInt)
  1675. & (clsI # SymTab.ClChar)
  1676. & (clsI # SymTab.ClEnum)
  1677. & (clsI
  1678. # SymTab.ClBool) THEN
  1679. SemError(218);
  1680. t := SymTab.InvalidType;
  1681. MGen.Drop;
  1682. IF doLoad THEN
  1683. MGen.Drop; MGen.PushInt(0)
  1684. END
  1685. ELSE
  1686. loA := SymTab.ArrayLo(t);
  1687. elemT := SymTab.ArrayElem(t);
  1688. esl := SymTab.TypeSlots(elemT);
  1689. IF esl = 0 THEN
  1690. SemError(230);
  1691. esl := 1
  1692. END;
  1693. IF (SymTab.ClassOf(elemT)
  1694. = SymTab.ClChar)
  1695. OR (SymTab.ClassOf(elemT)
  1696. = SymTab.ClBool) THEN
  1697. ebytes := 1
  1698. ELSE ebytes := esl * 8
  1699. END;
  1700. MGen.IdxScale(loA, ebytes);
  1701. t := elemT
  1702. END
  1703. END; .) }
  1704. "]"
  1705. | "^" (. firstT := ~sfx;
  1706. sfx := TRUE; lx[0] := 0C;
  1707. IF ~doLoad & firstT THEN
  1708. IF (k = SymTab.KindVar)
  1709. OR (k = SymTab.KindParam)
  1710. OR (k
  1711. = SymTab.KindVarPar) THEN
  1712. MGen.PushAddr(bn)
  1713. ELSIF k
  1714. = SymTab.KindField THEN
  1715. MGen.WithAddr(bn)
  1716. ELSE MGen.PushInt(0)
  1717. END
  1718. END; .)
  1719. (. IF t = SymTab.InvalidType THEN
  1720. IF doLoad THEN
  1721. MGen.Drop; MGen.PushInt(0)
  1722. ELSIF firstT THEN
  1723. MGen.Drop
  1724. END
  1725. ELSIF SymTab.ClassOf(t) #
  1726. SymTab.ClPtr THEN
  1727. SemError(219);
  1728. t := SymTab.InvalidType;
  1729. IF doLoad THEN
  1730. MGen.Drop; MGen.PushInt(0)
  1731. ELSIF firstT THEN
  1732. MGen.Drop
  1733. END
  1734. ELSE
  1735. elemT := SymTab.PtrBase(t);
  1736. t := elemT;
  1737. IF doLoad THEN
  1738. IF ~(firstT
  1739. & ((k
  1740. = SymTab.KindVar)
  1741. OR (k
  1742. = SymTab.KindParam)
  1743. OR (k
  1744. = SymTab.KindVarPar)))
  1745. THEN
  1746. MGen.LoadIndir
  1747. END
  1748. ELSE
  1749. MGen.LoadIndir
  1750. END
  1751. END; .) } .
  1752. Expr <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
  1753. VAR v: BOOLEAN; VAR vn: SymTab.Name>
  1754. (. VAR t2: SymTab.TypeIndex;
  1755. tc, op: INTEGER;
  1756. lx2: MGen.LitStr;
  1757. v2: BOOLEAN;
  1758. vn2: SymTab.Name;
  1759. r: BOOLEAN; .)
  1760. = SimExpr<t, lx, v, vn> [ Rel<op> SimExpr<t2, lx2, v2, vn2>
  1761. (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
  1762. IF op = SymTab.OpIn THEN
  1763. IF SymTab.InCheck(t, t2) THEN
  1764. t := SymTab.BoolType();
  1765. MGen.BitIn
  1766. ELSE SemError(222);
  1767. t := SymTab.InvalidType;
  1768. MGen.Drop; MGen.Drop; MGen.PushInt(0)
  1769. END
  1770. ELSIF (t # SymTab.InvalidType)
  1771. & (t2 # SymTab.InvalidType)
  1772. & (SymTab.ClassOf(t) = SymTab.ClArray)
  1773. & (SymTab.ClassOf(t2) = SymTab.ClArray)
  1774. & (SymTab.ClassOf(SymTab.ArrayElem(t)) = SymTab.ClChar)
  1775. & (SymTab.ClassOf(SymTab.ArrayElem(t2)) = SymTab.ClChar)
  1776. & ~SymTab.IsOpen(t) & ~SymTab.IsOpen(t2) THEN
  1777. t := SymTab.BoolType();
  1778. MGen.PushBytes(SymTab.TypeSlots(t) * 8);
  1779. MGen.PushBytes(SymTab.TypeSlots(t2) * 8);
  1780. MGen.StrComp;
  1781. IF op = SymTab.OpEq THEN MGen.Or; MGen.Not
  1782. ELSIF (op = SymTab.OpNeq1)
  1783. OR (op = SymTab.OpNeq2) THEN MGen.Or
  1784. ELSIF op = SymTab.OpLt THEN
  1785. MGen.Swap; MGen.Drop
  1786. ELSIF op = SymTab.OpLe THEN
  1787. MGen.Drop; MGen.Not
  1788. ELSIF op = SymTab.OpGt THEN
  1789. MGen.Drop
  1790. ELSE
  1791. MGen.Swap; MGen.Drop; MGen.Not
  1792. END
  1793. ELSIF (t # SymTab.InvalidType)
  1794. & (t2 # SymTab.InvalidType)
  1795. & ((SymTab.ClassOf(t) = SymTab.ClArray)
  1796. OR (SymTab.ClassOf(t) = SymTab.ClRecord)
  1797. OR (SymTab.ClassOf(t2) = SymTab.ClArray)
  1798. OR (SymTab.ClassOf(t2) = SymTab.ClRecord)) THEN
  1799. SemError(213); t := SymTab.InvalidType;
  1800. MGen.Drop; MGen.Drop; MGen.PushInt(0)
  1801. ELSE
  1802. tc := SymTab.ClassOf(t);
  1803. IF SymTab.RelCheck(t, t2, op) THEN
  1804. t := SymTab.BoolType()
  1805. ELSE SemError(213); t := SymTab.InvalidType END;
  1806. IF t # SymTab.InvalidType THEN
  1807. r := tc = SymTab.ClReal;
  1808. IF r THEN
  1809. IF op = SymTab.OpEq THEN MGen.RealEq
  1810. ELSIF (op = SymTab.OpNeq1)
  1811. OR (op = SymTab.OpNeq2) THEN MGen.RealNe
  1812. ELSIF op = SymTab.OpLt THEN MGen.RealLt
  1813. ELSIF op = SymTab.OpLe THEN MGen.RealLe
  1814. ELSIF op = SymTab.OpGt THEN MGen.RealGt
  1815. ELSE MGen.RealGe END
  1816. ELSE
  1817. IF op = SymTab.OpEq THEN MGen.Eq
  1818. ELSIF (op = SymTab.OpNeq1)
  1819. OR (op = SymTab.OpNeq2) THEN MGen.Neq
  1820. ELSIF op = SymTab.OpLt THEN MGen.ILt
  1821. ELSIF op = SymTab.OpLe THEN MGen.ILe
  1822. ELSIF op = SymTab.OpGt THEN MGen.IGt
  1823. ELSE MGen.IGe END
  1824. END
  1825. ELSE MGen.Drop; MGen.Drop; MGen.PushInt(0)
  1826. END
  1827. END; .) ] .
  1828. Rel <VAR op: INTEGER>
  1829. = "=" (. op := SymTab.OpEq; .)
  1830. | "#" (. op := SymTab.OpNeq1; .)
  1831. | "<>" (. op := SymTab.OpNeq2; .)
  1832. | "<" (. op := SymTab.OpLt; .)
  1833. | "<=" (. op := SymTab.OpLe; .)
  1834. | ">" (. op := SymTab.OpGt; .)
  1835. | ">=" (. op := SymTab.OpGe; .)
  1836. | "IN" (. op := SymTab.OpIn; .) .
  1837. SimExpr <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
  1838. VAR v: BOOLEAN; VAR vn: SymTab.Name>
  1839. (. VAR t2, res2: SymTab.TypeIndex;
  1840. op: INTEGER;
  1841. lx2: MGen.LitStr;
  1842. v2: BOOLEAN;
  1843. vn2: SymTab.Name;
  1844. neg, isR: BOOLEAN; .)
  1845. = (. neg := FALSE; .)
  1846. [ "+" | "-" (. neg := TRUE; .) ]
  1847. Term<t, lx, v, vn> (. IF neg THEN
  1848. v := FALSE;
  1849. MGen.ClrStash();
  1850. IF MGen.IsLit(lx) THEN
  1851. MGen.NegFold(lx, lx)
  1852. ELSE lx[0] := 0C
  1853. END;
  1854. IF SymTab.ClassOf(t)
  1855. = SymTab.ClReal THEN
  1856. MGen.NegReal
  1857. ELSE MGen.NegInt
  1858. END
  1859. END; .)
  1860. { AddOp<op> Term<t2, lx2, v2, vn2>
  1861. (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
  1862. IF op = SymTab.OpOr THEN
  1863. IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
  1864. t := SymTab.BoolType()
  1865. ELSE SemError(212); t := SymTab.InvalidType END;
  1866. MGen.Or
  1867. ELSIF (t # SymTab.InvalidType)
  1868. & (t2 # SymTab.InvalidType)
  1869. & (SymTab.ClassOf(t) = SymTab.ClSet)
  1870. & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
  1871. IF op = SymTab.OpAdd THEN
  1872. MGen.Or
  1873. ELSE
  1874. MGen.PushBits(0FFFFFFFFFFFFFFFFH);
  1875. MGen.BitXor;
  1876. MGen.And
  1877. END
  1878. ELSE
  1879. IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN t := res2
  1880. ELSE SemError(211); t := SymTab.InvalidType END;
  1881. isR := (t # SymTab.InvalidType)
  1882. & (SymTab.ClassOf(t) = SymTab.ClReal);
  1883. IF op = SymTab.OpAdd THEN
  1884. IF isR THEN MGen.RealAdd ELSE MGen.Add END
  1885. ELSE
  1886. IF isR THEN MGen.RealSub ELSE MGen.Sub END
  1887. END
  1888. END; .) } .
  1889. AddOp <VAR op: INTEGER>
  1890. = "+" (. op := SymTab.OpAdd; .)
  1891. | "-" (. op := SymTab.OpSub; .)
  1892. | "OR" (. op := SymTab.OpOr; .) .
  1893. Term <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
  1894. VAR v: BOOLEAN; VAR vn: SymTab.Name>
  1895. (. VAR t2, res2: SymTab.TypeIndex;
  1896. op: INTEGER;
  1897. lx2: MGen.LitStr;
  1898. v2: BOOLEAN;
  1899. vn2: SymTab.Name;
  1900. isR: BOOLEAN;
  1901. mt: INTEGER; .)
  1902. = Fact<t, lx, v, vn> { MulOp<op> Fact<t2, lx2, v2, vn2>
  1903. (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
  1904. IF op = SymTab.OpAnd THEN
  1905. IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
  1906. t := SymTab.BoolType()
  1907. ELSE SemError(212); t := SymTab.InvalidType END;
  1908. MGen.And
  1909. ELSIF (op = SymTab.OpTimes)
  1910. & (t # SymTab.InvalidType)
  1911. & (t2 # SymTab.InvalidType)
  1912. & (SymTab.ClassOf(t) = SymTab.ClSet)
  1913. & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
  1914. MGen.And
  1915. ELSE
  1916. IF SymTab.ArithCheck(t, t2,
  1917. (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
  1918. res2) THEN t := res2
  1919. ELSE SemError(211); t := SymTab.InvalidType END;
  1920. isR := (t # SymTab.InvalidType)
  1921. & (SymTab.ClassOf(t) = SymTab.ClReal);
  1922. IF op = SymTab.OpTimes THEN
  1923. IF isR THEN MGen.RealMul ELSE MGen.MulU END
  1924. ELSIF op = SymTab.OpSlash THEN
  1925. IF isR THEN MGen.RealDiv ELSE MGen.DivI END
  1926. ELSIF op = SymTab.OpDiv THEN
  1927. MGen.DivI
  1928. ELSE
  1929. mt := MGen.TempGlobal();
  1930. MGen.ModI(mt)
  1931. END
  1932. END; .) } .
  1933. MulOp <VAR op: INTEGER>
  1934. = "*" (. op := SymTab.OpTimes; .)
  1935. | "/" (. op := SymTab.OpSlash; .)
  1936. | "DIV" (. op := SymTab.OpDiv; .)
  1937. | "MOD" (. op := SymTab.OpMod; .)
  1938. | "AND" (. op := SymTab.OpAnd; .)
  1939. | "&" (. op := SymTab.OpAnd; .) .
  1940. Fact <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
  1941. VAR v: BOOLEAN; VAR vn: SymTab.Name>
  1942. (. VAR s: ARRAY [0 .. 255] OF CHAR;
  1943. t2, et, dt, st: SymTab.TypeIndex;
  1944. dk: INTEGER;
  1945. bnF: SymTab.Name;
  1946. lxD, lx2: MGen.LitStr;
  1947. v2: BOOLEAN;
  1948. vn2: SymTab.Name;
  1949. vi, mpF: INTEGER;
  1950. c: CARDINAL;
  1951. b: LONGCARD;
  1952. sfxF: BOOLEAN;
  1953. okF: BOOLEAN; .)
  1954. = integer (. LexString(s);
  1955. MGen.CopyName(s, lx);
  1956. v := FALSE; MGen.ClrStash();
  1957. IF MGen.ParseInt(s, vi) THEN
  1958. MGen.PushInt(vi)
  1959. ELSIF MGen.ParseCard(s, c) THEN
  1960. MGen.PushBits(
  1961. VAL(LONGCARD, c))
  1962. ELSE MGen.PushInt(0)
  1963. END;
  1964. t := SymTab.IntType(); .)
  1965. | real (. LexString(s);
  1966. MGen.CopyName(s, lx);
  1967. v := FALSE; MGen.ClrStash();
  1968. IF MGen.ParseReal(s, b) THEN
  1969. MGen.PushBits(b)
  1970. ELSE MGen.PushBits(0H)
  1971. END;
  1972. t := SymTab.RealType(); .)
  1973. | string (. LexString(s);
  1974. v := FALSE; MGen.ClrStash();
  1975. IF SymTab.StrLen(s) <= 3 THEN
  1976. t := SymTab.CharType();
  1977. MGen.CopyName(s, lx);
  1978. MGen.PushInt(
  1979. MGen.CharOrd(s))
  1980. ELSE t := SymTab.NewStr();
  1981. MGen.CopyName(s, lx);
  1982. MGen.EmitString(s)
  1983. END; .)
  1984. | "HIGH"
  1985. "(" DesignHead<dt, dk, bnF, FALSE, lxD>
  1986. DesignTail<dt, dk, bnF, FALSE, lxD, sfxF>
  1987. ")" (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
  1988. IF dt = SymTab.InvalidType THEN
  1989. IF sfxF THEN MGen.Drop END;
  1990. MGen.PushInt(0);
  1991. t := SymTab.InvalidType
  1992. ELSIF SymTab.ClassOf(dt)
  1993. # SymTab.ClArray THEN
  1994. SemError(217);
  1995. IF sfxF THEN MGen.Drop END;
  1996. MGen.PushInt(0);
  1997. t := SymTab.InvalidType
  1998. ELSIF SymTab.IsOpen(dt) THEN
  1999. IF sfxF THEN MGen.Drop END;
  2000. IF (dk = SymTab.KindParam)
  2001. OR (dk
  2002. = SymTab.KindVarPar) THEN
  2003. IF SymTab.CurDepth()
  2004. = SymTab.SymDepth(bnF) THEN
  2005. MGen.LoadLocal(
  2006. SymTab.SymSlot(bnF) + 1)
  2007. ELSE
  2008. MGen.FrameAddr(
  2009. SymTab.SymSlot(bnF) + 1,
  2010. VAL(CARDINAL,
  2011. SymTab.CurDepth() - 1
  2012. - SymTab.SymDepth(bnF)));
  2013. MGen.LoadIndir
  2014. END;
  2015. MGen.PushInt(1);
  2016. MGen.Sub;
  2017. t := SymTab.IntType()
  2018. ELSE
  2019. MGen.PushInt(0);
  2020. t := SymTab.InvalidType
  2021. END
  2022. ELSE
  2023. IF sfxF THEN MGen.Drop END;
  2024. MGen.PushInt(
  2025. SymTab.ArrayHi(dt));
  2026. t := SymTab.IntType()
  2027. END; .)
  2028. | DesignHead<dt, dk, bnF, TRUE, lxD>
  2029. DesignTail<dt, dk, bnF, TRUE, lxD, sfxF>
  2030. (. t := dt;
  2031. MGen.CopyName(lxD, lx);
  2032. IF sfxF
  2033. & (t # SymTab.InvalidType)
  2034. & MGen.ActIsVarNext()
  2035. & ((dk = SymTab.KindVar)
  2036. OR (dk
  2037. = SymTab.KindParam)
  2038. OR (dk
  2039. = SymTab.KindVarPar)
  2040. OR (dk
  2041. = SymTab.KindField))
  2042. & (SymTab.SymKind(bnF)
  2043. # SymTab.KindModule)
  2044. & (SymTab.ClassOf(t)
  2045. # SymTab.ClChar)
  2046. & (SymTab.ClassOf(t)
  2047. # SymTab.ClBool) THEN
  2048. MGen.StashAddr()
  2049. END;
  2050. IF sfxF
  2051. & (t # SymTab.InvalidType)
  2052. & (SymTab.ClassOf(t)
  2053. # SymTab.ClArray)
  2054. & (SymTab.ClassOf(t)
  2055. # SymTab.ClRecord) THEN
  2056. IF (SymTab.ClassOf(t)
  2057. = SymTab.ClChar)
  2058. OR (SymTab.ClassOf(t)
  2059. = SymTab.ClBool) THEN
  2060. MGen.LoadByte
  2061. ELSE MGen.LoadIndir
  2062. END
  2063. END;
  2064. v := ~sfxF
  2065. & ((dk = SymTab.KindVar)
  2066. OR (dk = SymTab.KindParam)
  2067. OR (dk
  2068. = SymTab.KindVarPar));
  2069. MGen.CopyName(bnF, vn); .)
  2070. [ CallTail<bnF, lxD, sfxF, TRUE, okF, TRUE>
  2071. (. IF okF THEN
  2072. IF SymTab.SymKind(bnF)
  2073. = SymTab.KindProc THEN
  2074. t := SymTab.ProcRet(bnF)
  2075. ELSIF (SymTab.SymKind(bnF)
  2076. = SymTab.KindModule)
  2077. & sfxF
  2078. & (SymTab.StrLen(lxD) > 0) THEN
  2079. mpF := SymTab.ExpProc(bnF,
  2080. lxD);
  2081. IF (mpF < 0)
  2082. & (SymTab.SelfKind(bnF,
  2083. lxD)
  2084. = SymTab.KindProc) THEN
  2085. mpF := SymTab.ProcNum(lxD)
  2086. END;
  2087. IF mpF >= 0 THEN
  2088. t := SymTab.ProcRetByNum(mpF)
  2089. ELSE
  2090. t := SymTab.InvalidType
  2091. END
  2092. ELSE
  2093. t := SymTab.InvalidType
  2094. END
  2095. ELSE t := SymTab.InvalidType
  2096. END;
  2097. lx[0] := 0C; v := FALSE;
  2098. MGen.ClrStash(); .) ]
  2099. | "("
  2100. Expr<et, lx, v, vn> ")" (. t := et; .)
  2101. | ( "NOT" | "~" )
  2102. Fact<t2, lx2, v2, vn2> (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
  2103. IF SymTab.BoolCheck(t2) THEN
  2104. t := SymTab.BoolType()
  2105. ELSE SemError(212);
  2106. t := SymTab.InvalidType END;
  2107. MGen.Not; .)
  2108. | SetLit<st> (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
  2109. t := st; .) .
  2110. SetLit <VAR t: SymTab.TypeIndex>
  2111. (. VAR first, et: SymTab.TypeIndex;
  2112. lxE, lxE2: MGen.LitStr;
  2113. vE, vE2: BOOLEAN;
  2114. vnE, vnE2: SymTab.Name;
  2115. hasR: BOOLEAN; .)
  2116. = "{"
  2117. (. MGen.PushInt(0);
  2118. t := SymTab.SetFor(SymTab.IntType()); .)
  2119. [ Elem<et, lxE, lxE2, hasR> (. first := et;
  2120. t := SymTab.SetFor(et);
  2121. MGen.ClrStash();
  2122. IF hasR THEN
  2123. MGen.PushInt(1); MGen.Add;
  2124. MGen.FieldMask
  2125. ELSE MGen.Power2 END;
  2126. MGen.Or; .)
  2127. { ","
  2128. Elem<et, lxE, lxE2, hasR> (. IF ~SymTab.SetElemCheck(first, et) THEN
  2129. SemError(222) END;
  2130. MGen.ClrStash();
  2131. IF hasR THEN
  2132. MGen.PushInt(1); MGen.Add;
  2133. MGen.FieldMask
  2134. ELSE MGen.Power2 END;
  2135. MGen.Or; .) } ]
  2136. "}" .
  2137. Elem <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
  2138. VAR lx2: MGen.LitStr; VAR hasR: BOOLEAN>
  2139. (. VAR t2: SymTab.TypeIndex;
  2140. vD, vD2: BOOLEAN;
  2141. vnD, vnD2: SymTab.Name; .)
  2142. = Expr<t, lx, vD, vnD> (. hasR := FALSE;
  2143. lx2[0] := 0C; .)
  2144. [ ".."
  2145. Expr<t2, lx2, vD2, vnD2> (. IF ~SymTab.SetElemCheck(t, t2) THEN
  2146. SemError(222) END;
  2147. hasR := TRUE; .) ] .
  2148. GetIdent <VAR n: SymTab.Name>
  2149. = ident (. LexName(n); .) .
  2150. END M2c.