M2c.lst 132 KB

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