M2c.lst 121 KB

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