M2c.lst 149 KB

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