|
@@ -457,1881 +457,1899 @@ Listing:
|
|
|
440 ELSE t := SymTab.NewSubR(lo, hi)
|
|
440 ELSE t := SymTab.NewSubR(lo, hi)
|
|
|
441 END; .)
|
|
441 END; .)
|
|
|
442 "]" .
|
|
442 "]" .
|
|
|
- 443 Enum<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 444 = "(" (. t := SymTab.NewEnum(); .)
|
|
|
|
|
- 445 GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 446 SymTab.KindConst) THEN
|
|
|
|
|
- 447 SemError(200) END;
|
|
|
|
|
- 448 SymTab.SetSymType(n, t); .)
|
|
|
|
|
- 449 { "," GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 450 SymTab.KindConst) THEN
|
|
|
|
|
- 451 SemError(200) END;
|
|
|
|
|
- 452 SymTab.SetSymType(n, t); .) }
|
|
|
|
|
- 453 ")" .
|
|
|
|
|
- 454 (* Clarion-form classes (docs/OOP.txt): declaration + single
|
|
|
|
|
- 455 inheritance + IMPLEMENTATION blocks. Scopes and member checks
|
|
|
|
|
- 456 now; lowering (vtable, dispatch, THIS) later — one 230 per
|
|
|
|
|
- 457 class/impl block. Methods end with ";" per the Table example
|
|
|
|
|
- 458 (not "," as in the sketch). No underscores in identifiers. *)
|
|
|
|
|
- 459 (* Single CLASS item in both loops: separating declaration from
|
|
|
|
|
- 460 IMPLEMENTATION at the loop level needs 2-token lookahead
|
|
|
|
|
- 461 (CLASS ident vs CLASS IMPLEMENTATION), which LL(1) cannot do.
|
|
|
|
|
- 462 The second token decides after CLASS is consumed. A misplaced
|
|
|
|
|
- 463 CLASS IMPLEMENTATION inside TYPE still parses (harmless: the
|
|
|
|
|
- 464 whole unit ends 230 until lowering). *)
|
|
|
|
|
- 465 ClassItem
|
|
|
|
|
- 466 = "CLASS" ( "IMPLEMENTATION" ClassImplRest | ClassRest ) .
|
|
|
|
|
- 467 ClassRest (. VAR cn, m2, pn: SymTab.Name;
|
|
|
|
|
- 468 ct: SymTab.TypeIndex; .)
|
|
|
|
|
- 469 = GetIdent<cn> (. IF NOT SymTab.Enter(cn,
|
|
|
|
|
- 470 SymTab.KindType) THEN
|
|
|
|
|
- 471 SemError(200) END;
|
|
|
|
|
- 472 ct := SymTab.NewClass();
|
|
|
|
|
- 473 SymTab.SetSymType(cn, ct);
|
|
|
|
|
- 474 SymTab.PushClassScope(ct); .)
|
|
|
|
|
- 475 [ Parents<ct> ]
|
|
|
|
|
- 476 ";"
|
|
|
|
|
- 477 { ClassField<ct> ";" }
|
|
|
|
|
- 478 { MethodHeading<pn> ";" (. SymTab.CloseProc;
|
|
|
|
|
- 479 QbeGen.AbortFunc; .) }
|
|
|
|
|
- 480 "END"
|
|
|
|
|
- 481 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
- 482 SemError(202) END;
|
|
|
|
|
- 483 SymTab.PopScope;
|
|
|
|
|
- 484 SemError(230); .) .
|
|
|
|
|
- 485 Parents<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name; .)
|
|
|
|
|
- 486 = "(" Parent1<ct>
|
|
|
|
|
- 487 { "," GetIdent<p> (. SemError(230); .) }
|
|
|
|
|
- 488 ")" .
|
|
|
|
|
- 489 Parent1<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name;
|
|
|
|
|
- 490 pt: SymTab.TypeIndex; .)
|
|
|
|
|
- 491 = GetIdent<p> (. IF NOT SymTab.Lookup(p) THEN
|
|
|
|
|
- 492 SemError(201)
|
|
|
|
|
- 493 ELSE pt := SymTab.SymType(p);
|
|
|
|
|
- 494 IF SymTab.ClassOf(pt) #
|
|
|
|
|
- 495 SymTab.ClClass THEN
|
|
|
|
|
- 496 SemError(230)
|
|
|
|
|
- 497 ELSE SymTab.SetParent(ct, pt)
|
|
|
|
|
- 498 END
|
|
|
|
|
- 499 END; .) .
|
|
|
|
|
- 500 ClassField<ct: SymTab.TypeIndex> (. VAR n, rhs: SymTab.Name;
|
|
|
|
|
- 501 t: SymTab.TypeIndex; .)
|
|
|
|
|
- 502 = GetIdent<n>
|
|
|
|
|
- 503 ( "=" GetIdent<rhs> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 504 SymTab.KindConst) THEN
|
|
|
|
|
- 505 SemError(200) END;
|
|
|
|
|
- 506 IF SymTab.Lookup(rhs) THEN
|
|
|
|
|
- 507 SymTab.SetSymType(n,
|
|
|
|
|
- 508 SymTab.SymType(rhs))
|
|
|
|
|
- 509 END; .)
|
|
|
|
|
- 510 | (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
- 511 n) THEN
|
|
|
|
|
- 512 SemError(200) END; .)
|
|
|
|
|
- 513 { "," GetIdent<n> (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
- 514 n) THEN
|
|
|
|
|
- 515 SemError(200) END; .) }
|
|
|
|
|
- 516 ":" Type<t, FALSE> (. SymTab.FixPendingF(ct, t); .) ) .
|
|
|
|
|
- 517 MethodHeading<VAR pn: SymTab.Name> (. VAR wantVirt: BOOLEAN; .)
|
|
|
|
|
- 518 = (. wantVirt := FALSE; .)
|
|
|
|
|
- 519 [ "VIRTUAL" (. wantVirt := TRUE; .) ]
|
|
|
|
|
- 520 ProcHeading<pn> (. IF wantVirt THEN
|
|
|
|
|
- 521 SymTab.MarkVirtual END; .) .
|
|
|
|
|
- 522 ClassImplRest (. VAR cn, m2: SymTab.Name;
|
|
|
|
|
- 523 ct: SymTab.TypeIndex; .)
|
|
|
|
|
- 524 = GetIdent<cn> (. IF NOT SymTab.Lookup(cn) THEN
|
|
|
|
|
- 525 SemError(201);
|
|
|
|
|
- 526 ct := SymTab.InvalidType
|
|
|
|
|
- 527 ELSE ct := SymTab.SymType(cn);
|
|
|
|
|
- 528 IF SymTab.ClassOf(ct) #
|
|
|
|
|
- 529 SymTab.ClClass THEN
|
|
|
|
|
- 530 SemError(230);
|
|
|
|
|
- 531 ct := SymTab.InvalidType
|
|
|
|
|
- 532 END
|
|
|
|
|
- 533 END;
|
|
|
|
|
- 534 IF ct #
|
|
|
|
|
- 535 SymTab.InvalidType THEN
|
|
|
|
|
- 536 IF NOT SymTab.PushClassMembers(
|
|
|
|
|
- 537 ct) THEN
|
|
|
|
|
- 538 SemError(230) END
|
|
|
|
|
- 539 END; .)
|
|
|
|
|
- 540 ";" { MethodImpl<ct> ";" }
|
|
|
|
|
- 541 [ "BEGIN"
|
|
|
|
|
- 542 [ StatSeq ] ]
|
|
|
|
|
- 543 "END"
|
|
|
|
|
- 544 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
- 545 SemError(202) END;
|
|
|
|
|
- 546 SymTab.PopScope;
|
|
|
|
|
- 547 SemError(230); .) .
|
|
|
|
|
- 548 MethodImpl<ct: SymTab.TypeIndex> (. VAR pn: SymTab.Name; .)
|
|
|
|
|
- 549 = (. QbeGen.SetNoEmit(TRUE); .)
|
|
|
|
|
- 550 MethodHeading<pn> ";"
|
|
|
|
|
- 551 (. IF (ct #
|
|
|
|
|
- 552 SymTab.InvalidType)
|
|
|
|
|
- 553 AND NOT SymTab.MethodExists(ct,
|
|
|
|
|
- 554 pn) THEN
|
|
|
|
|
- 555 SemError(201) END; .)
|
|
|
|
|
- 556 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
- 557 SymTab.CloseProc; .)
|
|
|
|
|
- 558 | Block<pn> (. SymTab.CloseProc; .) )
|
|
|
|
|
- 559 (. QbeGen.AbortFunc;
|
|
|
|
|
- 560 QbeGen.SetNoEmit(FALSE);
|
|
|
|
|
- 561 SemError(230); .) .
|
|
|
|
|
- 562 ConstBlock
|
|
|
|
|
- 563 = "CONST" { ConstDecl ";" } .
|
|
|
|
|
- 564 ConstDecl (. VAR n: SymTab.Name;
|
|
|
|
|
- 565 t: SymTab.TypeIndex;
|
|
|
|
|
- 566 qv: QbeGen.QVal;
|
|
|
|
|
- 567 cls: INTEGER; .)
|
|
|
|
|
- 568 = GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 569 SymTab.KindConst) THEN
|
|
|
|
|
- 570 SemError(200) END; .)
|
|
|
|
|
- 571 "="
|
|
|
|
|
- 572 Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
|
|
- 573 cls := SymTab.ClassOf(t);
|
|
|
|
|
- 574 IF cls = SymTab.ClStr THEN
|
|
|
|
|
- 575 SemError(230)
|
|
|
|
|
- 576 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
|
|
- 577 SemError(230) END;
|
|
|
|
|
- 578 SymTab.SetSymVal(n, qv);
|
|
|
|
|
- 579 QbeGen.DeclConst(n, qv, t); .) .
|
|
|
|
|
- 580 VarBlock
|
|
|
|
|
- 581 = "VAR" { VarDecl ";" } .
|
|
|
|
|
- 582 VarDecl (. VAR nm: SymTab.Name;
|
|
|
|
|
- 583 t: SymTab.TypeIndex;
|
|
|
|
|
- 584 i: CARDINAL;
|
|
|
|
|
- 585 cls: INTEGER; .)
|
|
|
|
|
- 586 = VarIdents ":"
|
|
|
|
|
- 587 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
|
|
- 588 IF (t # SymTab.InvalidType)
|
|
|
|
|
- 589 AND (cls # SymTab.ClInt)
|
|
|
|
|
- 590 AND (cls # SymTab.ClBool)
|
|
|
|
|
- 591 AND (cls # SymTab.ClChar)
|
|
|
|
|
- 592 AND (cls # SymTab.ClReal)
|
|
|
|
|
- 593 AND (cls # SymTab.ClArray)
|
|
|
|
|
- 594 AND (cls # SymTab.ClSet)
|
|
|
|
|
- 595 AND (cls # SymTab.ClRecord)
|
|
|
|
|
- 596 AND (cls # SymTab.ClPtr)
|
|
|
|
|
- 597 AND (cls # SymTab.ClLong)
|
|
|
|
|
- 598 AND (cls # SymTab.ClProc)
|
|
|
|
|
- 599 AND (cls # SymTab.ClUChar)
|
|
|
|
|
- 600 AND (cls # SymTab.ClUStr) THEN
|
|
|
|
|
- 601 SemError(230) END;
|
|
|
|
|
- 602 IF QbeGen.LocFull() THEN
|
|
|
|
|
- 603 SemError(233) END;
|
|
|
|
|
- 604 i := 0;
|
|
|
|
|
- 605 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
- 606 SymTab.PendName(i, nm);
|
|
|
|
|
- 607 QbeGen.DeclVar(nm, t);
|
|
|
|
|
- 608 INC(i)
|
|
|
|
|
- 609 END;
|
|
|
|
|
- 610 SymTab.FixPending(t); .) .
|
|
|
|
|
- 611 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 612 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
- 613 SymTab.KindVar) THEN
|
|
|
|
|
- 614 SemError(200) END; .)
|
|
|
|
|
- 615 { ","
|
|
|
|
|
- 616 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
- 617 SymTab.KindVar) THEN
|
|
|
|
|
- 618 SemError(200) END; .) } .
|
|
|
|
|
- 619 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 620 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
- 621 SemError(200) END; .)
|
|
|
|
|
- 622 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
- 623 SemError(200) END; .) } .
|
|
|
|
|
- 624 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
|
|
- 625 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
|
|
- 626 FORWARD marks; the body heading re-enters (signature compare
|
|
|
|
|
- 627 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
|
|
- 628 ProcHeading<VAR pn: SymTab.Name> (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 629 mg: QbeGen.QVal; .)
|
|
|
|
|
- 630 = "PROCEDURE"
|
|
|
|
|
- 631 GetIdent<pn> (. IF NOT SymTab.EnterProc(pn) THEN
|
|
|
|
|
- 632 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
|
|
- 633 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
|
|
- 634 SemError(200) END
|
|
|
|
|
- 635 END
|
|
|
|
|
- 636 END;
|
|
|
|
|
- 637 QbeGen.Mangled(pn,
|
|
|
|
|
- 638 SymTab.ProcUid(pn), mg);
|
|
|
|
|
- 639 QbeGen.BeginFunc(mg); .)
|
|
|
|
|
- 640 [ FormalParams ]
|
|
|
|
|
- 641 [ ":" TypeIdent<t> (. SymTab.SetProcRes(t);
|
|
|
|
|
- 642 QbeGen.SetFuncRes(t);
|
|
|
|
|
- 643 IF (t #
|
|
|
|
|
- 644 SymTab.InvalidType)
|
|
|
|
|
- 645 AND ((SymTab.ClassOf(t)
|
|
|
|
|
- 646 = SymTab.ClArray)
|
|
|
|
|
- 647 OR (SymTab.ClassOf(t)
|
|
|
|
|
- 648 = SymTab.ClRecord)
|
|
|
|
|
- 649 OR (SymTab.ClassOf(t)
|
|
|
|
|
- 650 = SymTab.ClSet)
|
|
|
|
|
- 651 OR (SymTab.ClassOf(t)
|
|
|
|
|
- 652 = SymTab.ClClass)) THEN
|
|
|
|
|
- 653 SemError(230) END; .) ] .
|
|
|
|
|
- 654 FormalParams
|
|
|
|
|
- 655 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
|
|
- 656 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 657 nm: SymTab.Name;
|
|
|
|
|
- 658 i: CARDINAL;
|
|
|
|
|
- 659 isV: BOOLEAN; .)
|
|
|
|
|
- 660 = (. isV := FALSE; .)
|
|
|
|
|
- 661 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
- 662 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
|
|
- 663 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
- 664 SymTab.PendName(i, nm);
|
|
|
|
|
- 665 (* value open arrays are
|
|
|
|
|
- 666 passed as descriptor
|
|
|
|
|
- 667 addresses (no copy):
|
|
|
|
|
- 668 same representation as
|
|
|
|
|
- 669 VAR formals *)
|
|
|
|
|
- 670 IF NOT QbeGen.FuncParam(nm,
|
|
|
|
|
- 671 isV
|
|
|
|
|
- 672 OR SymTab.IsOpenArray(t),
|
|
|
|
|
- 673 t) THEN
|
|
|
|
|
- 674 SemError(233) END;
|
|
|
|
|
- 675 INC(i)
|
|
|
|
|
- 676 END;
|
|
|
|
|
- 677 SymTab.FixPending(t); .) .
|
|
|
|
|
- 678 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
|
|
- 679 static link gives them their parent's frame. Methods keep
|
|
|
|
|
- 680 parse-now/230-later. *)
|
|
|
|
|
- 681 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
|
|
- 682 = ProcHeading<pn> ";"
|
|
|
|
|
- 683 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
- 684 SymTab.CloseProc;
|
|
|
|
|
- 685 QbeGen.AbortFunc; .)
|
|
|
|
|
- 686 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
|
|
- 687 SymTab.CloseProc;
|
|
|
|
|
- 688 QbeGen.AbortFunc; .)
|
|
|
|
|
- 689 | (. QbeGen.EndFuncHeader; .)
|
|
|
|
|
- 690 Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
- 691 QbeGen.EndFunc(
|
|
|
|
|
- 692 SymTab.ProcRes(pn)); .) ) .
|
|
|
|
|
- 693 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
|
|
- 694 = DeclSeq
|
|
|
|
|
- 695 [ "BEGIN"
|
|
|
|
|
- 696 [ StatSeq ] ]
|
|
|
|
|
- 697 "END"
|
|
|
|
|
- 698 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
|
|
- 699 SemError(202) END; .) .
|
|
|
|
|
- 700 StatSeq
|
|
|
|
|
- 701 = Statement { ";" [ Statement ] } .
|
|
|
|
|
- 702 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
|
|
- 703 are accepted: the statement after ';' is optional. *)
|
|
|
|
|
- 704 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
|
|
- 705 = AssOrCall
|
|
|
|
|
- 706 | IfStat
|
|
|
|
|
- 707 | WhileStat
|
|
|
|
|
- 708 | RepeatStat
|
|
|
|
|
- 709 | LoopStat
|
|
|
|
|
- 710 | ForStat
|
|
|
|
|
- 711 | CaseStat
|
|
|
|
|
- 712 | WithStat
|
|
|
|
|
- 713 | ReturnStat
|
|
|
|
|
- 714 | HaltStat
|
|
|
|
|
- 715 | NewStat
|
|
|
|
|
- 716 | DisposeStat
|
|
|
|
|
- 717 | IncDecStat
|
|
|
|
|
- 718 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
|
|
- 719 QbeGen.Jmp(lx)
|
|
|
|
|
- 720 ELSE SemError(230) END; .) .
|
|
|
|
|
- 721 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
|
|
- 722 integer designator. *)
|
|
|
|
|
- 723 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
|
|
- 724 dk: INTEGER;
|
|
|
|
|
- 725 qd, qv, qn2, qstep:
|
|
|
|
|
- 726 QbeGen.QVal;
|
|
|
|
|
- 727 qn: SymTab.Name;
|
|
|
|
|
- 728 sfx, isInc: BOOLEAN; .)
|
|
|
|
|
- 729 = (. isInc := TRUE; .)
|
|
|
|
|
- 730 ( "INC" (. isInc := TRUE; .)
|
|
|
|
|
- 731 | "DEC" (. isInc := FALSE; .) )
|
|
|
|
|
- 732 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
|
|
- 733 Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
- 734 [ "," Expr<et2, qstep> ]
|
|
|
|
|
- 735 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 736 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 737 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 738 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 739 SemError(210)
|
|
|
|
|
- 740 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
|
|
- 741 SemError(211)
|
|
|
|
|
- 742 ELSE
|
|
|
|
|
- 743 IF sfx
|
|
|
|
|
- 744 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
- 745 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
|
|
- 746 ELSE QbeGen.LoadVar(qn,
|
|
|
|
|
- 747 FALSE, qv)
|
|
|
|
|
- 748 END;
|
|
|
|
|
- 749 QbeGen.NewTemp(qn2);
|
|
|
|
|
- 750 IF isInc THEN
|
|
|
|
|
- 751 QbeGen.Op3("add", qn2, qv,
|
|
|
|
|
- 752 qstep, FALSE)
|
|
|
|
|
- 753 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
|
|
- 754 qstep, FALSE)
|
|
|
|
|
- 755 END;
|
|
|
|
|
- 756 IF sfx
|
|
|
|
|
- 757 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
- 758 QbeGen.ElemStore(qd, qn2,
|
|
|
|
|
- 759 dt)
|
|
|
|
|
- 760 ELSE QbeGen.StoreVar(qn,
|
|
|
|
|
- 761 qn2, FALSE)
|
|
|
|
|
- 762 END
|
|
|
|
|
- 763 END; .) .
|
|
|
|
|
- 764 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
|
|
- 765 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
|
|
- 766 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
|
|
- 767 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 768 dk: INTEGER;
|
|
|
|
|
- 769 qd, qm: QbeGen.QVal;
|
|
|
|
|
- 770 qn: SymTab.Name;
|
|
|
|
|
- 771 sfx: BOOLEAN;
|
|
|
|
|
- 772 bt: SymTab.TypeIndex; .)
|
|
|
|
|
- 773 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 774 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 775 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 776 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 777 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 778 SemError(210)
|
|
|
|
|
- 779 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 780 SymTab.ClPtr THEN
|
|
|
|
|
- 781 SemError(219)
|
|
|
|
|
- 782 ELSE bt := SymTab.PtrBase(dt);
|
|
|
|
|
- 783 IF bt #
|
|
|
|
|
- 784 SymTab.InvalidType THEN
|
|
|
|
|
- 785 QbeGen.NewHeap(bt, qm);
|
|
|
|
|
- 786 QbeGen.InitHeap(qm, bt);
|
|
|
|
|
- 787 IF sfx
|
|
|
|
|
- 788 OR (dk =
|
|
|
|
|
- 789 SymTab.KindField) THEN
|
|
|
|
|
- 790 QbeGen.ElemStore(qd, qm,
|
|
|
|
|
- 791 dt)
|
|
|
|
|
- 792 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
- 793 qm)
|
|
|
|
|
- 794 END
|
|
|
|
|
- 795 END
|
|
|
|
|
- 796 END; .) .
|
|
|
|
|
- 797 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 798 dk: INTEGER;
|
|
|
|
|
- 799 qd, qv: QbeGen.QVal;
|
|
|
|
|
- 800 qn: SymTab.Name;
|
|
|
|
|
- 801 sfx: BOOLEAN; .)
|
|
|
|
|
- 802 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 803 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 804 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 805 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 806 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 807 SemError(210)
|
|
|
|
|
- 808 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 809 SymTab.ClPtr THEN
|
|
|
|
|
- 810 SemError(219)
|
|
|
|
|
- 811 ELSE
|
|
|
|
|
- 812 IF sfx
|
|
|
|
|
- 813 OR (dk =
|
|
|
|
|
- 814 SymTab.KindField) THEN
|
|
|
|
|
- 815 QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
- 816 qv)
|
|
|
|
|
- 817 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
|
|
- 818 END;
|
|
|
|
|
- 819 QbeGen.FreeHeap(qv);
|
|
|
|
|
- 820 IF sfx
|
|
|
|
|
- 821 OR (dk =
|
|
|
|
|
- 822 SymTab.KindField) THEN
|
|
|
|
|
- 823 QbeGen.ElemStore(qd, "0",
|
|
|
|
|
- 824 dt)
|
|
|
|
|
- 825 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
- 826 "0")
|
|
|
|
|
- 827 END
|
|
|
|
|
- 828 END; .) .
|
|
|
|
|
- 829 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
|
|
- 830 address; field designators resolve through both stacks. *)
|
|
|
|
|
- 831 WithStat (. VAR nW: CARDINAL; .)
|
|
|
|
|
- 832 = "WITH" (. nW := 0; .)
|
|
|
|
|
- 833 WithItem<nW> { "," WithItem<nW> }
|
|
|
|
|
- 834 "DO" [ StatSeq ] "END"
|
|
|
|
|
- 835 (. WHILE nW > 0 DO
|
|
|
|
|
- 836 SymTab.PopScope;
|
|
|
|
|
- 837 QbeGen.PopWith;
|
|
|
|
|
- 838 DEC(nW)
|
|
|
|
|
- 839 END; .) .
|
|
|
|
|
- 840 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 841 dk: INTEGER;
|
|
|
|
|
- 842 qd, qe: QbeGen.QVal;
|
|
|
|
|
- 843 qn: SymTab.Name;
|
|
|
|
|
- 844 sfx: BOOLEAN; .)
|
|
|
|
|
- 845 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
- 846 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 847 ELSIF (SymTab.ClassOf(dt) #
|
|
|
|
|
- 848 SymTab.ClRecord)
|
|
|
|
|
- 849 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
- 850 SymTab.ClClass) THEN
|
|
|
|
|
- 851 SemError(215)
|
|
|
|
|
- 852 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
|
|
- 853 QbeGen.PushWith(qd);
|
|
|
|
|
- 854 INC(nW)
|
|
|
|
|
- 855 END; .) .
|
|
|
|
|
- 856 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
|
|
- 857 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
|
|
- 858 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
|
|
- 859 dk: INTEGER;
|
|
|
|
|
- 860 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
|
|
- 861 qn: SymTab.Name;
|
|
|
|
|
- 862 ct2, res0: SymTab.TypeIndex;
|
|
|
|
|
- 863 q2, mg0: QbeGen.QVal;
|
|
|
|
|
- 864 isR, conv, wconv: BOOLEAN;
|
|
|
|
|
- 865 called, sfx: BOOLEAN; .)
|
|
|
|
|
- 866 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
- 867 ( ":="
|
|
|
|
|
- 868 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 869 AND (dk # SymTab.KindVar)
|
|
|
|
|
- 870 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 871 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 872 SemError(210)
|
|
|
|
|
- 873 ELSIF NOT SymTab.Assignable(et,
|
|
|
|
|
- 874 dt) THEN
|
|
|
|
|
- 875 SemError(210)
|
|
|
|
|
- 876 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
- 877 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
- 878 SymTab.ClClass) THEN
|
|
|
|
|
- 879 SemError(230) END;
|
|
|
|
|
- 880 isR := (dt #
|
|
|
|
|
- 881 SymTab.InvalidType)
|
|
|
|
|
- 882 AND (SymTab.ClassOf(dt)
|
|
|
|
|
- 883 = SymTab.ClReal);
|
|
|
|
|
- 884 conv := isR
|
|
|
|
|
- 885 AND SymTab.IsIntFamily(et);
|
|
|
|
|
- 886 wconv := (dt #
|
|
|
|
|
- 887 SymTab.InvalidType)
|
|
|
|
|
- 888 AND SymTab.IsLongFamily(dt)
|
|
|
|
|
- 889 AND SymTab.IsIntFamily(et);
|
|
|
|
|
- 890 IF ((dk = SymTab.KindVar)
|
|
|
|
|
- 891 OR (dk = SymTab.KindParam)
|
|
|
|
|
- 892 OR (dk = SymTab.KindField))
|
|
|
|
|
- 893 AND (dt # SymTab.InvalidType)
|
|
|
|
|
- 894 AND (et # SymTab.InvalidType)
|
|
|
|
|
- 895 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
- 896 SymTab.ClClass) THEN
|
|
|
|
|
- 897 IF sfx
|
|
|
|
|
- 898 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
- 899 IF SymTab.ClassOf(dt) =
|
|
|
|
|
- 900 SymTab.ClArray THEN
|
|
|
|
|
- 901 QbeGen.CopyArray(qd, qe,
|
|
|
|
|
- 902 dt)
|
|
|
|
|
- 903 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 904 SymTab.ClSet THEN
|
|
|
|
|
- 905 QbeGen.CopySet(qd, qe,
|
|
|
|
|
- 906 SymTab.SetWords(dt),
|
|
|
|
|
- 907 SymTab.SetWords(et))
|
|
|
|
|
- 908 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 909 SymTab.ClRecord THEN
|
|
|
|
|
- 910 QbeGen.CopyRecord(qd, qe,
|
|
|
|
|
- 911 dt)
|
|
|
|
|
- 912 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
- 913 IF wconv THEN
|
|
|
|
|
- 914 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
- 915 QbeGen.ElemStore(qd, ql,
|
|
|
|
|
- 916 dt)
|
|
|
|
|
- 917 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
- 918 dt)
|
|
|
|
|
- 919 END
|
|
|
|
|
- 920 ELSIF conv THEN
|
|
|
|
|
- 921 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 922 QbeGen.ElemStore(qd, qt,
|
|
|
|
|
- 923 dt)
|
|
|
|
|
- 924 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
- 925 dt)
|
|
|
|
|
- 926 END
|
|
|
|
|
- 927 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 928 SymTab.ClArray THEN
|
|
|
|
|
- 929 QbeGen.CopyArray(qd, qe, dt)
|
|
|
|
|
- 930 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 931 SymTab.ClSet THEN
|
|
|
|
|
- 932 QbeGen.CopySet(qd, qe,
|
|
|
|
|
- 933 SymTab.SetWords(dt),
|
|
|
|
|
- 934 SymTab.SetWords(et))
|
|
|
|
|
- 935 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 936 SymTab.ClRecord THEN
|
|
|
|
|
- 937 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
|
|
- 938 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
- 939 SymTab.ClPtr)
|
|
|
|
|
- 940 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 941 SymTab.ClProc) THEN
|
|
|
|
|
- 942 QbeGen.StorePtr(qn, qe)
|
|
|
|
|
- 943 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
- 944 IF wconv THEN
|
|
|
|
|
- 945 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
- 946 QbeGen.StoreLong(qn, ql)
|
|
|
|
|
- 947 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
|
|
- 948 END
|
|
|
|
|
- 949 ELSIF conv THEN
|
|
|
|
|
- 950 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 951 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
|
|
- 952 ELSE
|
|
|
|
|
- 953 QbeGen.StoreVar(qn, qe, isR)
|
|
|
|
|
- 954 END
|
|
|
|
|
- 955 END; .)
|
|
|
|
|
- 956 | ArgList<qn, dt, qd, FALSE, ct2, q2, called>
|
|
|
|
|
- 957 | (* bare `P;`: proper parameterless
|
|
|
|
|
- 958 procedure call; anything else
|
|
|
|
|
- 959 here is 233 (was a bare syntax
|
|
|
|
|
- 960 error before 4.2) *)
|
|
|
|
|
- 961 (. IF (dk = SymTab.KindProc)
|
|
|
|
|
- 962 AND NOT sfx THEN
|
|
|
|
|
- 963 res0 := SymTab.ProcRes(qn);
|
|
|
|
|
- 964 IF res0 #
|
|
|
|
|
- 965 SymTab.InvalidType THEN
|
|
|
|
|
- 966 SemError(233)
|
|
|
|
|
- 967 ELSIF SymTab.ProcNPar(qn) #
|
|
|
|
|
- 968 0 THEN
|
|
|
|
|
- 969 SemError(233)
|
|
|
|
|
- 970 ELSE QbeGen.Mangled(qn,
|
|
|
|
|
- 971 SymTab.ProcUid(qn), mg0);
|
|
|
|
|
- 972 QbeGen.CallBegin(mg0,
|
|
|
|
|
- 973 res0,
|
|
|
|
|
- 974 SymTab.ProcDepthOf(qn),
|
|
|
|
|
- 975 SymTab.IsExternal(qn));
|
|
|
|
|
- 976 QbeGen.CallEnd(FALSE, q2)
|
|
|
|
|
- 977 END
|
|
|
|
|
- 978 ELSE SemError(233)
|
|
|
|
|
- 979 END; .) ) .
|
|
|
|
|
- 980 (* Actual-parameter list shared by statement and expression calls.
|
|
|
|
|
- 981 want selects CallEnd's result handling; t/q carry the call
|
|
|
|
|
- 982 value (statement calls discard). Arity/type failures are 233;
|
|
|
|
|
- 983 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
|
|
- 984 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
|
|
- 985 want: BOOLEAN;
|
|
|
|
|
- 986 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
|
|
- 987 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
|
|
- 988 res: SymTab.TypeIndex;
|
|
|
|
|
- 989 mg: QbeGen.QVal;
|
|
|
|
|
- 990 ok, ind: BOOLEAN; .)
|
|
|
|
|
- 991 = "(" (. called := TRUE;
|
|
|
|
|
- 992 ok := TRUE;
|
|
|
|
|
- 993 ind := FALSE;
|
|
|
|
|
- 994 IF SymTab.SymKind(pn) =
|
|
|
|
|
- 995 SymTab.KindProc THEN
|
|
|
|
|
- 996 res := SymTab.ProcRes(pn);
|
|
|
|
|
- 997 QbeGen.Mangled(pn,
|
|
|
|
|
- 998 SymTab.ProcUid(pn), mg);
|
|
|
|
|
- 999 QbeGen.CallBegin(mg, res,
|
|
|
|
|
- 1000 SymTab.ProcDepthOf(pn),
|
|
|
|
|
- 1001 SymTab.IsExternal(pn))
|
|
|
|
|
- 1002 ELSIF (pt # SymTab.InvalidType)
|
|
|
|
|
- 1003 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
|
|
- 1004 ind := TRUE;
|
|
|
|
|
- 1005 res :=
|
|
|
|
|
- 1006 SymTab.ProcTypeRes(pt);
|
|
|
|
|
- 1007 QbeGen.CallBeginInd(callee,
|
|
|
|
|
- 1008 res, FALSE)
|
|
|
|
|
- 1009 ELSE SemError(233);
|
|
|
|
|
- 1010 ok := FALSE;
|
|
|
|
|
- 1011 res := SymTab.InvalidType
|
|
|
|
|
- 1012 END;
|
|
|
|
|
- 1013 i := 0; .)
|
|
|
|
|
- 1014 [ ActParam<pn, pt, ind, i> (. INC(i); .)
|
|
|
|
|
- 1015 { "," ActParam<pn, pt, ind, i> (. INC(i); .) } ]
|
|
|
|
|
- 1016 ")" (. IF ok THEN
|
|
|
|
|
- 1017 IF ind THEN
|
|
|
|
|
- 1018 IF i #
|
|
|
|
|
- 1019 SymTab.ProcTypeNPar(pt) THEN
|
|
|
|
|
- 1020 SemError(233); ok := FALSE
|
|
|
|
|
- 1021 END
|
|
|
|
|
- 1022 ELSIF i #
|
|
|
|
|
- 1023 SymTab.ProcNPar(pn) THEN
|
|
|
|
|
- 1024 SemError(233); ok := FALSE
|
|
|
|
|
- 1025 END
|
|
|
|
|
- 1026 END;
|
|
|
|
|
- 1027 IF NOT ok THEN
|
|
|
|
|
- 1028 t := SymTab.InvalidType;
|
|
|
|
|
- 1029 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1030 ELSIF want THEN
|
|
|
|
|
- 1031 IF res =
|
|
|
|
|
- 1032 SymTab.InvalidType THEN
|
|
|
|
|
- 1033 SemError(233);
|
|
|
|
|
- 1034 t := SymTab.InvalidType;
|
|
|
|
|
- 1035 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1036 ELSE t := res;
|
|
|
|
|
- 1037 QbeGen.CallEnd(TRUE, q)
|
|
|
|
|
- 1038 END
|
|
|
|
|
- 1039 ELSE
|
|
|
|
|
- 1040 IF res #
|
|
|
|
|
- 1041 SymTab.InvalidType THEN
|
|
|
|
|
- 1042 SemError(233)
|
|
|
|
|
- 1043 END;
|
|
|
|
|
- 1044 t := SymTab.InvalidType;
|
|
|
|
|
- 1045 QbeGen.CopyOp("0", q);
|
|
|
|
|
- 1046 QbeGen.CallEnd(FALSE, q)
|
|
|
|
|
- 1047 END; .) .
|
|
|
|
|
- 1048 (* One actual: VAR formals take recorded designator addresses
|
|
|
|
|
- 1049 (233 otherwise); value formals take converted expressions. *)
|
|
|
|
|
- 1050 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
|
|
- 1051 i: CARDINAL> (. VAR at, ft: SymTab.TypeIndex;
|
|
|
|
|
- 1052 qe, qa, qt: QbeGen.QVal;
|
|
|
|
|
- 1053 isV, conv: BOOLEAN; .)
|
|
|
|
|
- 1054 = Expr<at, qe> (. IF ind THEN
|
|
|
|
|
- 1055 ft :=
|
|
|
|
|
- 1056 SymTab.ProcTypeParamType(pt,
|
|
|
|
|
- 1057 i);
|
|
|
|
|
- 1058 isV :=
|
|
|
|
|
- 1059 SymTab.ProcTypeParamIsVar(pt,
|
|
|
|
|
- 1060 i)
|
|
|
|
|
- 1061 ELSE
|
|
|
|
|
- 1062 ft := SymTab.ParamType(pn, i);
|
|
|
|
|
- 1063 isV := SymTab.ParamIsVar(pn, i)
|
|
|
|
|
- 1064 END;
|
|
|
|
|
- 1065 IF (at = SymTab.InvalidType)
|
|
|
|
|
- 1066 OR (ft =
|
|
|
|
|
- 1067 SymTab.InvalidType) THEN
|
|
|
|
|
- 1068 ELSIF isV THEN
|
|
|
|
|
- 1069 IF (SymTab.ClassOf(at)
|
|
|
|
|
- 1070 = SymTab.ClChar)
|
|
|
|
|
- 1071 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
- 1072 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
- 1073 = SymTab.ClChar)
|
|
|
|
|
- 1074 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
- 1075 (* 1-char string
|
|
|
|
|
- 1076 literal passed to
|
|
|
|
|
- 1077 a VAR ARRAY OF CHAR *)
|
|
|
|
|
- 1078 QbeGen.DeclCharStr(qe,
|
|
|
|
|
- 1079 qa);
|
|
|
|
|
- 1080 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
- 1081 "l") THEN
|
|
|
|
|
- 1082 SemError(233)
|
|
|
|
|
- 1083 END
|
|
|
|
|
- 1084 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
|
|
- 1085 qa) THEN
|
|
|
|
|
- 1086 SemError(233)
|
|
|
|
|
- 1087 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
|
|
- 1088 ft) THEN
|
|
|
|
|
- 1089 SemError(233)
|
|
|
|
|
- 1090 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
|
|
- 1091 "l") THEN
|
|
|
|
|
- 1092 SemError(233)
|
|
|
|
|
- 1093 END
|
|
|
|
|
- 1094 ELSE
|
|
|
|
|
- 1095 IF (SymTab.ClassOf(at)
|
|
|
|
|
- 1096 = SymTab.ClChar)
|
|
|
|
|
- 1097 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
- 1098 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
- 1099 = SymTab.ClChar)
|
|
|
|
|
- 1100 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
- 1101 (* 1-char string
|
|
|
|
|
- 1102 literal passed to
|
|
|
|
|
- 1103 ARRAY OF CHAR *)
|
|
|
|
|
- 1104 QbeGen.DeclCharStr(qe,
|
|
|
|
|
- 1105 qa);
|
|
|
|
|
- 1106 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
- 1107 "l") THEN
|
|
|
|
|
- 1108 SemError(233)
|
|
|
|
|
- 1109 END
|
|
|
|
|
- 1110 ELSIF NOT SymTab.Assignable(at,
|
|
|
|
|
- 1111 ft) THEN
|
|
|
|
|
- 1112 SemError(233)
|
|
|
|
|
- 1113 ELSE
|
|
|
|
|
- 1114 conv := (SymTab.ClassOf(
|
|
|
|
|
- 1115 ft) = SymTab.ClReal)
|
|
|
|
|
- 1116 AND SymTab.IsIntFamily(at);
|
|
|
|
|
- 1117 IF conv THEN
|
|
|
|
|
- 1118 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 1119 IF NOT QbeGen.CallArg(qt,
|
|
|
|
|
- 1120 "d") THEN
|
|
|
|
|
- 1121 SemError(233)
|
|
|
|
|
- 1122 END
|
|
|
|
|
- 1123 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
|
|
- 1124 QbeGen.ArgClass(ft)) THEN
|
|
|
|
|
- 1125 SemError(233)
|
|
|
|
|
- 1126 END
|
|
|
|
|
- 1127 END
|
|
|
|
|
- 1128 END; .) .
|
|
|
|
|
- 1129 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1130 q, lThen, lElse, lEnd:
|
|
|
|
|
- 1131 QbeGen.QVal;
|
|
|
|
|
- 1132 hasElse: BOOLEAN; .)
|
|
|
|
|
- 1133 = "IF" (. hasElse := FALSE; .)
|
|
|
|
|
- 1134 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 1135 SemError(214) END;
|
|
|
|
|
- 1136 QbeGen.NewLabel(lThen);
|
|
|
|
|
- 1137 QbeGen.NewLabel(lElse);
|
|
|
|
|
- 1138 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1139 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
- 1140 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
- 1141 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
|
|
- 1142 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 1143 QbeGen.NewLabel(lElse); .)
|
|
|
|
|
- 1144 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
|
|
+ 443 Enum<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
+ 444 ord: INTEGER;
|
|
|
|
|
+ 445 qv: QbeGen.QVal; .)
|
|
|
|
|
+ 446 = "(" (. t := SymTab.NewEnum();
|
|
|
|
|
+ 447 ord := 0; .)
|
|
|
|
|
+ 448 GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 449 SymTab.KindConst) THEN
|
|
|
|
|
+ 450 SemError(200) END;
|
|
|
|
|
+ 451 SymTab.SetSymType(n, t);
|
|
|
|
|
+ 452 QbeGen.IntStr(ord, qv);
|
|
|
|
|
+ 453 SymTab.SetSymVal(n, qv);
|
|
|
|
|
+ 454 INC(ord); .)
|
|
|
|
|
+ 455 { "," GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 456 SymTab.KindConst) THEN
|
|
|
|
|
+ 457 SemError(200) END;
|
|
|
|
|
+ 458 SymTab.SetSymType(n, t);
|
|
|
|
|
+ 459 QbeGen.IntStr(ord, qv);
|
|
|
|
|
+ 460 SymTab.SetSymVal(n, qv);
|
|
|
|
|
+ 461 INC(ord); .) }
|
|
|
|
|
+ 462 ")" .
|
|
|
|
|
+ 463 (* Clarion-form classes (docs/OOP.txt): declaration + single
|
|
|
|
|
+ 464 inheritance + IMPLEMENTATION blocks. Scopes and member checks
|
|
|
|
|
+ 465 now; lowering (vtable, dispatch, THIS) later — one 230 per
|
|
|
|
|
+ 466 class/impl block. Methods end with ";" per the Table example
|
|
|
|
|
+ 467 (not "," as in the sketch). No underscores in identifiers. *)
|
|
|
|
|
+ 468 (* Single CLASS item in both loops: separating declaration from
|
|
|
|
|
+ 469 IMPLEMENTATION at the loop level needs 2-token lookahead
|
|
|
|
|
+ 470 (CLASS ident vs CLASS IMPLEMENTATION), which LL(1) cannot do.
|
|
|
|
|
+ 471 The second token decides after CLASS is consumed. A misplaced
|
|
|
|
|
+ 472 CLASS IMPLEMENTATION inside TYPE still parses (harmless: the
|
|
|
|
|
+ 473 whole unit ends 230 until lowering). *)
|
|
|
|
|
+ 474 ClassItem
|
|
|
|
|
+ 475 = "CLASS" ( "IMPLEMENTATION" ClassImplRest | ClassRest ) .
|
|
|
|
|
+ 476 ClassRest (. VAR cn, m2, pn: SymTab.Name;
|
|
|
|
|
+ 477 ct: SymTab.TypeIndex; .)
|
|
|
|
|
+ 478 = GetIdent<cn> (. IF NOT SymTab.Enter(cn,
|
|
|
|
|
+ 479 SymTab.KindType) THEN
|
|
|
|
|
+ 480 SemError(200) END;
|
|
|
|
|
+ 481 ct := SymTab.NewClass();
|
|
|
|
|
+ 482 SymTab.SetSymType(cn, ct);
|
|
|
|
|
+ 483 SymTab.PushClassScope(ct); .)
|
|
|
|
|
+ 484 [ Parents<ct> ]
|
|
|
|
|
+ 485 ";"
|
|
|
|
|
+ 486 { ClassField<ct> ";" }
|
|
|
|
|
+ 487 { MethodHeading<pn> ";" (. SymTab.CloseProc;
|
|
|
|
|
+ 488 QbeGen.AbortFunc; .) }
|
|
|
|
|
+ 489 "END"
|
|
|
|
|
+ 490 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
+ 491 SemError(202) END;
|
|
|
|
|
+ 492 SymTab.PopScope;
|
|
|
|
|
+ 493 SemError(230); .) .
|
|
|
|
|
+ 494 Parents<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name; .)
|
|
|
|
|
+ 495 = "(" Parent1<ct>
|
|
|
|
|
+ 496 { "," GetIdent<p> (. SemError(230); .) }
|
|
|
|
|
+ 497 ")" .
|
|
|
|
|
+ 498 Parent1<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name;
|
|
|
|
|
+ 499 pt: SymTab.TypeIndex; .)
|
|
|
|
|
+ 500 = GetIdent<p> (. IF NOT SymTab.Lookup(p) THEN
|
|
|
|
|
+ 501 SemError(201)
|
|
|
|
|
+ 502 ELSE pt := SymTab.SymType(p);
|
|
|
|
|
+ 503 IF SymTab.ClassOf(pt) #
|
|
|
|
|
+ 504 SymTab.ClClass THEN
|
|
|
|
|
+ 505 SemError(230)
|
|
|
|
|
+ 506 ELSE SymTab.SetParent(ct, pt)
|
|
|
|
|
+ 507 END
|
|
|
|
|
+ 508 END; .) .
|
|
|
|
|
+ 509 ClassField<ct: SymTab.TypeIndex> (. VAR n, rhs: SymTab.Name;
|
|
|
|
|
+ 510 t: SymTab.TypeIndex; .)
|
|
|
|
|
+ 511 = GetIdent<n>
|
|
|
|
|
+ 512 ( "=" GetIdent<rhs> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 513 SymTab.KindConst) THEN
|
|
|
|
|
+ 514 SemError(200) END;
|
|
|
|
|
+ 515 IF SymTab.Lookup(rhs) THEN
|
|
|
|
|
+ 516 SymTab.SetSymType(n,
|
|
|
|
|
+ 517 SymTab.SymType(rhs))
|
|
|
|
|
+ 518 END; .)
|
|
|
|
|
+ 519 | (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
+ 520 n) THEN
|
|
|
|
|
+ 521 SemError(200) END; .)
|
|
|
|
|
+ 522 { "," GetIdent<n> (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
+ 523 n) THEN
|
|
|
|
|
+ 524 SemError(200) END; .) }
|
|
|
|
|
+ 525 ":" Type<t, FALSE> (. SymTab.FixPendingF(ct, t); .) ) .
|
|
|
|
|
+ 526 MethodHeading<VAR pn: SymTab.Name> (. VAR wantVirt: BOOLEAN; .)
|
|
|
|
|
+ 527 = (. wantVirt := FALSE; .)
|
|
|
|
|
+ 528 [ "VIRTUAL" (. wantVirt := TRUE; .) ]
|
|
|
|
|
+ 529 ProcHeading<pn> (. IF wantVirt THEN
|
|
|
|
|
+ 530 SymTab.MarkVirtual END; .) .
|
|
|
|
|
+ 531 ClassImplRest (. VAR cn, m2: SymTab.Name;
|
|
|
|
|
+ 532 ct: SymTab.TypeIndex; .)
|
|
|
|
|
+ 533 = GetIdent<cn> (. IF NOT SymTab.Lookup(cn) THEN
|
|
|
|
|
+ 534 SemError(201);
|
|
|
|
|
+ 535 ct := SymTab.InvalidType
|
|
|
|
|
+ 536 ELSE ct := SymTab.SymType(cn);
|
|
|
|
|
+ 537 IF SymTab.ClassOf(ct) #
|
|
|
|
|
+ 538 SymTab.ClClass THEN
|
|
|
|
|
+ 539 SemError(230);
|
|
|
|
|
+ 540 ct := SymTab.InvalidType
|
|
|
|
|
+ 541 END
|
|
|
|
|
+ 542 END;
|
|
|
|
|
+ 543 IF ct #
|
|
|
|
|
+ 544 SymTab.InvalidType THEN
|
|
|
|
|
+ 545 IF NOT SymTab.PushClassMembers(
|
|
|
|
|
+ 546 ct) THEN
|
|
|
|
|
+ 547 SemError(230) END
|
|
|
|
|
+ 548 END; .)
|
|
|
|
|
+ 549 ";" { MethodImpl<ct> ";" }
|
|
|
|
|
+ 550 [ "BEGIN"
|
|
|
|
|
+ 551 [ StatSeq ] ]
|
|
|
|
|
+ 552 "END"
|
|
|
|
|
+ 553 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
+ 554 SemError(202) END;
|
|
|
|
|
+ 555 SymTab.PopScope;
|
|
|
|
|
+ 556 SemError(230); .) .
|
|
|
|
|
+ 557 MethodImpl<ct: SymTab.TypeIndex> (. VAR pn: SymTab.Name; .)
|
|
|
|
|
+ 558 = (. QbeGen.SetNoEmit(TRUE); .)
|
|
|
|
|
+ 559 MethodHeading<pn> ";"
|
|
|
|
|
+ 560 (. IF (ct #
|
|
|
|
|
+ 561 SymTab.InvalidType)
|
|
|
|
|
+ 562 AND NOT SymTab.MethodExists(ct,
|
|
|
|
|
+ 563 pn) THEN
|
|
|
|
|
+ 564 SemError(201) END; .)
|
|
|
|
|
+ 565 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
+ 566 SymTab.CloseProc; .)
|
|
|
|
|
+ 567 | Block<pn> (. SymTab.CloseProc; .) )
|
|
|
|
|
+ 568 (. QbeGen.AbortFunc;
|
|
|
|
|
+ 569 QbeGen.SetNoEmit(FALSE);
|
|
|
|
|
+ 570 SemError(230); .) .
|
|
|
|
|
+ 571 ConstBlock
|
|
|
|
|
+ 572 = "CONST" { ConstDecl ";" } .
|
|
|
|
|
+ 573 ConstDecl (. VAR n: SymTab.Name;
|
|
|
|
|
+ 574 t: SymTab.TypeIndex;
|
|
|
|
|
+ 575 qv: QbeGen.QVal;
|
|
|
|
|
+ 576 cls: INTEGER; .)
|
|
|
|
|
+ 577 = GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 578 SymTab.KindConst) THEN
|
|
|
|
|
+ 579 SemError(200) END; .)
|
|
|
|
|
+ 580 "="
|
|
|
|
|
+ 581 Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
|
|
+ 582 cls := SymTab.ClassOf(t);
|
|
|
|
|
+ 583 IF cls = SymTab.ClStr THEN
|
|
|
|
|
+ 584 SemError(230)
|
|
|
|
|
+ 585 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
|
|
+ 586 SemError(230) END;
|
|
|
|
|
+ 587 SymTab.SetSymVal(n, qv);
|
|
|
|
|
+ 588 QbeGen.DeclConst(n, qv, t); .) .
|
|
|
|
|
+ 589 VarBlock
|
|
|
|
|
+ 590 = "VAR" { VarDecl ";" } .
|
|
|
|
|
+ 591 VarDecl (. VAR nm: SymTab.Name;
|
|
|
|
|
+ 592 t: SymTab.TypeIndex;
|
|
|
|
|
+ 593 i: CARDINAL;
|
|
|
|
|
+ 594 cls: INTEGER; .)
|
|
|
|
|
+ 595 = VarIdents ":"
|
|
|
|
|
+ 596 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
|
|
+ 597 IF (t # SymTab.InvalidType)
|
|
|
|
|
+ 598 AND (cls # SymTab.ClInt)
|
|
|
|
|
+ 599 AND (cls # SymTab.ClBool)
|
|
|
|
|
+ 600 AND (cls # SymTab.ClChar)
|
|
|
|
|
+ 601 AND (cls # SymTab.ClReal)
|
|
|
|
|
+ 602 AND (cls # SymTab.ClArray)
|
|
|
|
|
+ 603 AND (cls # SymTab.ClSet)
|
|
|
|
|
+ 604 AND (cls # SymTab.ClRecord)
|
|
|
|
|
+ 605 AND (cls # SymTab.ClPtr)
|
|
|
|
|
+ 606 AND (cls # SymTab.ClLong)
|
|
|
|
|
+ 607 AND (cls # SymTab.ClProc)
|
|
|
|
|
+ 608 AND (cls # SymTab.ClUChar)
|
|
|
|
|
+ 609 AND (cls # SymTab.ClUStr)
|
|
|
|
|
+ 610 AND (cls # SymTab.ClEnum) THEN
|
|
|
|
|
+ 611 SemError(230) END;
|
|
|
|
|
+ 612 IF QbeGen.LocFull() THEN
|
|
|
|
|
+ 613 SemError(233) END;
|
|
|
|
|
+ 614 i := 0;
|
|
|
|
|
+ 615 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
+ 616 SymTab.PendName(i, nm);
|
|
|
|
|
+ 617 QbeGen.DeclVar(nm, t);
|
|
|
|
|
+ 618 INC(i)
|
|
|
|
|
+ 619 END;
|
|
|
|
|
+ 620 SymTab.FixPending(t); .) .
|
|
|
|
|
+ 621 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 622 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
+ 623 SymTab.KindVar) THEN
|
|
|
|
|
+ 624 SemError(200) END; .)
|
|
|
|
|
+ 625 { ","
|
|
|
|
|
+ 626 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
+ 627 SymTab.KindVar) THEN
|
|
|
|
|
+ 628 SemError(200) END; .) } .
|
|
|
|
|
+ 629 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 630 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
+ 631 SemError(200) END; .)
|
|
|
|
|
+ 632 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
+ 633 SemError(200) END; .) } .
|
|
|
|
|
+ 634 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
|
|
+ 635 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
|
|
+ 636 FORWARD marks; the body heading re-enters (signature compare
|
|
|
|
|
+ 637 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
|
|
+ 638 ProcHeading<VAR pn: SymTab.Name> (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 639 mg: QbeGen.QVal; .)
|
|
|
|
|
+ 640 = "PROCEDURE"
|
|
|
|
|
+ 641 GetIdent<pn> (. IF NOT SymTab.EnterProc(pn) THEN
|
|
|
|
|
+ 642 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
|
|
+ 643 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
|
|
+ 644 SemError(200) END
|
|
|
|
|
+ 645 END
|
|
|
|
|
+ 646 END;
|
|
|
|
|
+ 647 QbeGen.Mangled(pn,
|
|
|
|
|
+ 648 SymTab.ProcUid(pn), mg);
|
|
|
|
|
+ 649 QbeGen.BeginFunc(mg); .)
|
|
|
|
|
+ 650 [ FormalParams ]
|
|
|
|
|
+ 651 [ ":" TypeIdent<t> (. SymTab.SetProcRes(t);
|
|
|
|
|
+ 652 QbeGen.SetFuncRes(t);
|
|
|
|
|
+ 653 IF (t #
|
|
|
|
|
+ 654 SymTab.InvalidType)
|
|
|
|
|
+ 655 AND ((SymTab.ClassOf(t)
|
|
|
|
|
+ 656 = SymTab.ClArray)
|
|
|
|
|
+ 657 OR (SymTab.ClassOf(t)
|
|
|
|
|
+ 658 = SymTab.ClRecord)
|
|
|
|
|
+ 659 OR (SymTab.ClassOf(t)
|
|
|
|
|
+ 660 = SymTab.ClSet)
|
|
|
|
|
+ 661 OR (SymTab.ClassOf(t)
|
|
|
|
|
+ 662 = SymTab.ClClass)) THEN
|
|
|
|
|
+ 663 SemError(230) END; .) ] .
|
|
|
|
|
+ 664 FormalParams
|
|
|
|
|
+ 665 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
|
|
+ 666 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 667 nm: SymTab.Name;
|
|
|
|
|
+ 668 i: CARDINAL;
|
|
|
|
|
+ 669 isV: BOOLEAN; .)
|
|
|
|
|
+ 670 = (. isV := FALSE; .)
|
|
|
|
|
+ 671 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
+ 672 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
|
|
+ 673 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
+ 674 SymTab.PendName(i, nm);
|
|
|
|
|
+ 675 (* value open arrays are
|
|
|
|
|
+ 676 passed as descriptor
|
|
|
|
|
+ 677 addresses (no copy):
|
|
|
|
|
+ 678 same representation as
|
|
|
|
|
+ 679 VAR formals *)
|
|
|
|
|
+ 680 IF NOT QbeGen.FuncParam(nm,
|
|
|
|
|
+ 681 isV
|
|
|
|
|
+ 682 OR SymTab.IsOpenArray(t),
|
|
|
|
|
+ 683 t) THEN
|
|
|
|
|
+ 684 SemError(233) END;
|
|
|
|
|
+ 685 INC(i)
|
|
|
|
|
+ 686 END;
|
|
|
|
|
+ 687 SymTab.FixPending(t); .) .
|
|
|
|
|
+ 688 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
|
|
+ 689 static link gives them their parent's frame. Methods keep
|
|
|
|
|
+ 690 parse-now/230-later. *)
|
|
|
|
|
+ 691 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
|
|
+ 692 = ProcHeading<pn> ";"
|
|
|
|
|
+ 693 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
+ 694 SymTab.CloseProc;
|
|
|
|
|
+ 695 QbeGen.AbortFunc; .)
|
|
|
|
|
+ 696 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
|
|
+ 697 SymTab.CloseProc;
|
|
|
|
|
+ 698 QbeGen.AbortFunc; .)
|
|
|
|
|
+ 699 | (. QbeGen.EndFuncHeader; .)
|
|
|
|
|
+ 700 Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
+ 701 QbeGen.EndFunc(
|
|
|
|
|
+ 702 SymTab.ProcRes(pn)); .) ) .
|
|
|
|
|
+ 703 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
|
|
+ 704 = DeclSeq
|
|
|
|
|
+ 705 [ "BEGIN"
|
|
|
|
|
+ 706 [ StatSeq ] ]
|
|
|
|
|
+ 707 "END"
|
|
|
|
|
+ 708 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
|
|
+ 709 SemError(202) END; .) .
|
|
|
|
|
+ 710 StatSeq
|
|
|
|
|
+ 711 = Statement { ";" [ Statement ] } .
|
|
|
|
|
+ 712 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
|
|
+ 713 are accepted: the statement after ';' is optional. *)
|
|
|
|
|
+ 714 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
|
|
+ 715 = AssOrCall
|
|
|
|
|
+ 716 | IfStat
|
|
|
|
|
+ 717 | WhileStat
|
|
|
|
|
+ 718 | RepeatStat
|
|
|
|
|
+ 719 | LoopStat
|
|
|
|
|
+ 720 | ForStat
|
|
|
|
|
+ 721 | CaseStat
|
|
|
|
|
+ 722 | WithStat
|
|
|
|
|
+ 723 | ReturnStat
|
|
|
|
|
+ 724 | HaltStat
|
|
|
|
|
+ 725 | NewStat
|
|
|
|
|
+ 726 | DisposeStat
|
|
|
|
|
+ 727 | IncDecStat
|
|
|
|
|
+ 728 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
|
|
+ 729 QbeGen.Jmp(lx)
|
|
|
|
|
+ 730 ELSE SemError(230) END; .) .
|
|
|
|
|
+ 731 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
|
|
+ 732 integer designator. *)
|
|
|
|
|
+ 733 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 734 dk: INTEGER;
|
|
|
|
|
+ 735 qd, qv, qn2, qstep:
|
|
|
|
|
+ 736 QbeGen.QVal;
|
|
|
|
|
+ 737 qn: SymTab.Name;
|
|
|
|
|
+ 738 sfx, isInc: BOOLEAN; .)
|
|
|
|
|
+ 739 = (. isInc := TRUE; .)
|
|
|
|
|
+ 740 ( "INC" (. isInc := TRUE; .)
|
|
|
|
|
+ 741 | "DEC" (. isInc := FALSE; .) )
|
|
|
|
|
+ 742 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
|
|
+ 743 Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
+ 744 [ "," Expr<et2, qstep> ]
|
|
|
|
|
+ 745 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 746 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 747 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 748 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 749 SemError(210)
|
|
|
|
|
+ 750 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
|
|
+ 751 SemError(211)
|
|
|
|
|
+ 752 ELSE
|
|
|
|
|
+ 753 IF sfx
|
|
|
|
|
+ 754 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
+ 755 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
|
|
+ 756 ELSE QbeGen.LoadVar(qn,
|
|
|
|
|
+ 757 FALSE, qv)
|
|
|
|
|
+ 758 END;
|
|
|
|
|
+ 759 QbeGen.NewTemp(qn2);
|
|
|
|
|
+ 760 IF isInc THEN
|
|
|
|
|
+ 761 QbeGen.Op3("add", qn2, qv,
|
|
|
|
|
+ 762 qstep, FALSE)
|
|
|
|
|
+ 763 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
|
|
+ 764 qstep, FALSE)
|
|
|
|
|
+ 765 END;
|
|
|
|
|
+ 766 IF sfx
|
|
|
|
|
+ 767 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
+ 768 QbeGen.ElemStore(qd, qn2,
|
|
|
|
|
+ 769 dt)
|
|
|
|
|
+ 770 ELSE QbeGen.StoreVar(qn,
|
|
|
|
|
+ 771 qn2, FALSE)
|
|
|
|
|
+ 772 END
|
|
|
|
|
+ 773 END; .) .
|
|
|
|
|
+ 774 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
|
|
+ 775 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
|
|
+ 776 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
|
|
+ 777 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 778 dk: INTEGER;
|
|
|
|
|
+ 779 qd, qm: QbeGen.QVal;
|
|
|
|
|
+ 780 qn: SymTab.Name;
|
|
|
|
|
+ 781 sfx: BOOLEAN;
|
|
|
|
|
+ 782 bt: SymTab.TypeIndex; .)
|
|
|
|
|
+ 783 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 784 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 785 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 786 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 787 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 788 SemError(210)
|
|
|
|
|
+ 789 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 790 SymTab.ClPtr THEN
|
|
|
|
|
+ 791 SemError(219)
|
|
|
|
|
+ 792 ELSE bt := SymTab.PtrBase(dt);
|
|
|
|
|
+ 793 IF bt #
|
|
|
|
|
+ 794 SymTab.InvalidType THEN
|
|
|
|
|
+ 795 QbeGen.NewHeap(bt, qm);
|
|
|
|
|
+ 796 QbeGen.InitHeap(qm, bt);
|
|
|
|
|
+ 797 IF sfx
|
|
|
|
|
+ 798 OR (dk =
|
|
|
|
|
+ 799 SymTab.KindField) THEN
|
|
|
|
|
+ 800 QbeGen.ElemStore(qd, qm,
|
|
|
|
|
+ 801 dt)
|
|
|
|
|
+ 802 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
+ 803 qm)
|
|
|
|
|
+ 804 END
|
|
|
|
|
+ 805 END
|
|
|
|
|
+ 806 END; .) .
|
|
|
|
|
+ 807 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 808 dk: INTEGER;
|
|
|
|
|
+ 809 qd, qv: QbeGen.QVal;
|
|
|
|
|
+ 810 qn: SymTab.Name;
|
|
|
|
|
+ 811 sfx: BOOLEAN; .)
|
|
|
|
|
+ 812 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 813 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 814 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 815 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 816 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 817 SemError(210)
|
|
|
|
|
+ 818 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 819 SymTab.ClPtr THEN
|
|
|
|
|
+ 820 SemError(219)
|
|
|
|
|
+ 821 ELSE
|
|
|
|
|
+ 822 IF sfx
|
|
|
|
|
+ 823 OR (dk =
|
|
|
|
|
+ 824 SymTab.KindField) THEN
|
|
|
|
|
+ 825 QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
+ 826 qv)
|
|
|
|
|
+ 827 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
|
|
+ 828 END;
|
|
|
|
|
+ 829 QbeGen.FreeHeap(qv);
|
|
|
|
|
+ 830 IF sfx
|
|
|
|
|
+ 831 OR (dk =
|
|
|
|
|
+ 832 SymTab.KindField) THEN
|
|
|
|
|
+ 833 QbeGen.ElemStore(qd, "0",
|
|
|
|
|
+ 834 dt)
|
|
|
|
|
+ 835 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
+ 836 "0")
|
|
|
|
|
+ 837 END
|
|
|
|
|
+ 838 END; .) .
|
|
|
|
|
+ 839 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
|
|
+ 840 address; field designators resolve through both stacks. *)
|
|
|
|
|
+ 841 WithStat (. VAR nW: CARDINAL; .)
|
|
|
|
|
+ 842 = "WITH" (. nW := 0; .)
|
|
|
|
|
+ 843 WithItem<nW> { "," WithItem<nW> }
|
|
|
|
|
+ 844 "DO" [ StatSeq ] "END"
|
|
|
|
|
+ 845 (. WHILE nW > 0 DO
|
|
|
|
|
+ 846 SymTab.PopScope;
|
|
|
|
|
+ 847 QbeGen.PopWith;
|
|
|
|
|
+ 848 DEC(nW)
|
|
|
|
|
+ 849 END; .) .
|
|
|
|
|
+ 850 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 851 dk: INTEGER;
|
|
|
|
|
+ 852 qd, qe: QbeGen.QVal;
|
|
|
|
|
+ 853 qn: SymTab.Name;
|
|
|
|
|
+ 854 sfx: BOOLEAN; .)
|
|
|
|
|
+ 855 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
+ 856 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 857 ELSIF (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 858 SymTab.ClRecord)
|
|
|
|
|
+ 859 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 860 SymTab.ClClass) THEN
|
|
|
|
|
+ 861 SemError(215)
|
|
|
|
|
+ 862 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
|
|
+ 863 QbeGen.PushWith(qd);
|
|
|
|
|
+ 864 INC(nW)
|
|
|
|
|
+ 865 END; .) .
|
|
|
|
|
+ 866 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
|
|
+ 867 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
|
|
+ 868 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
|
|
+ 869 dk: INTEGER;
|
|
|
|
|
+ 870 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
|
|
+ 871 qn: SymTab.Name;
|
|
|
|
|
+ 872 ct2, res0: SymTab.TypeIndex;
|
|
|
|
|
+ 873 q2, mg0: QbeGen.QVal;
|
|
|
|
|
+ 874 isR, conv, wconv: BOOLEAN;
|
|
|
|
|
+ 875 called, sfx: BOOLEAN; .)
|
|
|
|
|
+ 876 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
+ 877 ( ":="
|
|
|
|
|
+ 878 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 879 AND (dk # SymTab.KindVar)
|
|
|
|
|
+ 880 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 881 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 882 SemError(210)
|
|
|
|
|
+ 883 ELSIF NOT SymTab.Assignable(et,
|
|
|
|
|
+ 884 dt) THEN
|
|
|
|
|
+ 885 SemError(210)
|
|
|
|
|
+ 886 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 887 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 888 SymTab.ClClass) THEN
|
|
|
|
|
+ 889 SemError(230) END;
|
|
|
|
|
+ 890 isR := (dt #
|
|
|
|
|
+ 891 SymTab.InvalidType)
|
|
|
|
|
+ 892 AND (SymTab.ClassOf(dt)
|
|
|
|
|
+ 893 = SymTab.ClReal);
|
|
|
|
|
+ 894 conv := isR
|
|
|
|
|
+ 895 AND SymTab.IsIntFamily(et);
|
|
|
|
|
+ 896 wconv := (dt #
|
|
|
|
|
+ 897 SymTab.InvalidType)
|
|
|
|
|
+ 898 AND SymTab.IsLongFamily(dt)
|
|
|
|
|
+ 899 AND SymTab.IsIntFamily(et);
|
|
|
|
|
+ 900 IF ((dk = SymTab.KindVar)
|
|
|
|
|
+ 901 OR (dk = SymTab.KindParam)
|
|
|
|
|
+ 902 OR (dk = SymTab.KindField))
|
|
|
|
|
+ 903 AND (dt # SymTab.InvalidType)
|
|
|
|
|
+ 904 AND (et # SymTab.InvalidType)
|
|
|
|
|
+ 905 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 906 SymTab.ClClass) THEN
|
|
|
|
|
+ 907 IF sfx
|
|
|
|
|
+ 908 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
+ 909 IF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 910 SymTab.ClArray THEN
|
|
|
|
|
+ 911 QbeGen.CopyArray(qd, qe,
|
|
|
|
|
+ 912 dt)
|
|
|
|
|
+ 913 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 914 SymTab.ClSet THEN
|
|
|
|
|
+ 915 QbeGen.CopySet(qd, qe,
|
|
|
|
|
+ 916 SymTab.SetWords(dt),
|
|
|
|
|
+ 917 SymTab.SetWords(et))
|
|
|
|
|
+ 918 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 919 SymTab.ClRecord THEN
|
|
|
|
|
+ 920 QbeGen.CopyRecord(qd, qe,
|
|
|
|
|
+ 921 dt)
|
|
|
|
|
+ 922 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
+ 923 IF wconv THEN
|
|
|
|
|
+ 924 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
+ 925 QbeGen.ElemStore(qd, ql,
|
|
|
|
|
+ 926 dt)
|
|
|
|
|
+ 927 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
+ 928 dt)
|
|
|
|
|
+ 929 END
|
|
|
|
|
+ 930 ELSIF conv THEN
|
|
|
|
|
+ 931 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 932 QbeGen.ElemStore(qd, qt,
|
|
|
|
|
+ 933 dt)
|
|
|
|
|
+ 934 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
+ 935 dt)
|
|
|
|
|
+ 936 END
|
|
|
|
|
+ 937 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 938 SymTab.ClArray THEN
|
|
|
|
|
+ 939 QbeGen.CopyArray(qd, qe, dt)
|
|
|
|
|
+ 940 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 941 SymTab.ClSet THEN
|
|
|
|
|
+ 942 QbeGen.CopySet(qd, qe,
|
|
|
|
|
+ 943 SymTab.SetWords(dt),
|
|
|
|
|
+ 944 SymTab.SetWords(et))
|
|
|
|
|
+ 945 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 946 SymTab.ClRecord THEN
|
|
|
|
|
+ 947 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
|
|
+ 948 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 949 SymTab.ClPtr)
|
|
|
|
|
+ 950 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 951 SymTab.ClProc) THEN
|
|
|
|
|
+ 952 QbeGen.StorePtr(qn, qe)
|
|
|
|
|
+ 953 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
+ 954 IF wconv THEN
|
|
|
|
|
+ 955 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
+ 956 QbeGen.StoreLong(qn, ql)
|
|
|
|
|
+ 957 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
|
|
+ 958 END
|
|
|
|
|
+ 959 ELSIF conv THEN
|
|
|
|
|
+ 960 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 961 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
|
|
+ 962 ELSE
|
|
|
|
|
+ 963 QbeGen.StoreVar(qn, qe, isR)
|
|
|
|
|
+ 964 END
|
|
|
|
|
+ 965 END; .)
|
|
|
|
|
+ 966 | ArgList<qn, dt, qd, FALSE, ct2, q2, called>
|
|
|
|
|
+ 967 | (* bare `P;`: proper parameterless
|
|
|
|
|
+ 968 procedure call; anything else
|
|
|
|
|
+ 969 here is 233 (was a bare syntax
|
|
|
|
|
+ 970 error before 4.2) *)
|
|
|
|
|
+ 971 (. IF (dk = SymTab.KindProc)
|
|
|
|
|
+ 972 AND NOT sfx THEN
|
|
|
|
|
+ 973 res0 := SymTab.ProcRes(qn);
|
|
|
|
|
+ 974 IF res0 #
|
|
|
|
|
+ 975 SymTab.InvalidType THEN
|
|
|
|
|
+ 976 SemError(233)
|
|
|
|
|
+ 977 ELSIF SymTab.ProcNPar(qn) #
|
|
|
|
|
+ 978 0 THEN
|
|
|
|
|
+ 979 SemError(233)
|
|
|
|
|
+ 980 ELSE QbeGen.Mangled(qn,
|
|
|
|
|
+ 981 SymTab.ProcUid(qn), mg0);
|
|
|
|
|
+ 982 QbeGen.CallBegin(mg0,
|
|
|
|
|
+ 983 res0,
|
|
|
|
|
+ 984 SymTab.ProcDepthOf(qn),
|
|
|
|
|
+ 985 SymTab.IsExternal(qn));
|
|
|
|
|
+ 986 QbeGen.CallEnd(FALSE, q2)
|
|
|
|
|
+ 987 END
|
|
|
|
|
+ 988 ELSE SemError(233)
|
|
|
|
|
+ 989 END; .) ) .
|
|
|
|
|
+ 990 (* Actual-parameter list shared by statement and expression calls.
|
|
|
|
|
+ 991 want selects CallEnd's result handling; t/q carry the call
|
|
|
|
|
+ 992 value (statement calls discard). Arity/type failures are 233;
|
|
|
|
|
+ 993 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
|
|
+ 994 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
|
|
+ 995 want: BOOLEAN;
|
|
|
|
|
+ 996 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
|
|
+ 997 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
|
|
+ 998 res: SymTab.TypeIndex;
|
|
|
|
|
+ 999 mg: QbeGen.QVal;
|
|
|
|
|
+ 1000 ok, ind: BOOLEAN; .)
|
|
|
|
|
+ 1001 = "(" (. called := TRUE;
|
|
|
|
|
+ 1002 ok := TRUE;
|
|
|
|
|
+ 1003 ind := FALSE;
|
|
|
|
|
+ 1004 IF SymTab.SymKind(pn) =
|
|
|
|
|
+ 1005 SymTab.KindProc THEN
|
|
|
|
|
+ 1006 res := SymTab.ProcRes(pn);
|
|
|
|
|
+ 1007 QbeGen.Mangled(pn,
|
|
|
|
|
+ 1008 SymTab.ProcUid(pn), mg);
|
|
|
|
|
+ 1009 QbeGen.CallBegin(mg, res,
|
|
|
|
|
+ 1010 SymTab.ProcDepthOf(pn),
|
|
|
|
|
+ 1011 SymTab.IsExternal(pn))
|
|
|
|
|
+ 1012 ELSIF (pt # SymTab.InvalidType)
|
|
|
|
|
+ 1013 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
|
|
+ 1014 ind := TRUE;
|
|
|
|
|
+ 1015 res :=
|
|
|
|
|
+ 1016 SymTab.ProcTypeRes(pt);
|
|
|
|
|
+ 1017 QbeGen.CallBeginInd(callee,
|
|
|
|
|
+ 1018 res, FALSE)
|
|
|
|
|
+ 1019 ELSE SemError(233);
|
|
|
|
|
+ 1020 ok := FALSE;
|
|
|
|
|
+ 1021 res := SymTab.InvalidType
|
|
|
|
|
+ 1022 END;
|
|
|
|
|
+ 1023 i := 0; .)
|
|
|
|
|
+ 1024 [ ActParam<pn, pt, ind, i> (. INC(i); .)
|
|
|
|
|
+ 1025 { "," ActParam<pn, pt, ind, i> (. INC(i); .) } ]
|
|
|
|
|
+ 1026 ")" (. IF ok THEN
|
|
|
|
|
+ 1027 IF ind THEN
|
|
|
|
|
+ 1028 IF i #
|
|
|
|
|
+ 1029 SymTab.ProcTypeNPar(pt) THEN
|
|
|
|
|
+ 1030 SemError(233); ok := FALSE
|
|
|
|
|
+ 1031 END
|
|
|
|
|
+ 1032 ELSIF i #
|
|
|
|
|
+ 1033 SymTab.ProcNPar(pn) THEN
|
|
|
|
|
+ 1034 SemError(233); ok := FALSE
|
|
|
|
|
+ 1035 END
|
|
|
|
|
+ 1036 END;
|
|
|
|
|
+ 1037 IF NOT ok THEN
|
|
|
|
|
+ 1038 t := SymTab.InvalidType;
|
|
|
|
|
+ 1039 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1040 ELSIF want THEN
|
|
|
|
|
+ 1041 IF res =
|
|
|
|
|
+ 1042 SymTab.InvalidType THEN
|
|
|
|
|
+ 1043 SemError(233);
|
|
|
|
|
+ 1044 t := SymTab.InvalidType;
|
|
|
|
|
+ 1045 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1046 ELSE t := res;
|
|
|
|
|
+ 1047 QbeGen.CallEnd(TRUE, q)
|
|
|
|
|
+ 1048 END
|
|
|
|
|
+ 1049 ELSE
|
|
|
|
|
+ 1050 IF res #
|
|
|
|
|
+ 1051 SymTab.InvalidType THEN
|
|
|
|
|
+ 1052 SemError(233)
|
|
|
|
|
+ 1053 END;
|
|
|
|
|
+ 1054 t := SymTab.InvalidType;
|
|
|
|
|
+ 1055 QbeGen.CopyOp("0", q);
|
|
|
|
|
+ 1056 QbeGen.CallEnd(FALSE, q)
|
|
|
|
|
+ 1057 END; .) .
|
|
|
|
|
+ 1058 (* One actual: VAR formals take recorded designator addresses
|
|
|
|
|
+ 1059 (233 otherwise); value formals take converted expressions. *)
|
|
|
|
|
+ 1060 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
|
|
+ 1061 i: CARDINAL> (. VAR at, ft: SymTab.TypeIndex;
|
|
|
|
|
+ 1062 qe, qa, qt: QbeGen.QVal;
|
|
|
|
|
+ 1063 isV, conv: BOOLEAN; .)
|
|
|
|
|
+ 1064 = Expr<at, qe> (. IF ind THEN
|
|
|
|
|
+ 1065 ft :=
|
|
|
|
|
+ 1066 SymTab.ProcTypeParamType(pt,
|
|
|
|
|
+ 1067 i);
|
|
|
|
|
+ 1068 isV :=
|
|
|
|
|
+ 1069 SymTab.ProcTypeParamIsVar(pt,
|
|
|
|
|
+ 1070 i)
|
|
|
|
|
+ 1071 ELSE
|
|
|
|
|
+ 1072 ft := SymTab.ParamType(pn, i);
|
|
|
|
|
+ 1073 isV := SymTab.ParamIsVar(pn, i)
|
|
|
|
|
+ 1074 END;
|
|
|
|
|
+ 1075 IF (at = SymTab.InvalidType)
|
|
|
|
|
+ 1076 OR (ft =
|
|
|
|
|
+ 1077 SymTab.InvalidType) THEN
|
|
|
|
|
+ 1078 ELSIF isV THEN
|
|
|
|
|
+ 1079 IF (SymTab.ClassOf(at)
|
|
|
|
|
+ 1080 = SymTab.ClChar)
|
|
|
|
|
+ 1081 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
+ 1082 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
+ 1083 = SymTab.ClChar)
|
|
|
|
|
+ 1084 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
+ 1085 (* 1-char string
|
|
|
|
|
+ 1086 literal passed to
|
|
|
|
|
+ 1087 a VAR ARRAY OF CHAR *)
|
|
|
|
|
+ 1088 QbeGen.DeclCharStr(qe,
|
|
|
|
|
+ 1089 qa);
|
|
|
|
|
+ 1090 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
+ 1091 "l") THEN
|
|
|
|
|
+ 1092 SemError(233)
|
|
|
|
|
+ 1093 END
|
|
|
|
|
+ 1094 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
|
|
+ 1095 qa) THEN
|
|
|
|
|
+ 1096 SemError(233)
|
|
|
|
|
+ 1097 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
|
|
+ 1098 ft) THEN
|
|
|
|
|
+ 1099 SemError(233)
|
|
|
|
|
+ 1100 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
|
|
+ 1101 "l") THEN
|
|
|
|
|
+ 1102 SemError(233)
|
|
|
|
|
+ 1103 END
|
|
|
|
|
+ 1104 ELSE
|
|
|
|
|
+ 1105 IF (SymTab.ClassOf(at)
|
|
|
|
|
+ 1106 = SymTab.ClChar)
|
|
|
|
|
+ 1107 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
+ 1108 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
+ 1109 = SymTab.ClChar)
|
|
|
|
|
+ 1110 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
+ 1111 (* 1-char string
|
|
|
|
|
+ 1112 literal passed to
|
|
|
|
|
+ 1113 ARRAY OF CHAR *)
|
|
|
|
|
+ 1114 QbeGen.DeclCharStr(qe,
|
|
|
|
|
+ 1115 qa);
|
|
|
|
|
+ 1116 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
+ 1117 "l") THEN
|
|
|
|
|
+ 1118 SemError(233)
|
|
|
|
|
+ 1119 END
|
|
|
|
|
+ 1120 ELSIF NOT SymTab.Assignable(at,
|
|
|
|
|
+ 1121 ft) THEN
|
|
|
|
|
+ 1122 SemError(233)
|
|
|
|
|
+ 1123 ELSE
|
|
|
|
|
+ 1124 conv := (SymTab.ClassOf(
|
|
|
|
|
+ 1125 ft) = SymTab.ClReal)
|
|
|
|
|
+ 1126 AND SymTab.IsIntFamily(at);
|
|
|
|
|
+ 1127 IF conv THEN
|
|
|
|
|
+ 1128 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 1129 IF NOT QbeGen.CallArg(qt,
|
|
|
|
|
+ 1130 "d") THEN
|
|
|
|
|
+ 1131 SemError(233)
|
|
|
|
|
+ 1132 END
|
|
|
|
|
+ 1133 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
|
|
+ 1134 QbeGen.ArgClass(ft)) THEN
|
|
|
|
|
+ 1135 SemError(233)
|
|
|
|
|
+ 1136 END
|
|
|
|
|
+ 1137 END
|
|
|
|
|
+ 1138 END; .) .
|
|
|
|
|
+ 1139 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1140 q, lThen, lElse, lEnd:
|
|
|
|
|
+ 1141 QbeGen.QVal;
|
|
|
|
|
+ 1142 hasElse: BOOLEAN; .)
|
|
|
|
|
+ 1143 = "IF" (. hasElse := FALSE; .)
|
|
|
|
|
+ 1144 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
1145 SemError(214) END;
|
|
1145 SemError(214) END;
|
|
|
1146 QbeGen.NewLabel(lThen);
|
|
1146 QbeGen.NewLabel(lThen);
|
|
|
- 1147 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
- 1148 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
- 1149 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
|
|
- 1150 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 1151 hasElse := TRUE; .)
|
|
|
|
|
- 1152 [ StatSeq ] ]
|
|
|
|
|
- 1153 "END" (. IF hasElse THEN
|
|
|
|
|
- 1154 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
- 1155 ELSE QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 1156 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
- 1157 END; .) .
|
|
|
|
|
- 1158 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1159 q, lTop, lBody, lEnd:
|
|
|
|
|
- 1160 QbeGen.QVal; .)
|
|
|
|
|
- 1161 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1162 QbeGen.NewLabel(lBody);
|
|
|
|
|
- 1163 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1164 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
- 1165 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 1166 SemError(214) END;
|
|
|
|
|
- 1167 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
|
|
- 1168 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 1169 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
|
|
- 1170 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1171 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1172 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 1173 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1174 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1175 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
- 1176 [ StatSeq ]
|
|
|
|
|
- 1177 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 1178 SemError(214) END;
|
|
|
|
|
- 1179 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
|
|
- 1180 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1181 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 1182 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1183 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1184 QbeGen.PushLoop(lEnd);
|
|
|
|
|
|
|
+ 1147 QbeGen.NewLabel(lElse);
|
|
|
|
|
+ 1148 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1149 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
+ 1150 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
+ 1151 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
|
|
+ 1152 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 1153 QbeGen.NewLabel(lElse); .)
|
|
|
|
|
+ 1154 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 1155 SemError(214) END;
|
|
|
|
|
+ 1156 QbeGen.NewLabel(lThen);
|
|
|
|
|
+ 1157 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
+ 1158 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
+ 1159 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
|
|
+ 1160 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 1161 hasElse := TRUE; .)
|
|
|
|
|
+ 1162 [ StatSeq ] ]
|
|
|
|
|
+ 1163 "END" (. IF hasElse THEN
|
|
|
|
|
+ 1164 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
+ 1165 ELSE QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 1166 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
+ 1167 END; .) .
|
|
|
|
|
+ 1168 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1169 q, lTop, lBody, lEnd:
|
|
|
|
|
+ 1170 QbeGen.QVal; .)
|
|
|
|
|
+ 1171 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1172 QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 1173 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1174 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
+ 1175 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 1176 SemError(214) END;
|
|
|
|
|
+ 1177 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
|
|
+ 1178 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 1179 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
|
|
+ 1180 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1181 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1182 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 1183 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1184 QbeGen.NewLabel(lEnd);
|
|
|
1185 QbeGen.EmitLabel(lTop); .)
|
|
1185 QbeGen.EmitLabel(lTop); .)
|
|
|
1186 [ StatSeq ]
|
|
1186 [ StatSeq ]
|
|
|
- 1187 "END" (. QbeGen.Jmp(lTop);
|
|
|
|
|
- 1188 QbeGen.PopLoop;
|
|
|
|
|
- 1189 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1190 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
|
|
- 1191 Runtime direction would need a compare-select; the literal
|
|
|
|
|
- 1192 sign picks cslew/csegew at "DO" time. *)
|
|
|
|
|
- 1193 ForStat (. VAR lv: SymTab.Name;
|
|
|
|
|
- 1194 tlo, thi, tby:
|
|
|
|
|
- 1195 SymTab.TypeIndex;
|
|
|
|
|
- 1196 qlo, qhi, qby, qt, qk, qb:
|
|
|
|
|
- 1197 QbeGen.QVal;
|
|
|
|
|
- 1198 lTop, lBody, lEnd:
|
|
|
|
|
- 1199 QbeGen.QVal;
|
|
|
|
|
- 1200 by: INTEGER;
|
|
|
|
|
- 1201 ok: BOOLEAN; .)
|
|
|
|
|
- 1202 = "FOR" (. by := 1; .)
|
|
|
|
|
- 1203 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
|
|
- 1204 IF NOT ok THEN
|
|
|
|
|
- 1205 SemError(201)
|
|
|
|
|
- 1206 ELSIF (SymTab.SymKind(lv) #
|
|
|
|
|
- 1207 SymTab.KindVar)
|
|
|
|
|
- 1208 AND (SymTab.SymKind(lv) #
|
|
|
|
|
- 1209 SymTab.KindParam) THEN
|
|
|
|
|
- 1210 SemError(220); ok := FALSE
|
|
|
|
|
- 1211 ELSIF NOT SymTab.IsIntFamily(
|
|
|
|
|
- 1212 SymTab.SymType(lv)) THEN
|
|
|
|
|
- 1213 SemError(220); ok := FALSE
|
|
|
|
|
- 1214 END; .)
|
|
|
|
|
- 1215 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
|
|
- 1216 SemError(220); ok := FALSE
|
|
|
|
|
- 1217 END; .)
|
|
|
|
|
- 1218 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
|
|
- 1219 SemError(220); ok := FALSE
|
|
|
|
|
- 1220 END; .)
|
|
|
|
|
- 1221 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
|
|
- 1222 SymTab.InvalidType)
|
|
|
|
|
- 1223 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
|
|
- 1224 SemError(220); ok := FALSE
|
|
|
|
|
- 1225 END;
|
|
|
|
|
- 1226 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
|
|
- 1227 SemError(230); by := 1
|
|
|
|
|
- 1228 ELSIF by = 0 THEN
|
|
|
|
|
- 1229 SemError(220); by := 1
|
|
|
|
|
- 1230 END; .) ]
|
|
|
|
|
- 1231 "DO" (. IF ok THEN
|
|
|
|
|
- 1232 QbeGen.StoreVar(lv, qlo,
|
|
|
|
|
- 1233 FALSE) END;
|
|
|
|
|
- 1234 QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1235 QbeGen.NewLabel(lBody);
|
|
|
|
|
- 1236 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1237 QbeGen.EmitLabel(lTop);
|
|
|
|
|
- 1238 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
|
|
- 1239 QbeGen.NewTemp(qk);
|
|
|
|
|
- 1240 IF by > 0 THEN
|
|
|
|
|
- 1241 QbeGen.Op3("cslew", qk,
|
|
|
|
|
- 1242 qt, qhi, FALSE)
|
|
|
|
|
- 1243 ELSE QbeGen.Op3("csgew", qk,
|
|
|
|
|
- 1244 qt, qhi, FALSE)
|
|
|
|
|
- 1245 END;
|
|
|
|
|
- 1246 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
|
|
- 1247 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 1248 [ StatSeq ]
|
|
|
|
|
- 1249 "END" (. IF ok THEN
|
|
|
|
|
- 1250 QbeGen.LoadVar(lv, FALSE,
|
|
|
|
|
- 1251 qt);
|
|
|
|
|
- 1252 QbeGen.IntStr(by, qb);
|
|
|
|
|
- 1253 QbeGen.NewTemp(qk);
|
|
|
|
|
- 1254 QbeGen.Op3("add", qk,
|
|
|
|
|
- 1255 qt, qb, FALSE);
|
|
|
|
|
- 1256 QbeGen.StoreVar(lv, qk,
|
|
|
|
|
- 1257 FALSE) END;
|
|
|
|
|
- 1258 QbeGen.Jmp(lTop);
|
|
|
|
|
- 1259 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1260 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
|
|
- 1261 qsel, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 1262 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
|
|
- 1263 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
|
|
- 1264 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
|
|
- 1265 [ "ELSE" [ StatSeq ] ]
|
|
|
|
|
- 1266 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1267 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
|
|
- 1268 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
|
|
- 1269 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
|
|
- 1270 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
|
|
- 1271 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
- 1272 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
|
|
- 1273 = (. QbeGen.NewLabel(lBody);
|
|
|
|
|
- 1274 QbeGen.NewLabel(lAfter); .)
|
|
|
|
|
- 1275 CaseLabel<tsel, qsel, lBody>
|
|
|
|
|
- 1276 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
|
|
- 1277 ":" (. QbeGen.Jmp(lAfter);
|
|
|
|
|
- 1278 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 1279 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
|
|
- 1280 QbeGen.EmitLabel(lAfter); .) .
|
|
|
|
|
- 1281 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
- 1282 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
|
|
- 1283 q2, q3, qc, qd, qe:
|
|
|
|
|
- 1284 QbeGen.QVal;
|
|
|
|
|
- 1285 lNext: QbeGen.QVal; .)
|
|
|
|
|
- 1286 = Expr<t2, q2> (. IF (t2 #
|
|
|
|
|
- 1287 SymTab.InvalidType)
|
|
|
|
|
- 1288 AND (tsel #
|
|
|
|
|
- 1289 SymTab.InvalidType)
|
|
|
|
|
- 1290 AND ((SymTab.ClassOf(t2) =
|
|
|
|
|
- 1291 SymTab.ClSet)
|
|
|
|
|
- 1292 OR (SymTab.ClassOf(tsel) =
|
|
|
|
|
- 1293 SymTab.ClSet)) THEN
|
|
|
|
|
- 1294 SemError(230)
|
|
|
|
|
- 1295 ELSIF (t2 #
|
|
|
|
|
- 1296 SymTab.InvalidType)
|
|
|
|
|
- 1297 AND (tsel #
|
|
|
|
|
- 1298 SymTab.InvalidType)
|
|
|
|
|
- 1299 AND NOT SymTab.EqCheck(t2,
|
|
|
|
|
- 1300 tsel) THEN
|
|
|
|
|
- 1301 SemError(213) END;
|
|
|
|
|
- 1302 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 1303 SemError(230);
|
|
|
|
|
- 1304 QbeGen.CopyOp("0", q2)
|
|
|
|
|
- 1305 END;
|
|
|
|
|
- 1306 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 1307 QbeGen.Cmp(SymTab.OpEq,
|
|
|
|
|
- 1308 qsel, q2, qc, FALSE);
|
|
|
|
|
- 1309 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
|
|
- 1310 QbeGen.EmitLabel(lNext); .)
|
|
|
|
|
- 1311 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
|
|
- 1312 SymTab.InvalidType)
|
|
|
|
|
- 1313 AND (tsel #
|
|
|
|
|
- 1314 SymTab.InvalidType)
|
|
|
|
|
- 1315 AND NOT SymTab.EqCheck(t3,
|
|
|
|
|
- 1316 tsel) THEN
|
|
|
|
|
- 1317 SemError(213) END;
|
|
|
|
|
- 1318 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
|
|
- 1319 SemError(230);
|
|
|
|
|
- 1320 QbeGen.CopyOp("0", q3)
|
|
|
|
|
- 1321 END;
|
|
|
|
|
- 1322 QbeGen.Cmp(SymTab.OpGe,
|
|
|
|
|
- 1323 qsel, q2, qc, FALSE);
|
|
|
|
|
- 1324 QbeGen.Cmp(SymTab.OpLe,
|
|
|
|
|
- 1325 qsel, q3, qd, FALSE);
|
|
|
|
|
- 1326 QbeGen.NewTemp(qe);
|
|
|
|
|
- 1327 QbeGen.Op3("and", qe, qc, qd,
|
|
|
|
|
- 1328 FALSE);
|
|
|
|
|
- 1329 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 1330 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
|
|
- 1331 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
|
|
- 1332 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1333 q, qt: QbeGen.QVal;
|
|
|
|
|
- 1334 res: SymTab.TypeIndex;
|
|
|
|
|
- 1335 hadE, conv: BOOLEAN; .)
|
|
|
|
|
- 1336 = "RETURN" (. hadE := FALSE; .)
|
|
|
|
|
- 1337 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
|
|
- 1338 (. conv := FALSE;
|
|
|
|
|
- 1339 IF NOT SymTab.InProc() THEN
|
|
|
|
|
- 1340 SemError(232)
|
|
|
|
|
- 1341 ELSE res := SymTab.CurRes();
|
|
|
|
|
- 1342 IF NOT hadE THEN
|
|
|
|
|
- 1343 IF res #
|
|
|
|
|
- 1344 SymTab.InvalidType THEN
|
|
|
|
|
- 1345 SemError(232)
|
|
|
|
|
- 1346 ELSE QbeGen.EmitRet(q,
|
|
|
|
|
- 1347 FALSE)
|
|
|
|
|
- 1348 END
|
|
|
|
|
- 1349 ELSIF (res =
|
|
|
|
|
- 1350 SymTab.InvalidType)
|
|
|
|
|
- 1351 OR (t #
|
|
|
|
|
- 1352 SymTab.InvalidType)
|
|
|
|
|
- 1353 AND NOT SymTab.Assignable(t,
|
|
|
|
|
- 1354 res) THEN
|
|
|
|
|
- 1355 SemError(232)
|
|
|
|
|
- 1356 ELSE
|
|
|
|
|
- 1357 conv := (SymTab.ClassOf(
|
|
|
|
|
- 1358 res) = SymTab.ClReal)
|
|
|
|
|
- 1359 AND SymTab.IsIntFamily(t);
|
|
|
|
|
- 1360 IF conv THEN
|
|
|
|
|
- 1361 QbeGen.ConvIR(q, qt);
|
|
|
|
|
- 1362 QbeGen.EmitRet(qt, TRUE)
|
|
|
|
|
- 1363 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
|
|
- 1364 END
|
|
|
|
|
- 1365 END
|
|
|
|
|
- 1366 END; .) .
|
|
|
|
|
- 1367 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1368 q: QbeGen.QVal; .)
|
|
|
|
|
- 1369 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
|
|
- 1370 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
|
|
- 1371 Each index descends one level (bounds-checked, trap on breach);
|
|
|
|
|
- 1372 nested levels reload the inner descriptor address. q ends as the
|
|
|
|
|
- 1373 value (scalars), the descriptor address (plain arrays), or the
|
|
|
|
|
- 1374 element address (indexed); sfx marks the indexed form. *)
|
|
|
|
|
- 1375 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
|
|
- 1376 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
|
|
- 1377 (. VAR n, fn, mal: SymTab.Name;
|
|
|
|
|
- 1378 cls: INTEGER;
|
|
|
|
|
- 1379 curT, it, eT, bt:
|
|
|
|
|
- 1380 SymTab.TypeIndex;
|
|
|
|
|
- 1381 iq, ql, qlo, qhi, qe:
|
|
|
|
|
- 1382 QbeGen.QVal;
|
|
|
|
|
- 1383 lo, hi: INTEGER;
|
|
|
|
|
- 1384 fo: INTEGER;
|
|
|
|
|
- 1385 isOpen: BOOLEAN;
|
|
|
|
|
- 1386 qb, cv: QbeGen.QVal; .)
|
|
|
|
|
- 1387 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
|
|
- 1388 sfx := FALSE;
|
|
|
|
|
- 1389 IF NOT SymTab.Lookup(n) THEN
|
|
|
|
|
- 1390 SemError(201);
|
|
|
|
|
- 1391 t := SymTab.InvalidType;
|
|
|
|
|
- 1392 k := -1;
|
|
|
|
|
- 1393 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1394 ELSE
|
|
|
|
|
- 1395 t := SymTab.SymType(n);
|
|
|
|
|
- 1396 k := SymTab.SymKind(n);
|
|
|
|
|
- 1397 IF k = SymTab.KindConst THEN
|
|
|
|
|
- 1398 IF SymTab.Equal(n,
|
|
|
|
|
- 1399 "TRUE") THEN
|
|
|
|
|
- 1400 t := SymTab.BoolType();
|
|
|
|
|
- 1401 QbeGen.CopyOp("1", q)
|
|
|
|
|
- 1402 ELSIF SymTab.Equal(n,
|
|
|
|
|
- 1403 "FALSE") THEN
|
|
|
|
|
- 1404 t := SymTab.BoolType();
|
|
|
|
|
- 1405 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1406 ELSIF SymTab.Equal(n,
|
|
|
|
|
- 1407 "NIL") THEN
|
|
|
|
|
- 1408 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1409 ELSE
|
|
|
|
|
- 1410 cls :=
|
|
|
|
|
- 1411 SymTab.ClassOf(t);
|
|
|
|
|
- 1412 IF (t #
|
|
|
|
|
- 1413 SymTab.InvalidType)
|
|
|
|
|
- 1414 AND ((cls = SymTab.ClInt)
|
|
|
|
|
- 1415 OR (cls
|
|
|
|
|
- 1416 = SymTab.ClChar)
|
|
|
|
|
- 1417 OR (cls
|
|
|
|
|
- 1418 = SymTab.ClReal)
|
|
|
|
|
- 1419 OR (cls
|
|
|
|
|
- 1420 = SymTab.ClNil)) THEN
|
|
|
|
|
- 1421 IF cls = SymTab.ClNil THEN
|
|
|
|
|
- 1422 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1423 ELSIF ((cls
|
|
|
|
|
- 1424 = SymTab.ClInt)
|
|
|
|
|
- 1425 OR (cls
|
|
|
|
|
- 1426 = SymTab.ClChar))
|
|
|
|
|
- 1427 AND SymTab.GetSymVal(n, cv)
|
|
|
|
|
- 1428 AND QbeGen.IsImm(cv) THEN
|
|
|
|
|
- 1429 QbeGen.CopyOp(cv, q)
|
|
|
|
|
- 1430 ELSE
|
|
|
|
|
- 1431 QbeGen.LoadVar(n,
|
|
|
|
|
- 1432 cls = SymTab.ClReal,
|
|
|
|
|
- 1433 q)
|
|
|
|
|
- 1434 END
|
|
|
|
|
- 1435 ELSE
|
|
|
|
|
- 1436 IF t #
|
|
|
|
|
- 1437 SymTab.InvalidType THEN
|
|
|
|
|
- 1438 SemError(230)
|
|
|
|
|
- 1439 END;
|
|
|
|
|
- 1440 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1441 END
|
|
|
|
|
- 1442 END
|
|
|
|
|
- 1443 ELSIF (k = SymTab.KindVar)
|
|
|
|
|
- 1444 OR (k = SymTab.KindParam) THEN
|
|
|
|
|
- 1445 cls :=
|
|
|
|
|
- 1446 SymTab.ClassOf(t);
|
|
|
|
|
- 1447 IF (cls = SymTab.ClInt)
|
|
|
|
|
- 1448 OR (cls = SymTab.ClBool)
|
|
|
|
|
- 1449 OR (cls = SymTab.ClChar)
|
|
|
|
|
- 1450 OR (cls = SymTab.ClUChar)
|
|
|
|
|
- 1451 OR (cls
|
|
|
|
|
- 1452 = SymTab.ClReal) THEN
|
|
|
|
|
- 1453 QbeGen.LoadVar(n,
|
|
|
|
|
- 1454 cls = SymTab.ClReal, q)
|
|
|
|
|
- 1455 ELSIF (cls = SymTab.ClPtr)
|
|
|
|
|
- 1456 OR (cls = SymTab.ClProc) THEN
|
|
|
|
|
- 1457 QbeGen.LoadPtr(n, q)
|
|
|
|
|
- 1458 ELSIF cls = SymTab.ClLong THEN
|
|
|
|
|
- 1459 QbeGen.LoadLong(n, q)
|
|
|
|
|
- 1460 ELSIF (cls
|
|
|
|
|
- 1461 = SymTab.ClArray)
|
|
|
|
|
- 1462 OR (cls
|
|
|
|
|
- 1463 = SymTab.ClSet)
|
|
|
|
|
- 1464 OR (cls
|
|
|
|
|
- 1465 = SymTab.ClRecord)
|
|
|
|
|
|
|
+ 1187 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 1188 SemError(214) END;
|
|
|
|
|
+ 1189 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
|
|
+ 1190 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1191 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 1192 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1193 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1194 QbeGen.PushLoop(lEnd);
|
|
|
|
|
+ 1195 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
+ 1196 [ StatSeq ]
|
|
|
|
|
+ 1197 "END" (. QbeGen.Jmp(lTop);
|
|
|
|
|
+ 1198 QbeGen.PopLoop;
|
|
|
|
|
+ 1199 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1200 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
|
|
+ 1201 Runtime direction would need a compare-select; the literal
|
|
|
|
|
+ 1202 sign picks cslew/csegew at "DO" time. *)
|
|
|
|
|
+ 1203 ForStat (. VAR lv: SymTab.Name;
|
|
|
|
|
+ 1204 tlo, thi, tby:
|
|
|
|
|
+ 1205 SymTab.TypeIndex;
|
|
|
|
|
+ 1206 qlo, qhi, qby, qt, qk, qb:
|
|
|
|
|
+ 1207 QbeGen.QVal;
|
|
|
|
|
+ 1208 lTop, lBody, lEnd:
|
|
|
|
|
+ 1209 QbeGen.QVal;
|
|
|
|
|
+ 1210 by: INTEGER;
|
|
|
|
|
+ 1211 ok: BOOLEAN; .)
|
|
|
|
|
+ 1212 = "FOR" (. by := 1; .)
|
|
|
|
|
+ 1213 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
|
|
+ 1214 IF NOT ok THEN
|
|
|
|
|
+ 1215 SemError(201)
|
|
|
|
|
+ 1216 ELSIF (SymTab.SymKind(lv) #
|
|
|
|
|
+ 1217 SymTab.KindVar)
|
|
|
|
|
+ 1218 AND (SymTab.SymKind(lv) #
|
|
|
|
|
+ 1219 SymTab.KindParam) THEN
|
|
|
|
|
+ 1220 SemError(220); ok := FALSE
|
|
|
|
|
+ 1221 ELSIF NOT SymTab.IsIntFamily(
|
|
|
|
|
+ 1222 SymTab.SymType(lv)) THEN
|
|
|
|
|
+ 1223 SemError(220); ok := FALSE
|
|
|
|
|
+ 1224 END; .)
|
|
|
|
|
+ 1225 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
|
|
+ 1226 SemError(220); ok := FALSE
|
|
|
|
|
+ 1227 END; .)
|
|
|
|
|
+ 1228 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
|
|
+ 1229 SemError(220); ok := FALSE
|
|
|
|
|
+ 1230 END; .)
|
|
|
|
|
+ 1231 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
|
|
+ 1232 SymTab.InvalidType)
|
|
|
|
|
+ 1233 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
|
|
+ 1234 SemError(220); ok := FALSE
|
|
|
|
|
+ 1235 END;
|
|
|
|
|
+ 1236 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
|
|
+ 1237 SemError(230); by := 1
|
|
|
|
|
+ 1238 ELSIF by = 0 THEN
|
|
|
|
|
+ 1239 SemError(220); by := 1
|
|
|
|
|
+ 1240 END; .) ]
|
|
|
|
|
+ 1241 "DO" (. IF ok THEN
|
|
|
|
|
+ 1242 QbeGen.StoreVar(lv, qlo,
|
|
|
|
|
+ 1243 FALSE) END;
|
|
|
|
|
+ 1244 QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1245 QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 1246 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1247 QbeGen.EmitLabel(lTop);
|
|
|
|
|
+ 1248 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
|
|
+ 1249 QbeGen.NewTemp(qk);
|
|
|
|
|
+ 1250 IF by > 0 THEN
|
|
|
|
|
+ 1251 QbeGen.Op3("cslew", qk,
|
|
|
|
|
+ 1252 qt, qhi, FALSE)
|
|
|
|
|
+ 1253 ELSE QbeGen.Op3("csgew", qk,
|
|
|
|
|
+ 1254 qt, qhi, FALSE)
|
|
|
|
|
+ 1255 END;
|
|
|
|
|
+ 1256 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
|
|
+ 1257 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 1258 [ StatSeq ]
|
|
|
|
|
+ 1259 "END" (. IF ok THEN
|
|
|
|
|
+ 1260 QbeGen.LoadVar(lv, FALSE,
|
|
|
|
|
+ 1261 qt);
|
|
|
|
|
+ 1262 QbeGen.IntStr(by, qb);
|
|
|
|
|
+ 1263 QbeGen.NewTemp(qk);
|
|
|
|
|
+ 1264 QbeGen.Op3("add", qk,
|
|
|
|
|
+ 1265 qt, qb, FALSE);
|
|
|
|
|
+ 1266 QbeGen.StoreVar(lv, qk,
|
|
|
|
|
+ 1267 FALSE) END;
|
|
|
|
|
+ 1268 QbeGen.Jmp(lTop);
|
|
|
|
|
+ 1269 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1270 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
|
|
+ 1271 qsel, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 1272 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
|
|
+ 1273 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
|
|
+ 1274 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
|
|
+ 1275 [ "ELSE" [ StatSeq ] ]
|
|
|
|
|
+ 1276 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1277 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
|
|
+ 1278 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
|
|
+ 1279 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
|
|
+ 1280 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
|
|
+ 1281 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
+ 1282 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
|
|
+ 1283 = (. QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 1284 QbeGen.NewLabel(lAfter); .)
|
|
|
|
|
+ 1285 CaseLabel<tsel, qsel, lBody>
|
|
|
|
|
+ 1286 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
|
|
+ 1287 ":" (. QbeGen.Jmp(lAfter);
|
|
|
|
|
+ 1288 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 1289 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
|
|
+ 1290 QbeGen.EmitLabel(lAfter); .) .
|
|
|
|
|
+ 1291 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
+ 1292 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
|
|
+ 1293 q2, q3, qc, qd, qe:
|
|
|
|
|
+ 1294 QbeGen.QVal;
|
|
|
|
|
+ 1295 lNext: QbeGen.QVal; .)
|
|
|
|
|
+ 1296 = Expr<t2, q2> (. IF (t2 #
|
|
|
|
|
+ 1297 SymTab.InvalidType)
|
|
|
|
|
+ 1298 AND (tsel #
|
|
|
|
|
+ 1299 SymTab.InvalidType)
|
|
|
|
|
+ 1300 AND ((SymTab.ClassOf(t2) =
|
|
|
|
|
+ 1301 SymTab.ClSet)
|
|
|
|
|
+ 1302 OR (SymTab.ClassOf(tsel) =
|
|
|
|
|
+ 1303 SymTab.ClSet)) THEN
|
|
|
|
|
+ 1304 SemError(230)
|
|
|
|
|
+ 1305 ELSIF (t2 #
|
|
|
|
|
+ 1306 SymTab.InvalidType)
|
|
|
|
|
+ 1307 AND (tsel #
|
|
|
|
|
+ 1308 SymTab.InvalidType)
|
|
|
|
|
+ 1309 AND NOT SymTab.EqCheck(t2,
|
|
|
|
|
+ 1310 tsel) THEN
|
|
|
|
|
+ 1311 SemError(213) END;
|
|
|
|
|
+ 1312 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 1313 SemError(230);
|
|
|
|
|
+ 1314 QbeGen.CopyOp("0", q2)
|
|
|
|
|
+ 1315 END;
|
|
|
|
|
+ 1316 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 1317 QbeGen.Cmp(SymTab.OpEq,
|
|
|
|
|
+ 1318 qsel, q2, qc, FALSE);
|
|
|
|
|
+ 1319 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
|
|
+ 1320 QbeGen.EmitLabel(lNext); .)
|
|
|
|
|
+ 1321 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
|
|
+ 1322 SymTab.InvalidType)
|
|
|
|
|
+ 1323 AND (tsel #
|
|
|
|
|
+ 1324 SymTab.InvalidType)
|
|
|
|
|
+ 1325 AND NOT SymTab.EqCheck(t3,
|
|
|
|
|
+ 1326 tsel) THEN
|
|
|
|
|
+ 1327 SemError(213) END;
|
|
|
|
|
+ 1328 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
|
|
+ 1329 SemError(230);
|
|
|
|
|
+ 1330 QbeGen.CopyOp("0", q3)
|
|
|
|
|
+ 1331 END;
|
|
|
|
|
+ 1332 QbeGen.Cmp(SymTab.OpGe,
|
|
|
|
|
+ 1333 qsel, q2, qc, FALSE);
|
|
|
|
|
+ 1334 QbeGen.Cmp(SymTab.OpLe,
|
|
|
|
|
+ 1335 qsel, q3, qd, FALSE);
|
|
|
|
|
+ 1336 QbeGen.NewTemp(qe);
|
|
|
|
|
+ 1337 QbeGen.Op3("and", qe, qc, qd,
|
|
|
|
|
+ 1338 FALSE);
|
|
|
|
|
+ 1339 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 1340 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
|
|
+ 1341 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
|
|
+ 1342 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1343 q, qt: QbeGen.QVal;
|
|
|
|
|
+ 1344 res: SymTab.TypeIndex;
|
|
|
|
|
+ 1345 hadE, conv: BOOLEAN; .)
|
|
|
|
|
+ 1346 = "RETURN" (. hadE := FALSE; .)
|
|
|
|
|
+ 1347 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
|
|
+ 1348 (. conv := FALSE;
|
|
|
|
|
+ 1349 IF NOT SymTab.InProc() THEN
|
|
|
|
|
+ 1350 SemError(232)
|
|
|
|
|
+ 1351 ELSE res := SymTab.CurRes();
|
|
|
|
|
+ 1352 IF NOT hadE THEN
|
|
|
|
|
+ 1353 IF res #
|
|
|
|
|
+ 1354 SymTab.InvalidType THEN
|
|
|
|
|
+ 1355 SemError(232)
|
|
|
|
|
+ 1356 ELSE QbeGen.EmitRet(q,
|
|
|
|
|
+ 1357 FALSE)
|
|
|
|
|
+ 1358 END
|
|
|
|
|
+ 1359 ELSIF (res =
|
|
|
|
|
+ 1360 SymTab.InvalidType)
|
|
|
|
|
+ 1361 OR (t #
|
|
|
|
|
+ 1362 SymTab.InvalidType)
|
|
|
|
|
+ 1363 AND NOT SymTab.Assignable(t,
|
|
|
|
|
+ 1364 res) THEN
|
|
|
|
|
+ 1365 SemError(232)
|
|
|
|
|
+ 1366 ELSE
|
|
|
|
|
+ 1367 conv := (SymTab.ClassOf(
|
|
|
|
|
+ 1368 res) = SymTab.ClReal)
|
|
|
|
|
+ 1369 AND SymTab.IsIntFamily(t);
|
|
|
|
|
+ 1370 IF conv THEN
|
|
|
|
|
+ 1371 QbeGen.ConvIR(q, qt);
|
|
|
|
|
+ 1372 QbeGen.EmitRet(qt, TRUE)
|
|
|
|
|
+ 1373 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
|
|
+ 1374 END
|
|
|
|
|
+ 1375 END
|
|
|
|
|
+ 1376 END; .) .
|
|
|
|
|
+ 1377 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1378 q: QbeGen.QVal; .)
|
|
|
|
|
+ 1379 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
|
|
+ 1380 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
|
|
+ 1381 Each index descends one level (bounds-checked, trap on breach);
|
|
|
|
|
+ 1382 nested levels reload the inner descriptor address. q ends as the
|
|
|
|
|
+ 1383 value (scalars), the descriptor address (plain arrays), or the
|
|
|
|
|
+ 1384 element address (indexed); sfx marks the indexed form. *)
|
|
|
|
|
+ 1385 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
|
|
+ 1386 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
|
|
+ 1387 (. VAR n, fn, mal: SymTab.Name;
|
|
|
|
|
+ 1388 cls: INTEGER;
|
|
|
|
|
+ 1389 curT, it, eT, bt:
|
|
|
|
|
+ 1390 SymTab.TypeIndex;
|
|
|
|
|
+ 1391 iq, ql, qlo, qhi, qe:
|
|
|
|
|
+ 1392 QbeGen.QVal;
|
|
|
|
|
+ 1393 lo, hi: INTEGER;
|
|
|
|
|
+ 1394 fo: INTEGER;
|
|
|
|
|
+ 1395 isOpen: BOOLEAN;
|
|
|
|
|
+ 1396 qb, cv: QbeGen.QVal; .)
|
|
|
|
|
+ 1397 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
|
|
+ 1398 sfx := FALSE;
|
|
|
|
|
+ 1399 IF NOT SymTab.Lookup(n) THEN
|
|
|
|
|
+ 1400 SemError(201);
|
|
|
|
|
+ 1401 t := SymTab.InvalidType;
|
|
|
|
|
+ 1402 k := -1;
|
|
|
|
|
+ 1403 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1404 ELSE
|
|
|
|
|
+ 1405 t := SymTab.SymType(n);
|
|
|
|
|
+ 1406 k := SymTab.SymKind(n);
|
|
|
|
|
+ 1407 IF k = SymTab.KindConst THEN
|
|
|
|
|
+ 1408 IF SymTab.Equal(n,
|
|
|
|
|
+ 1409 "TRUE") THEN
|
|
|
|
|
+ 1410 t := SymTab.BoolType();
|
|
|
|
|
+ 1411 QbeGen.CopyOp("1", q)
|
|
|
|
|
+ 1412 ELSIF SymTab.Equal(n,
|
|
|
|
|
+ 1413 "FALSE") THEN
|
|
|
|
|
+ 1414 t := SymTab.BoolType();
|
|
|
|
|
+ 1415 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1416 ELSIF SymTab.Equal(n,
|
|
|
|
|
+ 1417 "NIL") THEN
|
|
|
|
|
+ 1418 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1419 ELSE
|
|
|
|
|
+ 1420 cls :=
|
|
|
|
|
+ 1421 SymTab.ClassOf(t);
|
|
|
|
|
+ 1422 IF (t #
|
|
|
|
|
+ 1423 SymTab.InvalidType)
|
|
|
|
|
+ 1424 AND ((cls = SymTab.ClInt)
|
|
|
|
|
+ 1425 OR (cls
|
|
|
|
|
+ 1426 = SymTab.ClChar)
|
|
|
|
|
+ 1427 OR (cls
|
|
|
|
|
+ 1428 = SymTab.ClEnum)
|
|
|
|
|
+ 1429 OR (cls
|
|
|
|
|
+ 1430 = SymTab.ClReal)
|
|
|
|
|
+ 1431 OR (cls
|
|
|
|
|
+ 1432 = SymTab.ClNil)) THEN
|
|
|
|
|
+ 1433 IF cls = SymTab.ClNil THEN
|
|
|
|
|
+ 1434 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1435 ELSIF ((cls
|
|
|
|
|
+ 1436 = SymTab.ClInt)
|
|
|
|
|
+ 1437 OR (cls
|
|
|
|
|
+ 1438 = SymTab.ClChar)
|
|
|
|
|
+ 1439 OR (cls
|
|
|
|
|
+ 1440 = SymTab.ClEnum))
|
|
|
|
|
+ 1441 AND SymTab.GetSymVal(n, cv)
|
|
|
|
|
+ 1442 AND QbeGen.IsImm(cv) THEN
|
|
|
|
|
+ 1443 QbeGen.CopyOp(cv, q)
|
|
|
|
|
+ 1444 ELSE
|
|
|
|
|
+ 1445 QbeGen.LoadVar(n,
|
|
|
|
|
+ 1446 cls = SymTab.ClReal,
|
|
|
|
|
+ 1447 q)
|
|
|
|
|
+ 1448 END
|
|
|
|
|
+ 1449 ELSE
|
|
|
|
|
+ 1450 IF t #
|
|
|
|
|
+ 1451 SymTab.InvalidType THEN
|
|
|
|
|
+ 1452 SemError(230)
|
|
|
|
|
+ 1453 END;
|
|
|
|
|
+ 1454 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1455 END
|
|
|
|
|
+ 1456 END
|
|
|
|
|
+ 1457 ELSIF (k = SymTab.KindVar)
|
|
|
|
|
+ 1458 OR (k = SymTab.KindParam) THEN
|
|
|
|
|
+ 1459 cls :=
|
|
|
|
|
+ 1460 SymTab.ClassOf(t);
|
|
|
|
|
+ 1461 IF (cls = SymTab.ClInt)
|
|
|
|
|
+ 1462 OR (cls = SymTab.ClBool)
|
|
|
|
|
+ 1463 OR (cls = SymTab.ClChar)
|
|
|
|
|
+ 1464 OR (cls = SymTab.ClUChar)
|
|
|
|
|
+ 1465 OR (cls = SymTab.ClEnum)
|
|
|
1466 OR (cls
|
|
1466 OR (cls
|
|
|
- 1467 = SymTab.ClUStr)
|
|
|
|
|
- 1468 OR (cls
|
|
|
|
|
- 1469 = SymTab.ClClass) THEN
|
|
|
|
|
- 1470 QbeGen.AddrOf(n, q)
|
|
|
|
|
- 1471 ELSE SemError(230);
|
|
|
|
|
- 1472 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1473 END
|
|
|
|
|
- 1474 ELSE QbeGen.CopyOp("0", q);
|
|
|
|
|
- 1475 IF k = SymTab.KindImport THEN
|
|
|
|
|
- 1476 SemError(230)
|
|
|
|
|
- 1477 ELSIF k =
|
|
|
|
|
- 1478 SymTab.KindProc THEN
|
|
|
|
|
- 1479 (* bare procedure name:
|
|
|
|
|
- 1480 a following ArgList
|
|
|
|
|
- 1481 makes it a call;
|
|
|
|
|
- 1482 otherwise Fact
|
|
|
|
|
- 1483 reports 230 *)
|
|
|
|
|
- 1484 ELSE
|
|
|
|
|
- 1485 IF k = SymTab.KindField THEN
|
|
|
|
|
- 1486 IF QbeGen.TopWith(qb) THEN
|
|
|
|
|
- 1487 fo :=
|
|
|
|
|
- 1488 SymTab.FieldOffset(
|
|
|
|
|
- 1489 SymTab.FieldOwner(n),
|
|
|
|
|
- 1490 n);
|
|
|
|
|
- 1491 QbeGen.FieldAddr(qb,
|
|
|
|
|
- 1492 fo, q);
|
|
|
|
|
- 1493 sfx := TRUE
|
|
|
|
|
- 1494 ELSE SemError(230);
|
|
|
|
|
- 1495 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1496 END
|
|
|
|
|
- 1497 END
|
|
|
|
|
- 1498 END
|
|
|
|
|
- 1499 END
|
|
|
|
|
- 1500 END; .)
|
|
|
|
|
- 1501 { "[" Expr<it, iq>
|
|
|
|
|
- 1502 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1503 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1504 SymTab.ClArray THEN
|
|
|
|
|
- 1505 SemError(217);
|
|
|
|
|
- 1506 t := SymTab.InvalidType
|
|
|
|
|
- 1507 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
- 1508 AND (SymTab.ClassOf(it) #
|
|
|
|
|
- 1509 SymTab.ClChar) THEN
|
|
|
|
|
- 1510 SemError(218);
|
|
|
|
|
- 1511 t := SymTab.InvalidType
|
|
|
|
|
- 1512 ELSE
|
|
|
|
|
- 1513 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
- 1514 isOpen :=
|
|
|
|
|
- 1515 SymTab.IsOpenArray(t);
|
|
|
|
|
- 1516 IF isOpen THEN
|
|
|
|
|
- 1517 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
- 1518 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
- 1519 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
- 1520 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
- 1521 END
|
|
|
|
|
- 1522 ELSE
|
|
|
|
|
- 1523 lo := SymTab.ArrayLo(t);
|
|
|
|
|
- 1524 hi := SymTab.ArrayHi(t);
|
|
|
|
|
- 1525 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
- 1526 hi := hi + 1
|
|
|
|
|
- 1527 END;
|
|
|
|
|
- 1528 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
- 1529 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
- 1530 END;
|
|
|
|
|
- 1531 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
- 1532 qhi);
|
|
|
|
|
- 1533 eT := SymTab.ArrayElem(t);
|
|
|
|
|
- 1534 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
- 1535 t, qe);
|
|
|
|
|
- 1536 IF SymTab.ClassOf(eT) =
|
|
|
|
|
- 1537 SymTab.ClArray THEN
|
|
|
|
|
- 1538 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
- 1539 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
- 1540 END;
|
|
|
|
|
- 1541 t := eT; sfx := TRUE
|
|
|
|
|
- 1542 END; .)
|
|
|
|
|
- 1543 { "," Expr<it, iq>
|
|
|
|
|
- 1544 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1545 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1546 SymTab.ClArray THEN
|
|
|
|
|
- 1547 SemError(217);
|
|
|
|
|
- 1548 t := SymTab.InvalidType
|
|
|
|
|
- 1549 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
- 1550 AND (SymTab.ClassOf(it) #
|
|
|
|
|
- 1551 SymTab.ClChar) THEN
|
|
|
|
|
- 1552 SemError(218);
|
|
|
|
|
- 1553 t := SymTab.InvalidType
|
|
|
|
|
- 1554 ELSE
|
|
|
|
|
- 1555 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
- 1556 isOpen :=
|
|
|
|
|
- 1557 SymTab.IsOpenArray(t);
|
|
|
|
|
- 1558 IF isOpen THEN
|
|
|
|
|
- 1559 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
- 1560 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
- 1561 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
- 1562 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
- 1563 END
|
|
|
|
|
- 1564 ELSE
|
|
|
|
|
- 1565 lo := SymTab.ArrayLo(t);
|
|
|
|
|
- 1566 hi := SymTab.ArrayHi(t);
|
|
|
|
|
- 1567 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
- 1568 hi := hi + 1
|
|
|
|
|
- 1569 END;
|
|
|
|
|
- 1570 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
- 1571 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
- 1572 END;
|
|
|
|
|
- 1573 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
- 1574 qhi);
|
|
|
|
|
- 1575 eT := SymTab.ArrayElem(t);
|
|
|
|
|
- 1576 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
- 1577 t, qe);
|
|
|
|
|
- 1578 IF SymTab.ClassOf(eT) =
|
|
|
|
|
- 1579 SymTab.ClArray THEN
|
|
|
|
|
- 1580 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
- 1581 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
- 1582 END;
|
|
|
|
|
- 1583 t := eT; sfx := TRUE
|
|
|
|
|
- 1584 END; .) }
|
|
|
|
|
- 1585 "]"
|
|
|
|
|
- 1586 | "." GetIdent<fn>
|
|
|
|
|
- 1587 (. IF k = SymTab.KindModule THEN
|
|
|
|
|
- 1588 (* qualified L.x: materialize
|
|
|
|
|
- 1589 the export, then load it *)
|
|
|
|
|
- 1590 IF NOT SymTab.MaterializeAlias(n,
|
|
|
|
|
- 1591 fn, mal) THEN
|
|
|
|
|
- 1592 SemError(201);
|
|
|
|
|
- 1593 t := SymTab.InvalidType;
|
|
|
|
|
- 1594 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1595 ELSE
|
|
|
|
|
- 1596 QbeGen.CopyOp(mal, qn);
|
|
|
|
|
- 1597 t := SymTab.SymType(mal);
|
|
|
|
|
- 1598 k := SymTab.SymKind(mal);
|
|
|
|
|
- 1599 sfx := FALSE;
|
|
|
|
|
- 1600 IF k = SymTab.KindProc THEN
|
|
|
|
|
- 1601 (* call: ArgList supplies
|
|
|
|
|
- 1602 the value *)
|
|
|
|
|
- 1603 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1604 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
|
|
- 1605 mal, t, k, q) THEN
|
|
|
|
|
- 1606 SemError(230);
|
|
|
|
|
- 1607 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1608 END
|
|
|
|
|
- 1609 END
|
|
|
|
|
- 1610 ELSIF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1611 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
- 1612 SymTab.ClRecord)
|
|
|
|
|
- 1613 AND (SymTab.ClassOf(t) #
|
|
|
|
|
- 1614 SymTab.ClClass) THEN
|
|
|
|
|
- 1615 SemError(215);
|
|
|
|
|
- 1616 t := SymTab.InvalidType
|
|
|
|
|
- 1617 ELSIF NOT SymTab.FieldExists(t,
|
|
|
|
|
- 1618 fn) THEN
|
|
|
|
|
- 1619 SemError(216);
|
|
|
|
|
- 1620 t := SymTab.InvalidType
|
|
|
|
|
- 1621 ELSE
|
|
|
|
|
- 1622 fo := SymTab.FieldOffset(t,
|
|
|
|
|
- 1623 fn);
|
|
|
|
|
- 1624 t := SymTab.FieldType(t, fn);
|
|
|
|
|
- 1625 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
- 1626 (* array fields are inline:
|
|
|
|
|
- 1627 the field address is the
|
|
|
|
|
- 1628 descriptor, like records *)
|
|
|
|
|
- 1629 QbeGen.CopyOp(qe, q);
|
|
|
|
|
- 1630 sfx := TRUE
|
|
|
|
|
- 1631 END; .)
|
|
|
|
|
- 1632 | "^"
|
|
|
|
|
- 1633 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1634 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1635 SymTab.ClPtr THEN
|
|
|
|
|
- 1636 SemError(219);
|
|
|
|
|
- 1637 t := SymTab.InvalidType
|
|
|
|
|
- 1638 ELSE
|
|
|
|
|
- 1639 bt := SymTab.PtrBase(t);
|
|
|
|
|
- 1640 IF bt = SymTab.InvalidType THEN
|
|
|
|
|
- 1641 ELSE
|
|
|
|
|
- 1642 IF sfx THEN
|
|
|
|
|
- 1643 QbeGen.ElemLoad(q, t,
|
|
|
|
|
- 1644 qb);
|
|
|
|
|
- 1645 QbeGen.CopyOp(qb, q)
|
|
|
|
|
- 1646 END;
|
|
|
|
|
- 1647 t := bt;
|
|
|
|
|
- 1648 (* q holds the pointee
|
|
|
|
|
- 1649 address: Fact loads
|
|
|
|
|
- 1650 scalars/pointers and uses
|
|
|
|
|
- 1651 the address for
|
|
|
|
|
- 1652 aggregates; the VAR-actual
|
|
|
|
|
- 1653 note is q itself. *)
|
|
|
|
|
- 1654 sfx := TRUE
|
|
|
|
|
- 1655 END
|
|
|
|
|
- 1656 END; .) } .
|
|
|
|
|
- 1657 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1658 (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
- 1659 op: INTEGER;
|
|
|
|
|
- 1660 q2, qt, wl: QbeGen.QVal;
|
|
|
|
|
- 1661 isR: BOOLEAN; .)
|
|
|
|
|
- 1662 = SimExpr<t, q>
|
|
|
|
|
- 1663 [ Rel<op> SimExpr<t2, q2>
|
|
|
|
|
- 1664 (. IF op = SymTab.OpIn THEN
|
|
|
|
|
- 1665 IF SymTab.InCheck(t, t2) THEN
|
|
|
|
|
- 1666 IF (t = SymTab.InvalidType)
|
|
|
|
|
- 1667 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
- 1668 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1669 ELSE
|
|
|
|
|
- 1670 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
|
|
- 1671 SymTab.SetCount(t2), qt);
|
|
|
|
|
- 1672 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1673 END
|
|
|
|
|
- 1674 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
|
|
- 1675 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1676 END
|
|
|
|
|
- 1677 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
|
|
- 1678 IF (t = SymTab.InvalidType)
|
|
|
|
|
- 1679 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
- 1680 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1681 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
|
|
- 1682 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
|
|
- 1683 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
|
|
- 1684 AND (op # SymTab.OpNeq2) THEN
|
|
|
|
|
- 1685 SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
- 1686 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1687 ELSE
|
|
|
|
|
- 1688 QbeGen.CmpL(op, q, q2, qt);
|
|
|
|
|
- 1689 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1690 END
|
|
|
|
|
- 1691 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 1692 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 1693 QbeGen.CmpSet(op, q, q2,
|
|
|
|
|
- 1694 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
|
|
- 1695 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1696 ELSIF SymTab.IsLongFamily(t)
|
|
|
|
|
- 1697 OR SymTab.IsLongFamily(t2) THEN
|
|
|
|
|
- 1698 IF SymTab.IsIntFamily(t) THEN
|
|
|
|
|
- 1699 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
|
|
- 1700 END;
|
|
|
|
|
- 1701 IF SymTab.IsIntFamily(t2) THEN
|
|
|
|
|
- 1702 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
|
|
- 1703 END;
|
|
|
|
|
- 1704 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
|
|
- 1705 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1706 ELSE
|
|
|
|
|
- 1707 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 1708 t := SymTab.BoolType();
|
|
|
|
|
- 1709 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
|
|
- 1710 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1711 END
|
|
|
|
|
- 1712 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
- 1713 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1714 END; .) ] .
|
|
|
|
|
- 1715 Rel<VAR op: INTEGER>
|
|
|
|
|
- 1716 = "=" (. op := SymTab.OpEq; .)
|
|
|
|
|
- 1717 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
|
|
- 1718 | "<" (. op := SymTab.OpLt; .)
|
|
|
|
|
- 1719 | "<=" (. op := SymTab.OpLe; .)
|
|
|
|
|
- 1720 | ">" (. op := SymTab.OpGt; .)
|
|
|
|
|
- 1721 | ">=" (. op := SymTab.OpGe; .)
|
|
|
|
|
- 1722 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
|
|
- 1723 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1724 (. VAR t2, res2, lt, rt:
|
|
|
|
|
- 1725 SymTab.TypeIndex;
|
|
|
|
|
- 1726 op: INTEGER;
|
|
|
|
|
- 1727 q2, qt, wq, qf:
|
|
|
|
|
- 1728 QbeGen.QVal;
|
|
|
|
|
- 1729 neg, isR, isL, folded:
|
|
|
|
|
- 1730 BOOLEAN;
|
|
|
|
|
- 1731 lw, rw, mw: CARDINAL;
|
|
|
|
|
- 1732 lTrue, lNext, lDone, qr, qs:
|
|
|
|
|
- 1733 QbeGen.QVal; .)
|
|
|
|
|
- 1734 = (. neg := FALSE; .)
|
|
|
|
|
- 1735 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
|
|
- 1736 Term<t, q> (. IF neg THEN
|
|
|
|
|
- 1737 IF QbeGen.IsImm(q) THEN
|
|
|
|
|
- 1738 QbeGen.NegFold(q, q)
|
|
|
|
|
- 1739 ELSE QbeGen.NewTemp(qt);
|
|
|
|
|
- 1740 QbeGen.NegQ(q, qt,
|
|
|
|
|
- 1741 SymTab.ClassOf(t)
|
|
|
|
|
- 1742 = SymTab.ClReal);
|
|
|
|
|
- 1743 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1744 END
|
|
|
|
|
- 1745 END; .)
|
|
|
|
|
- 1746 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
- 1747 QbeGen.DelayBegin END; .)
|
|
|
|
|
- 1748 Term<t2, q2> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
- 1749 QbeGen.DelayEnd END; .)
|
|
|
|
|
- 1750 (. IF op = SymTab.OpOr THEN
|
|
|
|
|
- 1751 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
|
|
- 1752 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 1753 t := SymTab.BoolType()
|
|
|
|
|
- 1754 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 1755 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1756 QbeGen.Slot4(qs);
|
|
|
|
|
- 1757 QbeGen.NewLabel(lTrue);
|
|
|
|
|
- 1758 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 1759 QbeGen.NewLabel(lDone);
|
|
|
|
|
- 1760 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
|
|
- 1761 QbeGen.EmitLabel(lTrue);
|
|
|
|
|
- 1762 QbeGen.StoreW(qs, "1");
|
|
|
|
|
- 1763 QbeGen.Jmp(lDone);
|
|
|
|
|
- 1764 QbeGen.EmitLabel(lNext);
|
|
|
|
|
- 1765 QbeGen.DelayFlush;
|
|
|
|
|
- 1766 QbeGen.StoreW(qs, q2);
|
|
|
|
|
- 1767 QbeGen.Jmp(lDone);
|
|
|
|
|
- 1768 QbeGen.EmitLabel(lDone);
|
|
|
|
|
- 1769 QbeGen.LoadW(qs, qr);
|
|
|
|
|
- 1770 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 1771 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1772 END
|
|
|
|
|
- 1773 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
- 1774 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 1775 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 1776 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 1777 mw := lw;
|
|
|
|
|
- 1778 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 1779 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 1780 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
|
|
- 1781 ELSE
|
|
|
|
|
- 1782 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
|
|
- 1783 END;
|
|
|
|
|
- 1784 t := SymTab.NewSet(
|
|
|
|
|
- 1785 SymTab.NewSubR(0,
|
|
|
|
|
- 1786 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 1787 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1788 ELSE
|
|
|
|
|
- 1789 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
- 1790 lt := t; rt := t2; t := res2
|
|
|
|
|
- 1791 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 1792 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1793 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
- 1794 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 1795 folded := FALSE;
|
|
|
|
|
- 1796 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
- 1797 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 1798 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 1799 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
|
|
- 1800 ELSE
|
|
|
|
|
- 1801 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
|
|
- 1802 END
|
|
|
|
|
- 1803 END;
|
|
|
|
|
- 1804 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
- 1805 ELSE
|
|
|
|
|
- 1806 IF isL THEN
|
|
|
|
|
- 1807 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
- 1808 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
- 1809 END;
|
|
|
|
|
- 1810 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
- 1811 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
- 1812 END;
|
|
|
|
|
- 1813 QbeGen.NewTemp(qt);
|
|
|
|
|
- 1814 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 1815 QbeGen.Op3L("add", qt, q, q2)
|
|
|
|
|
- 1816 ELSE
|
|
|
|
|
- 1817 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
|
|
- 1818 END
|
|
|
|
|
- 1819 ELSE
|
|
|
|
|
- 1820 QbeGen.NewTemp(qt);
|
|
|
|
|
- 1821 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 1822 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
|
|
- 1823 ELSE
|
|
|
|
|
- 1824 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
|
|
- 1825 END
|
|
|
|
|
- 1826 END;
|
|
|
|
|
- 1827 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1828 END
|
|
|
|
|
- 1829 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1830 END
|
|
|
|
|
- 1831 END; .) } .
|
|
|
|
|
- 1832 AddOp<VAR op: INTEGER>
|
|
|
|
|
- 1833 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
- 1834 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
- 1835 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
- 1836 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1837 (. VAR t2, res2, lt, rt:
|
|
|
|
|
- 1838 SymTab.TypeIndex;
|
|
|
|
|
- 1839 op: INTEGER;
|
|
|
|
|
- 1840 q2, qt, wq, qf:
|
|
|
|
|
- 1841 QbeGen.QVal;
|
|
|
|
|
- 1842 isR, isL, folded: BOOLEAN;
|
|
|
|
|
- 1843 lw, rw, mw: CARDINAL;
|
|
|
|
|
- 1844 lNext, lFalse, lDone, qr, qs:
|
|
|
|
|
- 1845 QbeGen.QVal; .)
|
|
|
|
|
- 1846 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 1847 QbeGen.DelayBegin END; .)
|
|
|
|
|
- 1848 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 1849 QbeGen.DelayEnd END; .)
|
|
|
|
|
- 1850 (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 1851 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
|
|
- 1852 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 1853 t := SymTab.BoolType()
|
|
|
|
|
- 1854 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 1855 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1856 QbeGen.Slot4(qs);
|
|
|
|
|
- 1857 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 1858 QbeGen.NewLabel(lFalse);
|
|
|
|
|
- 1859 QbeGen.NewLabel(lDone);
|
|
|
|
|
- 1860 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
|
|
- 1861 QbeGen.EmitLabel(lNext);
|
|
|
|
|
- 1862 QbeGen.DelayFlush;
|
|
|
|
|
- 1863 QbeGen.StoreW(qs, q2);
|
|
|
|
|
- 1864 QbeGen.Jmp(lDone);
|
|
|
|
|
- 1865 QbeGen.EmitLabel(lFalse);
|
|
|
|
|
- 1866 QbeGen.StoreW(qs, "0");
|
|
|
|
|
- 1867 QbeGen.Jmp(lDone);
|
|
|
|
|
- 1868 QbeGen.EmitLabel(lDone);
|
|
|
|
|
- 1869 QbeGen.LoadW(qs, qr);
|
|
|
|
|
- 1870 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 1871 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1872 END
|
|
|
|
|
- 1873 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
- 1874 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 1875 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 1876 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 1877 mw := lw;
|
|
|
|
|
- 1878 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 1879 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 1880 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
- 1881 ELSE
|
|
|
|
|
- 1882 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
- 1883 END;
|
|
|
|
|
- 1884 t := SymTab.NewSet(
|
|
|
|
|
- 1885 SymTab.NewSubR(0,
|
|
|
|
|
- 1886 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 1887 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1888 ELSE
|
|
|
|
|
- 1889 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
- 1890 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
- 1891 res2) THEN
|
|
|
|
|
- 1892 lt := t; rt := t2; t := res2
|
|
|
|
|
- 1893 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 1894 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1895 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
- 1896 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 1897 folded := FALSE;
|
|
|
|
|
- 1898 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
- 1899 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 1900 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 1901 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
|
|
- 1902 ELSIF op = SymTab.OpDiv THEN
|
|
|
|
|
- 1903 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
|
|
- 1904 ELSIF op = SymTab.OpMod THEN
|
|
|
|
|
- 1905 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
|
|
- 1906 END
|
|
|
|
|
- 1907 END;
|
|
|
|
|
- 1908 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
- 1909 ELSE
|
|
|
|
|
- 1910 IF isL THEN
|
|
|
|
|
- 1911 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
- 1912 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
- 1913 END;
|
|
|
|
|
- 1914 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
- 1915 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
- 1916 END;
|
|
|
|
|
- 1917 QbeGen.NewTemp(qt);
|
|
|
|
|
|
|
+ 1467 = SymTab.ClReal) THEN
|
|
|
|
|
+ 1468 QbeGen.LoadVar(n,
|
|
|
|
|
+ 1469 cls = SymTab.ClReal, q)
|
|
|
|
|
+ 1470 ELSIF (cls = SymTab.ClPtr)
|
|
|
|
|
+ 1471 OR (cls = SymTab.ClProc) THEN
|
|
|
|
|
+ 1472 QbeGen.LoadPtr(n, q)
|
|
|
|
|
+ 1473 ELSIF cls = SymTab.ClLong THEN
|
|
|
|
|
+ 1474 QbeGen.LoadLong(n, q)
|
|
|
|
|
+ 1475 ELSIF (cls
|
|
|
|
|
+ 1476 = SymTab.ClArray)
|
|
|
|
|
+ 1477 OR (cls
|
|
|
|
|
+ 1478 = SymTab.ClSet)
|
|
|
|
|
+ 1479 OR (cls
|
|
|
|
|
+ 1480 = SymTab.ClRecord)
|
|
|
|
|
+ 1481 OR (cls
|
|
|
|
|
+ 1482 = SymTab.ClUStr)
|
|
|
|
|
+ 1483 OR (cls
|
|
|
|
|
+ 1484 = SymTab.ClClass) THEN
|
|
|
|
|
+ 1485 QbeGen.AddrOf(n, q)
|
|
|
|
|
+ 1486 ELSE SemError(230);
|
|
|
|
|
+ 1487 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1488 END
|
|
|
|
|
+ 1489 ELSE QbeGen.CopyOp("0", q);
|
|
|
|
|
+ 1490 IF k = SymTab.KindImport THEN
|
|
|
|
|
+ 1491 SemError(230)
|
|
|
|
|
+ 1492 ELSIF k =
|
|
|
|
|
+ 1493 SymTab.KindProc THEN
|
|
|
|
|
+ 1494 (* bare procedure name:
|
|
|
|
|
+ 1495 a following ArgList
|
|
|
|
|
+ 1496 makes it a call;
|
|
|
|
|
+ 1497 otherwise Fact
|
|
|
|
|
+ 1498 reports 230 *)
|
|
|
|
|
+ 1499 ELSE
|
|
|
|
|
+ 1500 IF k = SymTab.KindField THEN
|
|
|
|
|
+ 1501 IF QbeGen.TopWith(qb) THEN
|
|
|
|
|
+ 1502 fo :=
|
|
|
|
|
+ 1503 SymTab.FieldOffset(
|
|
|
|
|
+ 1504 SymTab.FieldOwner(n),
|
|
|
|
|
+ 1505 n);
|
|
|
|
|
+ 1506 QbeGen.FieldAddr(qb,
|
|
|
|
|
+ 1507 fo, q);
|
|
|
|
|
+ 1508 sfx := TRUE
|
|
|
|
|
+ 1509 ELSE SemError(230);
|
|
|
|
|
+ 1510 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1511 END
|
|
|
|
|
+ 1512 END
|
|
|
|
|
+ 1513 END
|
|
|
|
|
+ 1514 END
|
|
|
|
|
+ 1515 END; .)
|
|
|
|
|
+ 1516 { "[" Expr<it, iq>
|
|
|
|
|
+ 1517 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1518 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 1519 SymTab.ClArray THEN
|
|
|
|
|
+ 1520 SemError(217);
|
|
|
|
|
+ 1521 t := SymTab.InvalidType
|
|
|
|
|
+ 1522 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
+ 1523 AND (SymTab.ClassOf(it) #
|
|
|
|
|
+ 1524 SymTab.ClChar) THEN
|
|
|
|
|
+ 1525 SemError(218);
|
|
|
|
|
+ 1526 t := SymTab.InvalidType
|
|
|
|
|
+ 1527 ELSE
|
|
|
|
|
+ 1528 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
+ 1529 isOpen :=
|
|
|
|
|
+ 1530 SymTab.IsOpenArray(t);
|
|
|
|
|
+ 1531 IF isOpen THEN
|
|
|
|
|
+ 1532 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
+ 1533 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
+ 1534 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
+ 1535 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
+ 1536 END
|
|
|
|
|
+ 1537 ELSE
|
|
|
|
|
+ 1538 lo := SymTab.ArrayLo(t);
|
|
|
|
|
+ 1539 hi := SymTab.ArrayHi(t);
|
|
|
|
|
+ 1540 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
+ 1541 hi := hi + 1
|
|
|
|
|
+ 1542 END;
|
|
|
|
|
+ 1543 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
+ 1544 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
+ 1545 END;
|
|
|
|
|
+ 1546 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
+ 1547 qhi);
|
|
|
|
|
+ 1548 eT := SymTab.ArrayElem(t);
|
|
|
|
|
+ 1549 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
+ 1550 t, qe);
|
|
|
|
|
+ 1551 IF SymTab.ClassOf(eT) =
|
|
|
|
|
+ 1552 SymTab.ClArray THEN
|
|
|
|
|
+ 1553 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
+ 1554 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 1555 END;
|
|
|
|
|
+ 1556 t := eT; sfx := TRUE
|
|
|
|
|
+ 1557 END; .)
|
|
|
|
|
+ 1558 { "," Expr<it, iq>
|
|
|
|
|
+ 1559 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1560 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 1561 SymTab.ClArray THEN
|
|
|
|
|
+ 1562 SemError(217);
|
|
|
|
|
+ 1563 t := SymTab.InvalidType
|
|
|
|
|
+ 1564 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
+ 1565 AND (SymTab.ClassOf(it) #
|
|
|
|
|
+ 1566 SymTab.ClChar) THEN
|
|
|
|
|
+ 1567 SemError(218);
|
|
|
|
|
+ 1568 t := SymTab.InvalidType
|
|
|
|
|
+ 1569 ELSE
|
|
|
|
|
+ 1570 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
+ 1571 isOpen :=
|
|
|
|
|
+ 1572 SymTab.IsOpenArray(t);
|
|
|
|
|
+ 1573 IF isOpen THEN
|
|
|
|
|
+ 1574 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
+ 1575 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
+ 1576 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
+ 1577 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
+ 1578 END
|
|
|
|
|
+ 1579 ELSE
|
|
|
|
|
+ 1580 lo := SymTab.ArrayLo(t);
|
|
|
|
|
+ 1581 hi := SymTab.ArrayHi(t);
|
|
|
|
|
+ 1582 IF SymTab.IsCharArray(t) THEN
|
|
|
|
|
+ 1583 hi := hi + 1
|
|
|
|
|
+ 1584 END;
|
|
|
|
|
+ 1585 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
+ 1586 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
+ 1587 END;
|
|
|
|
|
+ 1588 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
+ 1589 qhi);
|
|
|
|
|
+ 1590 eT := SymTab.ArrayElem(t);
|
|
|
|
|
+ 1591 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
+ 1592 t, qe);
|
|
|
|
|
+ 1593 IF SymTab.ClassOf(eT) =
|
|
|
|
|
+ 1594 SymTab.ClArray THEN
|
|
|
|
|
+ 1595 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
+ 1596 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 1597 END;
|
|
|
|
|
+ 1598 t := eT; sfx := TRUE
|
|
|
|
|
+ 1599 END; .) }
|
|
|
|
|
+ 1600 "]"
|
|
|
|
|
+ 1601 | "." GetIdent<fn>
|
|
|
|
|
+ 1602 (. IF k = SymTab.KindModule THEN
|
|
|
|
|
+ 1603 (* qualified L.x: materialize
|
|
|
|
|
+ 1604 the export, then load it *)
|
|
|
|
|
+ 1605 IF NOT SymTab.MaterializeAlias(n,
|
|
|
|
|
+ 1606 fn, mal) THEN
|
|
|
|
|
+ 1607 SemError(201);
|
|
|
|
|
+ 1608 t := SymTab.InvalidType;
|
|
|
|
|
+ 1609 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1610 ELSE
|
|
|
|
|
+ 1611 QbeGen.CopyOp(mal, qn);
|
|
|
|
|
+ 1612 t := SymTab.SymType(mal);
|
|
|
|
|
+ 1613 k := SymTab.SymKind(mal);
|
|
|
|
|
+ 1614 sfx := FALSE;
|
|
|
|
|
+ 1615 IF k = SymTab.KindProc THEN
|
|
|
|
|
+ 1616 (* call: ArgList supplies
|
|
|
|
|
+ 1617 the value *)
|
|
|
|
|
+ 1618 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1619 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
|
|
+ 1620 mal, t, k, q) THEN
|
|
|
|
|
+ 1621 SemError(230);
|
|
|
|
|
+ 1622 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1623 END
|
|
|
|
|
+ 1624 END
|
|
|
|
|
+ 1625 ELSIF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1626 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
+ 1627 SymTab.ClRecord)
|
|
|
|
|
+ 1628 AND (SymTab.ClassOf(t) #
|
|
|
|
|
+ 1629 SymTab.ClClass) THEN
|
|
|
|
|
+ 1630 SemError(215);
|
|
|
|
|
+ 1631 t := SymTab.InvalidType
|
|
|
|
|
+ 1632 ELSIF NOT SymTab.FieldExists(t,
|
|
|
|
|
+ 1633 fn) THEN
|
|
|
|
|
+ 1634 SemError(216);
|
|
|
|
|
+ 1635 t := SymTab.InvalidType
|
|
|
|
|
+ 1636 ELSE
|
|
|
|
|
+ 1637 fo := SymTab.FieldOffset(t,
|
|
|
|
|
+ 1638 fn);
|
|
|
|
|
+ 1639 t := SymTab.FieldType(t, fn);
|
|
|
|
|
+ 1640 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
+ 1641 (* array fields are inline:
|
|
|
|
|
+ 1642 the field address is the
|
|
|
|
|
+ 1643 descriptor, like records *)
|
|
|
|
|
+ 1644 QbeGen.CopyOp(qe, q);
|
|
|
|
|
+ 1645 sfx := TRUE
|
|
|
|
|
+ 1646 END; .)
|
|
|
|
|
+ 1647 | "^"
|
|
|
|
|
+ 1648 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1649 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 1650 SymTab.ClPtr THEN
|
|
|
|
|
+ 1651 SemError(219);
|
|
|
|
|
+ 1652 t := SymTab.InvalidType
|
|
|
|
|
+ 1653 ELSE
|
|
|
|
|
+ 1654 bt := SymTab.PtrBase(t);
|
|
|
|
|
+ 1655 IF bt = SymTab.InvalidType THEN
|
|
|
|
|
+ 1656 ELSE
|
|
|
|
|
+ 1657 IF sfx THEN
|
|
|
|
|
+ 1658 QbeGen.ElemLoad(q, t,
|
|
|
|
|
+ 1659 qb);
|
|
|
|
|
+ 1660 QbeGen.CopyOp(qb, q)
|
|
|
|
|
+ 1661 END;
|
|
|
|
|
+ 1662 t := bt;
|
|
|
|
|
+ 1663 (* q holds the pointee
|
|
|
|
|
+ 1664 address: Fact loads
|
|
|
|
|
+ 1665 scalars/pointers and uses
|
|
|
|
|
+ 1666 the address for
|
|
|
|
|
+ 1667 aggregates; the VAR-actual
|
|
|
|
|
+ 1668 note is q itself. *)
|
|
|
|
|
+ 1669 sfx := TRUE
|
|
|
|
|
+ 1670 END
|
|
|
|
|
+ 1671 END; .) } .
|
|
|
|
|
+ 1672 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1673 (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
+ 1674 op: INTEGER;
|
|
|
|
|
+ 1675 q2, qt, wl: QbeGen.QVal;
|
|
|
|
|
+ 1676 isR: BOOLEAN; .)
|
|
|
|
|
+ 1677 = SimExpr<t, q>
|
|
|
|
|
+ 1678 [ Rel<op> SimExpr<t2, q2>
|
|
|
|
|
+ 1679 (. IF op = SymTab.OpIn THEN
|
|
|
|
|
+ 1680 IF SymTab.InCheck(t, t2) THEN
|
|
|
|
|
+ 1681 IF (t = SymTab.InvalidType)
|
|
|
|
|
+ 1682 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
+ 1683 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1684 ELSE
|
|
|
|
|
+ 1685 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
|
|
+ 1686 SymTab.SetCount(t2), qt);
|
|
|
|
|
+ 1687 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1688 END
|
|
|
|
|
+ 1689 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
|
|
+ 1690 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1691 END
|
|
|
|
|
+ 1692 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
|
|
+ 1693 IF (t = SymTab.InvalidType)
|
|
|
|
|
+ 1694 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
+ 1695 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1696 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
|
|
+ 1697 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
|
|
+ 1698 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
|
|
+ 1699 AND (op # SymTab.OpNeq2) THEN
|
|
|
|
|
+ 1700 SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
+ 1701 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1702 ELSE
|
|
|
|
|
+ 1703 QbeGen.CmpL(op, q, q2, qt);
|
|
|
|
|
+ 1704 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1705 END
|
|
|
|
|
+ 1706 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 1707 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 1708 QbeGen.CmpSet(op, q, q2,
|
|
|
|
|
+ 1709 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
|
|
+ 1710 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1711 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
|
|
+ 1712 QbeGen.StrEq(op, q, q2, qt);
|
|
|
|
|
+ 1713 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1714 ELSIF SymTab.IsLongFamily(t)
|
|
|
|
|
+ 1715 OR SymTab.IsLongFamily(t2) THEN
|
|
|
|
|
+ 1716 IF SymTab.IsIntFamily(t) THEN
|
|
|
|
|
+ 1717 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
|
|
+ 1718 END;
|
|
|
|
|
+ 1719 IF SymTab.IsIntFamily(t2) THEN
|
|
|
|
|
+ 1720 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
|
|
+ 1721 END;
|
|
|
|
|
+ 1722 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
|
|
+ 1723 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1724 ELSE
|
|
|
|
|
+ 1725 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 1726 t := SymTab.BoolType();
|
|
|
|
|
+ 1727 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
|
|
+ 1728 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1729 END
|
|
|
|
|
+ 1730 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
+ 1731 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1732 END; .) ] .
|
|
|
|
|
+ 1733 Rel<VAR op: INTEGER>
|
|
|
|
|
+ 1734 = "=" (. op := SymTab.OpEq; .)
|
|
|
|
|
+ 1735 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
|
|
+ 1736 | "<" (. op := SymTab.OpLt; .)
|
|
|
|
|
+ 1737 | "<=" (. op := SymTab.OpLe; .)
|
|
|
|
|
+ 1738 | ">" (. op := SymTab.OpGt; .)
|
|
|
|
|
+ 1739 | ">=" (. op := SymTab.OpGe; .)
|
|
|
|
|
+ 1740 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
|
|
+ 1741 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1742 (. VAR t2, res2, lt, rt:
|
|
|
|
|
+ 1743 SymTab.TypeIndex;
|
|
|
|
|
+ 1744 op: INTEGER;
|
|
|
|
|
+ 1745 q2, qt, wq, qf:
|
|
|
|
|
+ 1746 QbeGen.QVal;
|
|
|
|
|
+ 1747 neg, isR, isL, folded:
|
|
|
|
|
+ 1748 BOOLEAN;
|
|
|
|
|
+ 1749 lw, rw, mw: CARDINAL;
|
|
|
|
|
+ 1750 lTrue, lNext, lDone, qr, qs:
|
|
|
|
|
+ 1751 QbeGen.QVal; .)
|
|
|
|
|
+ 1752 = (. neg := FALSE; .)
|
|
|
|
|
+ 1753 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
|
|
+ 1754 Term<t, q> (. IF neg THEN
|
|
|
|
|
+ 1755 IF QbeGen.IsImm(q) THEN
|
|
|
|
|
+ 1756 QbeGen.NegFold(q, q)
|
|
|
|
|
+ 1757 ELSE QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1758 QbeGen.NegQ(q, qt,
|
|
|
|
|
+ 1759 SymTab.ClassOf(t)
|
|
|
|
|
+ 1760 = SymTab.ClReal);
|
|
|
|
|
+ 1761 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1762 END
|
|
|
|
|
+ 1763 END; .)
|
|
|
|
|
+ 1764 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 1765 QbeGen.DelayBegin END; .)
|
|
|
|
|
+ 1766 Term<t2, q2> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 1767 QbeGen.DelayEnd END; .)
|
|
|
|
|
+ 1768 (. IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 1769 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
|
|
+ 1770 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 1771 t := SymTab.BoolType()
|
|
|
|
|
+ 1772 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1773 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1774 QbeGen.Slot4(qs);
|
|
|
|
|
+ 1775 QbeGen.NewLabel(lTrue);
|
|
|
|
|
+ 1776 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 1777 QbeGen.NewLabel(lDone);
|
|
|
|
|
+ 1778 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
|
|
+ 1779 QbeGen.EmitLabel(lTrue);
|
|
|
|
|
+ 1780 QbeGen.StoreW(qs, "1");
|
|
|
|
|
+ 1781 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 1782 QbeGen.EmitLabel(lNext);
|
|
|
|
|
+ 1783 QbeGen.DelayFlush;
|
|
|
|
|
+ 1784 QbeGen.StoreW(qs, q2);
|
|
|
|
|
+ 1785 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 1786 QbeGen.EmitLabel(lDone);
|
|
|
|
|
+ 1787 QbeGen.LoadW(qs, qr);
|
|
|
|
|
+ 1788 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 1789 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1790 END
|
|
|
|
|
+ 1791 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 1792 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 1793 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 1794 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 1795 mw := lw;
|
|
|
|
|
+ 1796 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 1797 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 1798 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1799 ELSE
|
|
|
|
|
+ 1800 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1801 END;
|
|
|
|
|
+ 1802 t := SymTab.NewSet(
|
|
|
|
|
+ 1803 SymTab.NewSubR(0,
|
|
|
|
|
+ 1804 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 1805 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1806 ELSE
|
|
|
|
|
+ 1807 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
+ 1808 lt := t; rt := t2; t := res2
|
|
|
|
|
+ 1809 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1810 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1811 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
+ 1812 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 1813 folded := FALSE;
|
|
|
|
|
+ 1814 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
+ 1815 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 1816 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 1817 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
|
|
+ 1818 ELSE
|
|
|
|
|
+ 1819 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
|
|
+ 1820 END
|
|
|
|
|
+ 1821 END;
|
|
|
|
|
+ 1822 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
+ 1823 ELSE
|
|
|
|
|
+ 1824 IF isL THEN
|
|
|
|
|
+ 1825 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
+ 1826 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
+ 1827 END;
|
|
|
|
|
+ 1828 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
+ 1829 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
+ 1830 END;
|
|
|
|
|
+ 1831 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1832 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 1833 QbeGen.Op3L("add", qt, q, q2)
|
|
|
|
|
+ 1834 ELSE
|
|
|
|
|
+ 1835 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
|
|
+ 1836 END
|
|
|
|
|
+ 1837 ELSE
|
|
|
|
|
+ 1838 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1839 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 1840 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
|
|
+ 1841 ELSE
|
|
|
|
|
+ 1842 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
|
|
+ 1843 END
|
|
|
|
|
+ 1844 END;
|
|
|
|
|
+ 1845 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1846 END
|
|
|
|
|
+ 1847 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1848 END
|
|
|
|
|
+ 1849 END; .) } .
|
|
|
|
|
+ 1850 AddOp<VAR op: INTEGER>
|
|
|
|
|
+ 1851 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
+ 1852 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
+ 1853 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
+ 1854 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1855 (. VAR t2, res2, lt, rt:
|
|
|
|
|
+ 1856 SymTab.TypeIndex;
|
|
|
|
|
+ 1857 op: INTEGER;
|
|
|
|
|
+ 1858 q2, qt, wq, qf:
|
|
|
|
|
+ 1859 QbeGen.QVal;
|
|
|
|
|
+ 1860 isR, isL, folded: BOOLEAN;
|
|
|
|
|
+ 1861 lw, rw, mw: CARDINAL;
|
|
|
|
|
+ 1862 lNext, lFalse, lDone, qr, qs:
|
|
|
|
|
+ 1863 QbeGen.QVal; .)
|
|
|
|
|
+ 1864 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 1865 QbeGen.DelayBegin END; .)
|
|
|
|
|
+ 1866 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 1867 QbeGen.DelayEnd END; .)
|
|
|
|
|
+ 1868 (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 1869 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
|
|
+ 1870 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 1871 t := SymTab.BoolType()
|
|
|
|
|
+ 1872 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1873 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1874 QbeGen.Slot4(qs);
|
|
|
|
|
+ 1875 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 1876 QbeGen.NewLabel(lFalse);
|
|
|
|
|
+ 1877 QbeGen.NewLabel(lDone);
|
|
|
|
|
+ 1878 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
|
|
+ 1879 QbeGen.EmitLabel(lNext);
|
|
|
|
|
+ 1880 QbeGen.DelayFlush;
|
|
|
|
|
+ 1881 QbeGen.StoreW(qs, q2);
|
|
|
|
|
+ 1882 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 1883 QbeGen.EmitLabel(lFalse);
|
|
|
|
|
+ 1884 QbeGen.StoreW(qs, "0");
|
|
|
|
|
+ 1885 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 1886 QbeGen.EmitLabel(lDone);
|
|
|
|
|
+ 1887 QbeGen.LoadW(qs, qr);
|
|
|
|
|
+ 1888 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 1889 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1890 END
|
|
|
|
|
+ 1891 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 1892 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 1893 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 1894 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 1895 mw := lw;
|
|
|
|
|
+ 1896 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 1897 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 1898 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1899 ELSE
|
|
|
|
|
+ 1900 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1901 END;
|
|
|
|
|
+ 1902 t := SymTab.NewSet(
|
|
|
|
|
+ 1903 SymTab.NewSubR(0,
|
|
|
|
|
+ 1904 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 1905 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1906 ELSE
|
|
|
|
|
+ 1907 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
+ 1908 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
+ 1909 res2) THEN
|
|
|
|
|
+ 1910 lt := t; rt := t2; t := res2
|
|
|
|
|
+ 1911 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1912 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1913 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
+ 1914 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 1915 folded := FALSE;
|
|
|
|
|
+ 1916 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
+ 1917 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
1918 IF op = SymTab.OpTimes THEN
|
|
1918 IF op = SymTab.OpTimes THEN
|
|
|
- 1919 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
|
|
- 1920 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
- 1921 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
- 1922 QbeGen.Op3L("div", qt, q, q2)
|
|
|
|
|
- 1923 ELSE
|
|
|
|
|
- 1924 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
|
|
- 1925 END
|
|
|
|
|
- 1926 ELSE
|
|
|
|
|
- 1927 QbeGen.NewTemp(qt);
|
|
|
|
|
- 1928 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 1929 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
- 1930 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
- 1931 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
- 1932 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
- 1933 ELSE
|
|
|
|
|
- 1934 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
- 1935 END
|
|
|
|
|
- 1936 END;
|
|
|
|
|
- 1937 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1938 END
|
|
|
|
|
- 1939 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1940 END
|
|
|
|
|
- 1941 END; .) } .
|
|
|
|
|
- 1942 MulOp<VAR op: INTEGER>
|
|
|
|
|
- 1943 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
- 1944 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
- 1945 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
- 1946 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
- 1947 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
|
|
- 1948 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1949 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
- 1950 et, dt, t2, st, ct2:
|
|
|
|
|
- 1951 SymTab.TypeIndex;
|
|
|
|
|
- 1952 dk: INTEGER;
|
|
|
|
|
- 1953 qd, q2, sq, qa, qm0, qr:
|
|
|
|
|
- 1954 QbeGen.QVal;
|
|
|
|
|
- 1955 qn, vn: SymTab.Name;
|
|
|
|
|
- 1956 vt: SymTab.TypeIndex;
|
|
|
|
|
- 1957 c1, c2: INTEGER;
|
|
|
|
|
- 1958 called, isHigh, sfx, isCh,
|
|
|
|
|
- 1959 isU, uok: BOOLEAN;
|
|
|
|
|
- 1960 ucp: INTEGER; .)
|
|
|
|
|
- 1961 = integer (. LexString(s);
|
|
|
|
|
- 1962 QbeGen.NormInt(s, q);
|
|
|
|
|
- 1963 t := SymTab.IntType(); .)
|
|
|
|
|
- 1964 | charConst (. LexString(s);
|
|
|
|
|
- 1965 QbeGen.NormLit(s, q, isCh);
|
|
|
|
|
- 1966 t := SymTab.CharType(); .)
|
|
|
|
|
- 1967 | real (. LexString(s);
|
|
|
|
|
- 1968 QbeGen.NormReal(s, q);
|
|
|
|
|
- 1969 t := SymTab.RealType(); .)
|
|
|
|
|
- 1970 | string (. LexString(s);
|
|
|
|
|
- 1971 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 1972 t := SymTab.CharType();
|
|
|
|
|
- 1973 QbeGen.IntStr(
|
|
|
|
|
- 1974 QbeGen.CharVal(s), q)
|
|
|
|
|
- 1975 ELSE t := SymTab.NewStr();
|
|
|
|
|
- 1976 QbeGen.DeclStr(s, q);
|
|
|
|
|
- 1977 (* a literal's value IS its
|
|
|
|
|
- 1978 static descriptor address *)
|
|
|
|
|
- 1979 QbeGen.NoteAddr(q, q)
|
|
|
|
|
- 1980 END; .)
|
|
|
|
|
- 1981 | ustring (. LexString(s);
|
|
|
|
|
- 1982 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
|
|
- 1983 uok);
|
|
|
|
|
- 1984 IF NOT uok THEN
|
|
|
|
|
- 1985 SemError(234);
|
|
|
|
|
- 1986 t := SymTab.InvalidType
|
|
|
|
|
- 1987 ELSIF isU THEN
|
|
|
|
|
- 1988 t := SymTab.UCharType();
|
|
|
|
|
- 1989 QbeGen.IntStr(ucp, q)
|
|
|
|
|
- 1990 ELSE
|
|
|
|
|
- 1991 t := SymTab.NewUStr();
|
|
|
|
|
- 1992 QbeGen.NoteAddr(q, q)
|
|
|
|
|
- 1993 END; .)
|
|
|
|
|
- 1994 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
|
|
- 1995 t := dt;
|
|
|
|
|
- 1996 IF sfx THEN
|
|
|
|
|
- 1997 IF dt =
|
|
|
|
|
- 1998 SymTab.InvalidType THEN
|
|
|
|
|
- 1999 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2000 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2001 SymTab.ClRecord)
|
|
|
|
|
- 2002 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2003 SymTab.ClSet)
|
|
|
|
|
- 2004 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2005 SymTab.ClArray)
|
|
|
|
|
- 2006 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2007 SymTab.ClClass) THEN
|
|
|
|
|
- 2008 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 2009 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
- 2010 q)
|
|
|
|
|
- 2011 END
|
|
|
|
|
- 2012 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 2013 END;
|
|
|
|
|
- 2014 IF (dk = SymTab.KindVar)
|
|
|
|
|
- 2015 OR (dk = SymTab.KindParam)
|
|
|
|
|
- 2016 OR (dk =
|
|
|
|
|
- 2017 SymTab.KindField) THEN
|
|
|
|
|
- 2018 IF sfx THEN
|
|
|
|
|
- 2019 QbeGen.NoteAddr(q, qd)
|
|
|
|
|
- 2020 ELSE
|
|
|
|
|
- 2021 QbeGen.AddrOf(qn, qa);
|
|
|
|
|
- 2022 QbeGen.NoteAddr(q, qa)
|
|
|
|
|
- 2023 END
|
|
|
|
|
- 2024 ELSIF sfx
|
|
|
|
|
- 2025 AND (dt #
|
|
|
|
|
- 2026 SymTab.InvalidType)
|
|
|
|
|
- 2027 AND ((SymTab.ClassOf(dt) =
|
|
|
|
|
- 2028 SymTab.ClArray)
|
|
|
|
|
- 2029 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2030 SymTab.ClSet)
|
|
|
|
|
- 2031 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2032 SymTab.ClRecord)) THEN
|
|
|
|
|
- 2033 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 2034 END; .)
|
|
|
|
|
- 2035 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
|
|
- 2036 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
|
|
- 2037 (. t := ct2;
|
|
|
|
|
- 2038 QbeGen.CopyOp(q2, q); .) ]
|
|
|
|
|
- 2039 (. IF NOT called
|
|
|
|
|
- 2040 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
- 2041 (* bare zero-arg function
|
|
|
|
|
- 2042 call (parentheses may be
|
|
|
|
|
- 2043 omitted); a proper or
|
|
|
|
|
- 2044 parameterised proc here
|
|
|
|
|
- 2045 is 230 *)
|
|
|
|
|
- 2046 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
- 2047 AND (SymTab.ProcRes(qn) #
|
|
|
|
|
- 2048 SymTab.InvalidType) THEN
|
|
|
|
|
- 2049 QbeGen.Mangled(qn,
|
|
|
|
|
- 2050 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 2051 QbeGen.CallBegin(qm0,
|
|
|
|
|
- 2052 SymTab.ProcRes(qn),
|
|
|
|
|
- 2053 SymTab.ProcDepthOf(qn),
|
|
|
|
|
- 2054 SymTab.IsExternal(qn));
|
|
|
|
|
- 2055 QbeGen.CallEnd(TRUE, q);
|
|
|
|
|
- 2056 t := SymTab.ProcRes(qn)
|
|
|
|
|
- 2057 ELSE
|
|
|
|
|
- 2058 (* procedure used as a
|
|
|
|
|
- 2059 value (assign to a
|
|
|
|
|
- 2060 procedure variable):
|
|
|
|
|
- 2061 its code address *)
|
|
|
|
|
- 2062 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
- 2063 QbeGen.Mangled(qn,
|
|
|
|
|
- 2064 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 2065 QbeGen.ProcAddr(qm0, q)
|
|
|
|
|
- 2066 END
|
|
|
|
|
- 2067 END; .)
|
|
|
|
|
- 2068 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
- 2069 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
- 2070 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 2071 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 2072 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 2073 SymTab.ClArray THEN
|
|
|
|
|
- 2074 SemError(217);
|
|
|
|
|
- 2075 t := SymTab.InvalidType;
|
|
|
|
|
- 2076 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2077 ELSE
|
|
|
|
|
- 2078 IF isHigh THEN
|
|
|
|
|
- 2079 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 2080 QbeGen.OpenHi(qd, qr)
|
|
|
|
|
- 2081 ELSE
|
|
|
|
|
- 2082 QbeGen.IntStr(
|
|
|
|
|
- 2083 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
- 2084 END
|
|
|
|
|
- 2085 ELSE
|
|
|
|
|
- 2086 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 2087 QbeGen.LoadCount(qd, qr)
|
|
|
|
|
- 2088 ELSE
|
|
|
|
|
- 2089 QbeGen.IntStr(VAL(
|
|
|
|
|
- 2090 INTEGER,
|
|
|
|
|
- 2091 SymTab.ArrayLen(dt)),
|
|
|
|
|
- 2092 qr)
|
|
|
|
|
- 2093 END
|
|
|
|
|
- 2094 END;
|
|
|
|
|
- 2095 t := SymTab.IntType();
|
|
|
|
|
- 2096 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2097 END; .)
|
|
|
|
|
- 2098 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 2099 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 2100 t := SymTab.InvalidType;
|
|
|
|
|
- 2101 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2102 ELSE
|
|
|
|
|
- 2103 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
- 2104 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
- 2105 t := SymTab.IntType()
|
|
|
|
|
- 2106 END; .)
|
|
|
|
|
- 2107 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 2108 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 2109 t := SymTab.InvalidType;
|
|
|
|
|
- 2110 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2111 ELSE
|
|
|
|
|
- 2112 IF sfx THEN
|
|
|
|
|
- 2113 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 2114 ELSIF (dk = SymTab.KindVar)
|
|
|
|
|
- 2115 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
- 2116 QbeGen.AddrOf(qn, q)
|
|
|
|
|
- 2117 ELSE SemError(230);
|
|
|
|
|
- 2118 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2119 END;
|
|
|
|
|
- 2120 t := SymTab.AddrType()
|
|
|
|
|
- 2121 END; .)
|
|
|
|
|
- 2122 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 2123 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2124 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 2125 SemError(211) END;
|
|
|
|
|
- 2126 t := SymTab.CharType(); .)
|
|
|
|
|
- 2127 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
- 2128 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
- 2129 IF (SymTab.ClassOf(et) #
|
|
|
|
|
- 2130 SymTab.ClChar)
|
|
|
|
|
- 2131 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 2132 SymTab.ClBool)
|
|
|
|
|
- 2133 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 2134 SymTab.ClEnum)
|
|
|
|
|
- 2135 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 2136 SemError(211) END
|
|
|
|
|
- 2137 END;
|
|
|
|
|
- 2138 t := SymTab.IntType(); .)
|
|
|
|
|
- 2139 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
- 2140 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
- 2141 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 2142 t := SymTab.CharType(); .)
|
|
|
|
|
- 2143 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 2144 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
- 2145 CHAR -> UCHAR (identity);
|
|
|
|
|
- 2146 INTEGER familly -> UCHAR
|
|
|
|
|
- 2147 (codepoint value). *)
|
|
|
|
|
- 2148 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2149 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
- 2150 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 2151 SemError(211) END;
|
|
|
|
|
- 2152 t := SymTab.UCharType(); .)
|
|
|
|
|
- 2153 | "CHR8" "(" Expr<et, q> ")"
|
|
|
|
|
- 2154 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2155 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 2156 SemError(211) END;
|
|
|
|
|
- 2157 QbeGen.WidenLong(q, qa);
|
|
|
|
|
- 2158 QbeGen.CheckRange(qa, "0", "255");
|
|
|
|
|
- 2159 t := SymTab.CharType(); .)
|
|
|
|
|
- 2160 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
- 2161 (. (* UORD(u): the codepoint as a
|
|
|
|
|
- 2162 32-bit ordinal (INTEGER),
|
|
|
|
|
- 2163 cf. ORD for CHAR. *)
|
|
|
|
|
- 2164 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2165 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 2166 SemError(211) END;
|
|
|
|
|
- 2167 t := SymTab.IntType(); .)
|
|
|
|
|
- 2168 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
- 2169 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2170 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
- 2171 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 2172 SymTab.ClReal) THEN
|
|
|
|
|
- 2173 SemError(211)
|
|
|
|
|
- 2174 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
- 2175 SymTab.ClassOf(et) =
|
|
|
|
|
- 2176 SymTab.ClReal);
|
|
|
|
|
- 2177 QbeGen.CopyOp(qa, q)
|
|
|
|
|
- 2178 END;
|
|
|
|
|
- 2179 t := et; .)
|
|
|
|
|
- 2180 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
|
|
- 2181 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
- 2182 SemError(201);
|
|
|
|
|
- 2183 t := SymTab.InvalidType
|
|
|
|
|
- 2184 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
- 2185 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 2186 t := SymTab.InvalidType
|
|
|
|
|
- 2187 ELSIF et =
|
|
|
|
|
- 2188 SymTab.InvalidType THEN
|
|
|
|
|
- 2189 t := vt
|
|
|
|
|
- 2190 ELSE
|
|
|
|
|
- 2191 c1 := SymTab.ClassOf(et);
|
|
|
|
|
- 2192 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
- 2193 IF ((c1 = SymTab.ClInt)
|
|
|
|
|
- 2194 OR (c1 =
|
|
|
|
|
- 2195 SymTab.ClChar)
|
|
|
|
|
- 2196 OR (c1 =
|
|
|
|
|
- 2197 SymTab.ClBool)
|
|
|
|
|
- 2198 OR (c1 =
|
|
|
|
|
- 2199 SymTab.ClEnum))
|
|
|
|
|
- 2200 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
- 2201 OR (c2 =
|
|
|
|
|
- 2202 SymTab.ClChar)
|
|
|
|
|
- 2203 OR (c2 =
|
|
|
|
|
- 2204 SymTab.ClBool)
|
|
|
|
|
- 2205 OR (c2 =
|
|
|
|
|
- 2206 SymTab.ClEnum)) THEN
|
|
|
|
|
- 2207 t := vt
|
|
|
|
|
- 2208 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
- 2209 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
- 2210 t := vt
|
|
|
|
|
- 2211 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 2212 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 2213 t := vt
|
|
|
|
|
- 2214 ELSE SemError(230);
|
|
|
|
|
- 2215 t := SymTab.InvalidType
|
|
|
|
|
- 2216 END
|
|
|
|
|
- 2217 END
|
|
|
|
|
- 2218 END; .)
|
|
|
|
|
- 2219 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
|
|
- 2220 | SetLit<st, sq> (. t := st;
|
|
|
|
|
- 2221 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
- 2222 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 2223 t := SymTab.BoolType()
|
|
|
|
|
- 2224 ELSE SemError(212);
|
|
|
|
|
- 2225 t := SymTab.InvalidType END;
|
|
|
|
|
- 2226 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2227 QbeGen.NotQ(q2, q)
|
|
|
|
|
- 2228 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2229 END; .) .
|
|
|
|
|
- 2230 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
- 2231 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
- 2232 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
- 2233 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2234 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
- 2235 SymTab.NewSubR(0, 255));
|
|
|
|
|
- 2236 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
- 2237 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
- 2238 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
|
|
- 2239 "}" .
|
|
|
|
|
- 2240 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
|
|
- 2241 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
|
|
- 2242 width and element span. *)
|
|
|
|
|
- 2243 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2244 (. VAR nw: CARDINAL; .)
|
|
|
|
|
- 2245 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
|
|
- 2246 SymTab.ClSet THEN
|
|
|
|
|
- 2247 SemError(230); nw := 8
|
|
|
|
|
- 2248 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
- 2249 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
- 2250 END;
|
|
|
|
|
- 2251 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
- 2252 QbeGen.SetZero(q, nw); .)
|
|
|
|
|
- 2253 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
|
|
- 2254 "}" .
|
|
|
|
|
- 2255 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 2256 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 2257 v, v2: INTEGER;
|
|
|
|
|
- 2258 lo: INTEGER;
|
|
|
|
|
- 2259 span: CARDINAL;
|
|
|
|
|
- 2260 cl, cl2: INTEGER;
|
|
|
|
|
- 2261 hasR: BOOLEAN; .)
|
|
|
|
|
- 2262 = (. hasR := FALSE; .)
|
|
|
|
|
- 2263 Expr<et, qe>
|
|
|
|
|
- 2264 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
- 2265 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
- 2266 span := SymTab.SetCount(st);
|
|
|
|
|
- 2267 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 2268 OR (hasR AND (et2 =
|
|
|
|
|
- 2269 SymTab.InvalidType)) THEN
|
|
|
|
|
- 2270 ELSE cl :=
|
|
|
|
|
- 2271 SymTab.ClassOf(et);
|
|
|
|
|
- 2272 IF hasR THEN
|
|
|
|
|
- 2273 cl2 :=
|
|
|
|
|
- 2274 SymTab.ClassOf(et2)
|
|
|
|
|
- 2275 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 2276 END;
|
|
|
|
|
- 2277 IF ((cl # SymTab.ClInt)
|
|
|
|
|
- 2278 AND (cl # SymTab.ClChar)
|
|
|
|
|
- 2279 AND (cl # SymTab.ClBool))
|
|
|
|
|
- 2280 OR (hasR AND
|
|
|
|
|
- 2281 ((cl2
|
|
|
|
|
- 2282 # SymTab.ClInt)
|
|
|
|
|
- 2283 AND (cl2
|
|
|
|
|
- 2284 # SymTab.ClChar)
|
|
|
|
|
- 2285 AND (cl2
|
|
|
|
|
- 2286 # SymTab.ClBool))) THEN
|
|
|
|
|
- 2287 SemError(222)
|
|
|
|
|
- 2288 ELSIF hasR
|
|
|
|
|
- 2289 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
- 2290 AND SymTab.ConstInt(q2,
|
|
|
|
|
- 2291 v2)
|
|
|
|
|
- 2292 AND ((v < lo)
|
|
|
|
|
- 2293 OR (v2 < lo)
|
|
|
|
|
- 2294 OR (v >= lo +
|
|
|
|
|
- 2295 VAL(INTEGER, span))
|
|
|
|
|
- 2296 OR (v2 >= lo +
|
|
|
|
|
- 2297 VAL(INTEGER, span))
|
|
|
|
|
- 2298 OR (v > v2)) THEN
|
|
|
|
|
- 2299 SemError(222)
|
|
|
|
|
- 2300 ELSIF hasR THEN
|
|
|
|
|
- 2301 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 2302 lo, span)
|
|
|
|
|
- 2303 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 2304 v)
|
|
|
|
|
- 2305 AND ((v < lo)
|
|
|
|
|
- 2306 OR (v >= lo +
|
|
|
|
|
- 2307 VAL(INTEGER,
|
|
|
|
|
- 2308 span))) THEN
|
|
|
|
|
- 2309 SemError(222)
|
|
|
|
|
- 2310 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 2311 lo, span)
|
|
|
|
|
- 2312 END
|
|
|
|
|
- 2313 END; .) .
|
|
|
|
|
- 2314 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
- 2315 = ident (. LexName(n); .) .
|
|
|
|
|
- 2316
|
|
|
|
|
- 2317 END M2.
|
|
|
|
|
|
|
+ 1919 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
|
|
+ 1920 ELSIF op = SymTab.OpDiv THEN
|
|
|
|
|
+ 1921 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
|
|
+ 1922 ELSIF op = SymTab.OpMod THEN
|
|
|
|
|
+ 1923 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
|
|
+ 1924 END
|
|
|
|
|
+ 1925 END;
|
|
|
|
|
+ 1926 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
+ 1927 ELSE
|
|
|
|
|
+ 1928 IF isL THEN
|
|
|
|
|
+ 1929 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
+ 1930 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
+ 1931 END;
|
|
|
|
|
+ 1932 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
+ 1933 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
+ 1934 END;
|
|
|
|
|
+ 1935 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1936 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 1937 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
|
|
+ 1938 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
+ 1939 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
+ 1940 QbeGen.Op3L("div", qt, q, q2)
|
|
|
|
|
+ 1941 ELSE
|
|
|
|
|
+ 1942 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
|
|
+ 1943 END
|
|
|
|
|
+ 1944 ELSE
|
|
|
|
|
+ 1945 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1946 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 1947 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
+ 1948 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
+ 1949 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
+ 1950 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
+ 1951 ELSE
|
|
|
|
|
+ 1952 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
+ 1953 END
|
|
|
|
|
+ 1954 END;
|
|
|
|
|
+ 1955 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1956 END
|
|
|
|
|
+ 1957 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1958 END
|
|
|
|
|
+ 1959 END; .) } .
|
|
|
|
|
+ 1960 MulOp<VAR op: INTEGER>
|
|
|
|
|
+ 1961 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
+ 1962 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
+ 1963 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
+ 1964 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
+ 1965 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
|
|
+ 1966 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1967 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
+ 1968 et, dt, t2, st, ct2:
|
|
|
|
|
+ 1969 SymTab.TypeIndex;
|
|
|
|
|
+ 1970 dk: INTEGER;
|
|
|
|
|
+ 1971 qd, q2, sq, qa, qm0, qr:
|
|
|
|
|
+ 1972 QbeGen.QVal;
|
|
|
|
|
+ 1973 qn, vn: SymTab.Name;
|
|
|
|
|
+ 1974 vt: SymTab.TypeIndex;
|
|
|
|
|
+ 1975 c1, c2: INTEGER;
|
|
|
|
|
+ 1976 called, isHigh, sfx, isCh,
|
|
|
|
|
+ 1977 isU, uok: BOOLEAN;
|
|
|
|
|
+ 1978 ucp: INTEGER; .)
|
|
|
|
|
+ 1979 = integer (. LexString(s);
|
|
|
|
|
+ 1980 QbeGen.NormInt(s, q);
|
|
|
|
|
+ 1981 t := SymTab.IntType(); .)
|
|
|
|
|
+ 1982 | charConst (. LexString(s);
|
|
|
|
|
+ 1983 QbeGen.NormLit(s, q, isCh);
|
|
|
|
|
+ 1984 t := SymTab.CharType(); .)
|
|
|
|
|
+ 1985 | real (. LexString(s);
|
|
|
|
|
+ 1986 QbeGen.NormReal(s, q);
|
|
|
|
|
+ 1987 t := SymTab.RealType(); .)
|
|
|
|
|
+ 1988 | string (. LexString(s);
|
|
|
|
|
+ 1989 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 1990 t := SymTab.CharType();
|
|
|
|
|
+ 1991 QbeGen.IntStr(
|
|
|
|
|
+ 1992 QbeGen.CharVal(s), q)
|
|
|
|
|
+ 1993 ELSE t := SymTab.NewStr();
|
|
|
|
|
+ 1994 QbeGen.DeclStr(s, q);
|
|
|
|
|
+ 1995 (* a literal's value IS its
|
|
|
|
|
+ 1996 static descriptor address *)
|
|
|
|
|
+ 1997 QbeGen.NoteAddr(q, q)
|
|
|
|
|
+ 1998 END; .)
|
|
|
|
|
+ 1999 | ustring (. LexString(s);
|
|
|
|
|
+ 2000 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
|
|
+ 2001 uok);
|
|
|
|
|
+ 2002 IF NOT uok THEN
|
|
|
|
|
+ 2003 SemError(234);
|
|
|
|
|
+ 2004 t := SymTab.InvalidType
|
|
|
|
|
+ 2005 ELSIF isU THEN
|
|
|
|
|
+ 2006 t := SymTab.UCharType();
|
|
|
|
|
+ 2007 QbeGen.IntStr(ucp, q)
|
|
|
|
|
+ 2008 ELSE
|
|
|
|
|
+ 2009 t := SymTab.NewUStr();
|
|
|
|
|
+ 2010 QbeGen.NoteAddr(q, q)
|
|
|
|
|
+ 2011 END; .)
|
|
|
|
|
+ 2012 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
|
|
+ 2013 t := dt;
|
|
|
|
|
+ 2014 IF sfx THEN
|
|
|
|
|
+ 2015 IF dt =
|
|
|
|
|
+ 2016 SymTab.InvalidType THEN
|
|
|
|
|
+ 2017 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2018 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2019 SymTab.ClRecord)
|
|
|
|
|
+ 2020 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2021 SymTab.ClSet)
|
|
|
|
|
+ 2022 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2023 SymTab.ClArray)
|
|
|
|
|
+ 2024 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2025 SymTab.ClClass) THEN
|
|
|
|
|
+ 2026 QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2027 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
+ 2028 q)
|
|
|
|
|
+ 2029 END
|
|
|
|
|
+ 2030 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2031 END;
|
|
|
|
|
+ 2032 IF (dk = SymTab.KindVar)
|
|
|
|
|
+ 2033 OR (dk = SymTab.KindParam)
|
|
|
|
|
+ 2034 OR (dk =
|
|
|
|
|
+ 2035 SymTab.KindField) THEN
|
|
|
|
|
+ 2036 IF sfx THEN
|
|
|
|
|
+ 2037 QbeGen.NoteAddr(q, qd)
|
|
|
|
|
+ 2038 ELSE
|
|
|
|
|
+ 2039 QbeGen.AddrOf(qn, qa);
|
|
|
|
|
+ 2040 QbeGen.NoteAddr(q, qa)
|
|
|
|
|
+ 2041 END
|
|
|
|
|
+ 2042 ELSIF sfx
|
|
|
|
|
+ 2043 AND (dt #
|
|
|
|
|
+ 2044 SymTab.InvalidType)
|
|
|
|
|
+ 2045 AND ((SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2046 SymTab.ClArray)
|
|
|
|
|
+ 2047 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2048 SymTab.ClSet)
|
|
|
|
|
+ 2049 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2050 SymTab.ClRecord)) THEN
|
|
|
|
|
+ 2051 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 2052 END; .)
|
|
|
|
|
+ 2053 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
|
|
+ 2054 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
|
|
+ 2055 (. t := ct2;
|
|
|
|
|
+ 2056 QbeGen.CopyOp(q2, q); .) ]
|
|
|
|
|
+ 2057 (. IF NOT called
|
|
|
|
|
+ 2058 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
+ 2059 (* bare zero-arg function
|
|
|
|
|
+ 2060 call (parentheses may be
|
|
|
|
|
+ 2061 omitted); a proper or
|
|
|
|
|
+ 2062 parameterised proc here
|
|
|
|
|
+ 2063 is 230 *)
|
|
|
|
|
+ 2064 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
+ 2065 AND (SymTab.ProcRes(qn) #
|
|
|
|
|
+ 2066 SymTab.InvalidType) THEN
|
|
|
|
|
+ 2067 QbeGen.Mangled(qn,
|
|
|
|
|
+ 2068 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
+ 2069 QbeGen.CallBegin(qm0,
|
|
|
|
|
+ 2070 SymTab.ProcRes(qn),
|
|
|
|
|
+ 2071 SymTab.ProcDepthOf(qn),
|
|
|
|
|
+ 2072 SymTab.IsExternal(qn));
|
|
|
|
|
+ 2073 QbeGen.CallEnd(TRUE, q);
|
|
|
|
|
+ 2074 t := SymTab.ProcRes(qn)
|
|
|
|
|
+ 2075 ELSE
|
|
|
|
|
+ 2076 (* procedure used as a
|
|
|
|
|
+ 2077 value (assign to a
|
|
|
|
|
+ 2078 procedure variable):
|
|
|
|
|
+ 2079 its code address *)
|
|
|
|
|
+ 2080 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
+ 2081 QbeGen.Mangled(qn,
|
|
|
|
|
+ 2082 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
+ 2083 QbeGen.ProcAddr(qm0, q)
|
|
|
|
|
+ 2084 END
|
|
|
|
|
+ 2085 END; .)
|
|
|
|
|
+ 2086 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
+ 2087 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
+ 2088 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 2089 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2090 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 2091 SymTab.ClArray THEN
|
|
|
|
|
+ 2092 SemError(217);
|
|
|
|
|
+ 2093 t := SymTab.InvalidType;
|
|
|
|
|
+ 2094 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2095 ELSE
|
|
|
|
|
+ 2096 IF isHigh THEN
|
|
|
|
|
+ 2097 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
+ 2098 QbeGen.OpenHi(qd, qr)
|
|
|
|
|
+ 2099 ELSE
|
|
|
|
|
+ 2100 QbeGen.IntStr(
|
|
|
|
|
+ 2101 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
+ 2102 END
|
|
|
|
|
+ 2103 ELSE
|
|
|
|
|
+ 2104 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
+ 2105 QbeGen.LoadCount(qd, qr)
|
|
|
|
|
+ 2106 ELSE
|
|
|
|
|
+ 2107 QbeGen.IntStr(VAL(
|
|
|
|
|
+ 2108 INTEGER,
|
|
|
|
|
+ 2109 SymTab.ArrayLen(dt)),
|
|
|
|
|
+ 2110 qr)
|
|
|
|
|
+ 2111 END
|
|
|
|
|
+ 2112 END;
|
|
|
|
|
+ 2113 t := SymTab.IntType();
|
|
|
|
|
+ 2114 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2115 END; .)
|
|
|
|
|
+ 2116 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 2117 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2118 t := SymTab.InvalidType;
|
|
|
|
|
+ 2119 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2120 ELSE
|
|
|
|
|
+ 2121 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
+ 2122 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
+ 2123 t := SymTab.IntType()
|
|
|
|
|
+ 2124 END; .)
|
|
|
|
|
+ 2125 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 2126 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2127 t := SymTab.InvalidType;
|
|
|
|
|
+ 2128 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2129 ELSE
|
|
|
|
|
+ 2130 IF sfx THEN
|
|
|
|
|
+ 2131 QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2132 ELSIF (dk = SymTab.KindVar)
|
|
|
|
|
+ 2133 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
+ 2134 QbeGen.AddrOf(qn, q)
|
|
|
|
|
+ 2135 ELSE SemError(230);
|
|
|
|
|
+ 2136 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2137 END;
|
|
|
|
|
+ 2138 t := SymTab.AddrType()
|
|
|
|
|
+ 2139 END; .)
|
|
|
|
|
+ 2140 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2141 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2142 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 2143 SemError(211) END;
|
|
|
|
|
+ 2144 t := SymTab.CharType(); .)
|
|
|
|
|
+ 2145 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
+ 2146 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
+ 2147 IF (SymTab.ClassOf(et) #
|
|
|
|
|
+ 2148 SymTab.ClChar)
|
|
|
|
|
+ 2149 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 2150 SymTab.ClBool)
|
|
|
|
|
+ 2151 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 2152 SymTab.ClEnum)
|
|
|
|
|
+ 2153 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 2154 SemError(211) END
|
|
|
|
|
+ 2155 END;
|
|
|
|
|
+ 2156 t := SymTab.IntType(); .)
|
|
|
|
|
+ 2157 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2158 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
+ 2159 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 2160 t := SymTab.CharType(); .)
|
|
|
|
|
+ 2161 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2162 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
+ 2163 CHAR -> UCHAR (identity);
|
|
|
|
|
+ 2164 INTEGER familly -> UCHAR
|
|
|
|
|
+ 2165 (codepoint value). *)
|
|
|
|
|
+ 2166 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2167 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
+ 2168 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 2169 SemError(211) END;
|
|
|
|
|
+ 2170 t := SymTab.UCharType(); .)
|
|
|
|
|
+ 2171 | "CHR8" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2172 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2173 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 2174 SemError(211) END;
|
|
|
|
|
+ 2175 QbeGen.WidenLong(q, qa);
|
|
|
|
|
+ 2176 QbeGen.CheckRange(qa, "0", "255");
|
|
|
|
|
+ 2177 t := SymTab.CharType(); .)
|
|
|
|
|
+ 2178 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2179 (. (* UORD(u): the codepoint as a
|
|
|
|
|
+ 2180 32-bit ordinal (INTEGER),
|
|
|
|
|
+ 2181 cf. ORD for CHAR. *)
|
|
|
|
|
+ 2182 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2183 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 2184 SemError(211) END;
|
|
|
|
|
+ 2185 t := SymTab.IntType(); .)
|
|
|
|
|
+ 2186 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2187 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2188 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
+ 2189 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 2190 SymTab.ClReal) THEN
|
|
|
|
|
+ 2191 SemError(211)
|
|
|
|
|
+ 2192 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
+ 2193 SymTab.ClassOf(et) =
|
|
|
|
|
+ 2194 SymTab.ClReal);
|
|
|
|
|
+ 2195 QbeGen.CopyOp(qa, q)
|
|
|
|
|
+ 2196 END;
|
|
|
|
|
+ 2197 t := et; .)
|
|
|
|
|
+ 2198 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
|
|
+ 2199 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
+ 2200 SemError(201);
|
|
|
|
|
+ 2201 t := SymTab.InvalidType
|
|
|
|
|
+ 2202 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
+ 2203 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2204 t := SymTab.InvalidType
|
|
|
|
|
+ 2205 ELSIF et =
|
|
|
|
|
+ 2206 SymTab.InvalidType THEN
|
|
|
|
|
+ 2207 t := vt
|
|
|
|
|
+ 2208 ELSE
|
|
|
|
|
+ 2209 c1 := SymTab.ClassOf(et);
|
|
|
|
|
+ 2210 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
+ 2211 IF ((c1 = SymTab.ClInt)
|
|
|
|
|
+ 2212 OR (c1 =
|
|
|
|
|
+ 2213 SymTab.ClChar)
|
|
|
|
|
+ 2214 OR (c1 =
|
|
|
|
|
+ 2215 SymTab.ClBool)
|
|
|
|
|
+ 2216 OR (c1 =
|
|
|
|
|
+ 2217 SymTab.ClEnum))
|
|
|
|
|
+ 2218 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
+ 2219 OR (c2 =
|
|
|
|
|
+ 2220 SymTab.ClChar)
|
|
|
|
|
+ 2221 OR (c2 =
|
|
|
|
|
+ 2222 SymTab.ClBool)
|
|
|
|
|
+ 2223 OR (c2 =
|
|
|
|
|
+ 2224 SymTab.ClEnum)) THEN
|
|
|
|
|
+ 2225 t := vt
|
|
|
|
|
+ 2226 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
+ 2227 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
+ 2228 t := vt
|
|
|
|
|
+ 2229 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 2230 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 2231 t := vt
|
|
|
|
|
+ 2232 ELSE SemError(230);
|
|
|
|
|
+ 2233 t := SymTab.InvalidType
|
|
|
|
|
+ 2234 END
|
|
|
|
|
+ 2235 END
|
|
|
|
|
+ 2236 END; .)
|
|
|
|
|
+ 2237 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
|
|
+ 2238 | SetLit<st, sq> (. t := st;
|
|
|
|
|
+ 2239 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
+ 2240 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 2241 t := SymTab.BoolType()
|
|
|
|
|
+ 2242 ELSE SemError(212);
|
|
|
|
|
+ 2243 t := SymTab.InvalidType END;
|
|
|
|
|
+ 2244 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2245 QbeGen.NotQ(q2, q)
|
|
|
|
|
+ 2246 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2247 END; .) .
|
|
|
|
|
+ 2248 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
+ 2249 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
+ 2250 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
+ 2251 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2252 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
+ 2253 SymTab.NewSubR(0, 255));
|
|
|
|
|
+ 2254 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
+ 2255 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
+ 2256 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
|
|
+ 2257 "}" .
|
|
|
|
|
+ 2258 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
|
|
+ 2259 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
|
|
+ 2260 width and element span. *)
|
|
|
|
|
+ 2261 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2262 (. VAR nw: CARDINAL; .)
|
|
|
|
|
+ 2263 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
|
|
+ 2264 SymTab.ClSet THEN
|
|
|
|
|
+ 2265 SemError(230); nw := 8
|
|
|
|
|
+ 2266 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
+ 2267 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
+ 2268 END;
|
|
|
|
|
+ 2269 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
+ 2270 QbeGen.SetZero(q, nw); .)
|
|
|
|
|
+ 2271 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
|
|
+ 2272 "}" .
|
|
|
|
|
+ 2273 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 2274 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 2275 v, v2: INTEGER;
|
|
|
|
|
+ 2276 lo: INTEGER;
|
|
|
|
|
+ 2277 span: CARDINAL;
|
|
|
|
|
+ 2278 cl, cl2: INTEGER;
|
|
|
|
|
+ 2279 hasR: BOOLEAN; .)
|
|
|
|
|
+ 2280 = (. hasR := FALSE; .)
|
|
|
|
|
+ 2281 Expr<et, qe>
|
|
|
|
|
+ 2282 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
+ 2283 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
+ 2284 span := SymTab.SetCount(st);
|
|
|
|
|
+ 2285 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 2286 OR (hasR AND (et2 =
|
|
|
|
|
+ 2287 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 2288 ELSE cl :=
|
|
|
|
|
+ 2289 SymTab.ClassOf(et);
|
|
|
|
|
+ 2290 IF hasR THEN
|
|
|
|
|
+ 2291 cl2 :=
|
|
|
|
|
+ 2292 SymTab.ClassOf(et2)
|
|
|
|
|
+ 2293 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 2294 END;
|
|
|
|
|
+ 2295 IF ((cl # SymTab.ClInt)
|
|
|
|
|
+ 2296 AND (cl # SymTab.ClChar)
|
|
|
|
|
+ 2297 AND (cl # SymTab.ClBool))
|
|
|
|
|
+ 2298 OR (hasR AND
|
|
|
|
|
+ 2299 ((cl2
|
|
|
|
|
+ 2300 # SymTab.ClInt)
|
|
|
|
|
+ 2301 AND (cl2
|
|
|
|
|
+ 2302 # SymTab.ClChar)
|
|
|
|
|
+ 2303 AND (cl2
|
|
|
|
|
+ 2304 # SymTab.ClBool))) THEN
|
|
|
|
|
+ 2305 SemError(222)
|
|
|
|
|
+ 2306 ELSIF hasR
|
|
|
|
|
+ 2307 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 2308 AND SymTab.ConstInt(q2,
|
|
|
|
|
+ 2309 v2)
|
|
|
|
|
+ 2310 AND ((v < lo)
|
|
|
|
|
+ 2311 OR (v2 < lo)
|
|
|
|
|
+ 2312 OR (v >= lo +
|
|
|
|
|
+ 2313 VAL(INTEGER, span))
|
|
|
|
|
+ 2314 OR (v2 >= lo +
|
|
|
|
|
+ 2315 VAL(INTEGER, span))
|
|
|
|
|
+ 2316 OR (v > v2)) THEN
|
|
|
|
|
+ 2317 SemError(222)
|
|
|
|
|
+ 2318 ELSIF hasR THEN
|
|
|
|
|
+ 2319 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 2320 lo, span)
|
|
|
|
|
+ 2321 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 2322 v)
|
|
|
|
|
+ 2323 AND ((v < lo)
|
|
|
|
|
+ 2324 OR (v >= lo +
|
|
|
|
|
+ 2325 VAL(INTEGER,
|
|
|
|
|
+ 2326 span))) THEN
|
|
|
|
|
+ 2327 SemError(222)
|
|
|
|
|
+ 2328 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 2329 lo, span)
|
|
|
|
|
+ 2330 END
|
|
|
|
|
+ 2331 END; .) .
|
|
|
|
|
+ 2332 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
+ 2333 = ident (. LexName(n); .) .
|
|
|
|
|
+ 2334
|
|
|
|
|
+ 2335 END M2.
|
|
|
|
|
|
|
|
0 errors
|
|
0 errors
|
|
|
|
|
|