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