|
|
@@ -596,1184 +596,1193 @@ Listing:
|
|
|
579 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
580 SymTab.CloseProc;
|
|
|
581 QbeGen.AbortFunc; .)
|
|
|
- 582 | (. QbeGen.EndFuncHeader; .)
|
|
|
- 583 Block<pn> (. SymTab.CloseProc;
|
|
|
- 584 QbeGen.EndFunc(
|
|
|
- 585 SymTab.ProcRes(pn)); .) ) .
|
|
|
- 586 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
- 587 = DeclSeq
|
|
|
- 588 [ "BEGIN"
|
|
|
- 589 [ StatSeq ] ]
|
|
|
- 590 "END"
|
|
|
- 591 GetIdent<m2> (. IF ~SymTab.Equal(pn, m2) THEN
|
|
|
- 592 SemError(202) END; .) .
|
|
|
- 593 StatSeq
|
|
|
- 594 = Statement { ";" Statement } .
|
|
|
- 595 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
- 596 = AssOrCall
|
|
|
- 597 | IfStat
|
|
|
- 598 | WhileStat
|
|
|
- 599 | RepeatStat
|
|
|
- 600 | LoopStat
|
|
|
- 601 | ForStat
|
|
|
- 602 | CaseStat
|
|
|
- 603 | WithStat
|
|
|
- 604 | ReturnStat
|
|
|
- 605 | NewStat
|
|
|
- 606 | DisposeStat
|
|
|
- 607 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
- 608 QbeGen.Jmp(lx)
|
|
|
- 609 ELSE SemError(230) END; .) .
|
|
|
- 610 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
- 611 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
- 612 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
- 613 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 614 dk: INTEGER;
|
|
|
- 615 qd, qm: QbeGen.QVal;
|
|
|
- 616 qn: SymTab.Name;
|
|
|
- 617 sfx: BOOLEAN;
|
|
|
- 618 bt: SymTab.TypeIndex; .)
|
|
|
- 619 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 620 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 621 ELSIF (dk # SymTab.KindVar)
|
|
|
- 622 & (dk # SymTab.KindParam)
|
|
|
- 623 & (dk # SymTab.KindField) THEN
|
|
|
- 624 SemError(210)
|
|
|
- 625 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 626 SymTab.ClPtr THEN
|
|
|
- 627 SemError(219)
|
|
|
- 628 ELSE bt := SymTab.PtrBase(dt);
|
|
|
- 629 IF bt #
|
|
|
- 630 SymTab.InvalidType THEN
|
|
|
- 631 QbeGen.NewHeap(bt, qm);
|
|
|
- 632 QbeGen.InitHeap(qm, bt);
|
|
|
- 633 IF sfx
|
|
|
- 634 OR (dk =
|
|
|
- 635 SymTab.KindField) THEN
|
|
|
- 636 QbeGen.ElemStore(qd, qm,
|
|
|
- 637 dt)
|
|
|
- 638 ELSE QbeGen.StorePtr(qn,
|
|
|
- 639 qm)
|
|
|
- 640 END
|
|
|
- 641 END
|
|
|
- 642 END; .) .
|
|
|
- 643 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 644 dk: INTEGER;
|
|
|
- 645 qd, qv: QbeGen.QVal;
|
|
|
- 646 qn: SymTab.Name;
|
|
|
- 647 sfx: BOOLEAN; .)
|
|
|
- 648 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 649 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 650 ELSIF (dk # SymTab.KindVar)
|
|
|
- 651 & (dk # SymTab.KindParam)
|
|
|
- 652 & (dk # SymTab.KindField) THEN
|
|
|
- 653 SemError(210)
|
|
|
- 654 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 655 SymTab.ClPtr THEN
|
|
|
- 656 SemError(219)
|
|
|
- 657 ELSE
|
|
|
- 658 IF sfx
|
|
|
- 659 OR (dk =
|
|
|
- 660 SymTab.KindField) THEN
|
|
|
- 661 QbeGen.ElemLoad(qd, dt,
|
|
|
- 662 qv)
|
|
|
- 663 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
- 664 END;
|
|
|
- 665 QbeGen.FreeHeap(qv);
|
|
|
- 666 IF sfx
|
|
|
- 667 OR (dk =
|
|
|
- 668 SymTab.KindField) THEN
|
|
|
- 669 QbeGen.ElemStore(qd, "0",
|
|
|
- 670 dt)
|
|
|
- 671 ELSE QbeGen.StorePtr(qn,
|
|
|
- 672 "0")
|
|
|
- 673 END
|
|
|
- 674 END; .) .
|
|
|
- 675 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
- 676 address; field designators resolve through both stacks. *)
|
|
|
- 677 WithStat (. VAR nW: CARDINAL; .)
|
|
|
- 678 = "WITH" (. nW := 0; .)
|
|
|
- 679 WithItem<nW> { "," WithItem<nW> }
|
|
|
- 680 "DO" StatSeq "END"
|
|
|
- 681 (. WHILE nW > 0 DO
|
|
|
- 682 SymTab.PopScope;
|
|
|
- 683 QbeGen.PopWith;
|
|
|
- 684 DEC(nW)
|
|
|
- 685 END; .) .
|
|
|
- 686 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
- 687 dk: INTEGER;
|
|
|
- 688 qd, qe: QbeGen.QVal;
|
|
|
- 689 qn: SymTab.Name;
|
|
|
- 690 sfx: BOOLEAN; .)
|
|
|
- 691 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 692 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 693 ELSIF (SymTab.ClassOf(dt) #
|
|
|
- 694 SymTab.ClRecord)
|
|
|
- 695 & (SymTab.ClassOf(dt) #
|
|
|
- 696 SymTab.ClClass) THEN
|
|
|
- 697 SemError(215)
|
|
|
- 698 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
- 699 QbeGen.PushWith(qd);
|
|
|
- 700 INC(nW)
|
|
|
- 701 END; .) .
|
|
|
- 702 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
- 703 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
- 704 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
- 705 dk: INTEGER;
|
|
|
- 706 qd, qe, qt: QbeGen.QVal;
|
|
|
- 707 qn: SymTab.Name;
|
|
|
- 708 ct2, res0: SymTab.TypeIndex;
|
|
|
- 709 q2, mg0: QbeGen.QVal;
|
|
|
- 710 isR, conv: BOOLEAN;
|
|
|
- 711 called, sfx: BOOLEAN; .)
|
|
|
- 712 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 713 ( ":="
|
|
|
- 714 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
- 715 & (dk # SymTab.KindVar)
|
|
|
- 716 & (dk # SymTab.KindParam)
|
|
|
- 717 & (dk # SymTab.KindField) THEN
|
|
|
- 718 SemError(210)
|
|
|
- 719 ELSIF ~SymTab.Assignable(et,
|
|
|
- 720 dt) THEN
|
|
|
+ 582 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
+ 583 SymTab.CloseProc;
|
|
|
+ 584 QbeGen.AbortFunc; .)
|
|
|
+ 585 | (. QbeGen.EndFuncHeader; .)
|
|
|
+ 586 Block<pn> (. SymTab.CloseProc;
|
|
|
+ 587 QbeGen.EndFunc(
|
|
|
+ 588 SymTab.ProcRes(pn)); .) ) .
|
|
|
+ 589 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
+ 590 = DeclSeq
|
|
|
+ 591 [ "BEGIN"
|
|
|
+ 592 [ StatSeq ] ]
|
|
|
+ 593 "END"
|
|
|
+ 594 GetIdent<m2> (. IF ~SymTab.Equal(pn, m2) THEN
|
|
|
+ 595 SemError(202) END; .) .
|
|
|
+ 596 StatSeq
|
|
|
+ 597 = Statement { ";" Statement } .
|
|
|
+ 598 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
+ 599 = AssOrCall
|
|
|
+ 600 | IfStat
|
|
|
+ 601 | WhileStat
|
|
|
+ 602 | RepeatStat
|
|
|
+ 603 | LoopStat
|
|
|
+ 604 | ForStat
|
|
|
+ 605 | CaseStat
|
|
|
+ 606 | WithStat
|
|
|
+ 607 | ReturnStat
|
|
|
+ 608 | NewStat
|
|
|
+ 609 | DisposeStat
|
|
|
+ 610 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
+ 611 QbeGen.Jmp(lx)
|
|
|
+ 612 ELSE SemError(230) END; .) .
|
|
|
+ 613 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
+ 614 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
+ 615 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
+ 616 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 617 dk: INTEGER;
|
|
|
+ 618 qd, qm: QbeGen.QVal;
|
|
|
+ 619 qn: SymTab.Name;
|
|
|
+ 620 sfx: BOOLEAN;
|
|
|
+ 621 bt: SymTab.TypeIndex; .)
|
|
|
+ 622 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 623 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 624 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 625 & (dk # SymTab.KindParam)
|
|
|
+ 626 & (dk # SymTab.KindField) THEN
|
|
|
+ 627 SemError(210)
|
|
|
+ 628 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 629 SymTab.ClPtr THEN
|
|
|
+ 630 SemError(219)
|
|
|
+ 631 ELSE bt := SymTab.PtrBase(dt);
|
|
|
+ 632 IF bt #
|
|
|
+ 633 SymTab.InvalidType THEN
|
|
|
+ 634 QbeGen.NewHeap(bt, qm);
|
|
|
+ 635 QbeGen.InitHeap(qm, bt);
|
|
|
+ 636 IF sfx
|
|
|
+ 637 OR (dk =
|
|
|
+ 638 SymTab.KindField) THEN
|
|
|
+ 639 QbeGen.ElemStore(qd, qm,
|
|
|
+ 640 dt)
|
|
|
+ 641 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 642 qm)
|
|
|
+ 643 END
|
|
|
+ 644 END
|
|
|
+ 645 END; .) .
|
|
|
+ 646 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 647 dk: INTEGER;
|
|
|
+ 648 qd, qv: QbeGen.QVal;
|
|
|
+ 649 qn: SymTab.Name;
|
|
|
+ 650 sfx: BOOLEAN; .)
|
|
|
+ 651 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 652 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 653 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 654 & (dk # SymTab.KindParam)
|
|
|
+ 655 & (dk # SymTab.KindField) THEN
|
|
|
+ 656 SemError(210)
|
|
|
+ 657 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 658 SymTab.ClPtr THEN
|
|
|
+ 659 SemError(219)
|
|
|
+ 660 ELSE
|
|
|
+ 661 IF sfx
|
|
|
+ 662 OR (dk =
|
|
|
+ 663 SymTab.KindField) THEN
|
|
|
+ 664 QbeGen.ElemLoad(qd, dt,
|
|
|
+ 665 qv)
|
|
|
+ 666 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
+ 667 END;
|
|
|
+ 668 QbeGen.FreeHeap(qv);
|
|
|
+ 669 IF sfx
|
|
|
+ 670 OR (dk =
|
|
|
+ 671 SymTab.KindField) THEN
|
|
|
+ 672 QbeGen.ElemStore(qd, "0",
|
|
|
+ 673 dt)
|
|
|
+ 674 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 675 "0")
|
|
|
+ 676 END
|
|
|
+ 677 END; .) .
|
|
|
+ 678 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
+ 679 address; field designators resolve through both stacks. *)
|
|
|
+ 680 WithStat (. VAR nW: CARDINAL; .)
|
|
|
+ 681 = "WITH" (. nW := 0; .)
|
|
|
+ 682 WithItem<nW> { "," WithItem<nW> }
|
|
|
+ 683 "DO" StatSeq "END"
|
|
|
+ 684 (. WHILE nW > 0 DO
|
|
|
+ 685 SymTab.PopScope;
|
|
|
+ 686 QbeGen.PopWith;
|
|
|
+ 687 DEC(nW)
|
|
|
+ 688 END; .) .
|
|
|
+ 689 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 690 dk: INTEGER;
|
|
|
+ 691 qd, qe: QbeGen.QVal;
|
|
|
+ 692 qn: SymTab.Name;
|
|
|
+ 693 sfx: BOOLEAN; .)
|
|
|
+ 694 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 695 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 696 ELSIF (SymTab.ClassOf(dt) #
|
|
|
+ 697 SymTab.ClRecord)
|
|
|
+ 698 & (SymTab.ClassOf(dt) #
|
|
|
+ 699 SymTab.ClClass) THEN
|
|
|
+ 700 SemError(215)
|
|
|
+ 701 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
+ 702 QbeGen.PushWith(qd);
|
|
|
+ 703 INC(nW)
|
|
|
+ 704 END; .) .
|
|
|
+ 705 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
+ 706 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
+ 707 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
+ 708 dk: INTEGER;
|
|
|
+ 709 qd, qe, qt: QbeGen.QVal;
|
|
|
+ 710 qn: SymTab.Name;
|
|
|
+ 711 ct2, res0: SymTab.TypeIndex;
|
|
|
+ 712 q2, mg0: QbeGen.QVal;
|
|
|
+ 713 isR, conv: BOOLEAN;
|
|
|
+ 714 called, sfx: BOOLEAN; .)
|
|
|
+ 715 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 716 ( ":="
|
|
|
+ 717 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
+ 718 & (dk # SymTab.KindVar)
|
|
|
+ 719 & (dk # SymTab.KindParam)
|
|
|
+ 720 & (dk # SymTab.KindField) THEN
|
|
|
721 SemError(210)
|
|
|
- 722 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 723 & (SymTab.ClassOf(dt) =
|
|
|
- 724 SymTab.ClClass) THEN
|
|
|
- 725 SemError(230) END;
|
|
|
- 726 isR := (dt #
|
|
|
- 727 SymTab.InvalidType)
|
|
|
- 728 & (SymTab.ClassOf(dt)
|
|
|
- 729 = SymTab.ClReal);
|
|
|
- 730 conv := isR
|
|
|
- 731 & SymTab.IsIntFamily(et);
|
|
|
- 732 IF ((dk = SymTab.KindVar)
|
|
|
- 733 OR (dk = SymTab.KindParam)
|
|
|
- 734 OR (dk = SymTab.KindField))
|
|
|
- 735 & (dt # SymTab.InvalidType)
|
|
|
- 736 & (et # SymTab.InvalidType)
|
|
|
- 737 & (SymTab.ClassOf(dt) #
|
|
|
- 738 SymTab.ClClass) THEN
|
|
|
- 739 IF sfx
|
|
|
- 740 OR (dk = SymTab.KindField) THEN
|
|
|
- 741 IF SymTab.ClassOf(dt) =
|
|
|
- 742 SymTab.ClArray THEN
|
|
|
- 743 QbeGen.CopyArray(qd, qe,
|
|
|
- 744 dt)
|
|
|
- 745 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 746 SymTab.ClSet THEN
|
|
|
- 747 QbeGen.CopySet(qd, qe,
|
|
|
- 748 SymTab.SetWords(dt),
|
|
|
- 749 SymTab.SetWords(et))
|
|
|
- 750 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 751 SymTab.ClRecord THEN
|
|
|
- 752 QbeGen.CopyRecord(qd, qe,
|
|
|
- 753 dt)
|
|
|
- 754 ELSIF conv THEN
|
|
|
- 755 QbeGen.ConvIR(qe, qt);
|
|
|
- 756 QbeGen.ElemStore(qd, qt,
|
|
|
- 757 dt)
|
|
|
- 758 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 759 dt)
|
|
|
- 760 END
|
|
|
- 761 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 762 SymTab.ClArray THEN
|
|
|
- 763 QbeGen.CopyArray(qd, qe, dt)
|
|
|
+ 722 ELSIF ~SymTab.Assignable(et,
|
|
|
+ 723 dt) THEN
|
|
|
+ 724 SemError(210)
|
|
|
+ 725 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 726 & (SymTab.ClassOf(dt) =
|
|
|
+ 727 SymTab.ClClass) THEN
|
|
|
+ 728 SemError(230) END;
|
|
|
+ 729 isR := (dt #
|
|
|
+ 730 SymTab.InvalidType)
|
|
|
+ 731 & (SymTab.ClassOf(dt)
|
|
|
+ 732 = SymTab.ClReal);
|
|
|
+ 733 conv := isR
|
|
|
+ 734 & SymTab.IsIntFamily(et);
|
|
|
+ 735 IF ((dk = SymTab.KindVar)
|
|
|
+ 736 OR (dk = SymTab.KindParam)
|
|
|
+ 737 OR (dk = SymTab.KindField))
|
|
|
+ 738 & (dt # SymTab.InvalidType)
|
|
|
+ 739 & (et # SymTab.InvalidType)
|
|
|
+ 740 & (SymTab.ClassOf(dt) #
|
|
|
+ 741 SymTab.ClClass) THEN
|
|
|
+ 742 IF sfx
|
|
|
+ 743 OR (dk = SymTab.KindField) THEN
|
|
|
+ 744 IF SymTab.ClassOf(dt) =
|
|
|
+ 745 SymTab.ClArray THEN
|
|
|
+ 746 QbeGen.CopyArray(qd, qe,
|
|
|
+ 747 dt)
|
|
|
+ 748 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 749 SymTab.ClSet THEN
|
|
|
+ 750 QbeGen.CopySet(qd, qe,
|
|
|
+ 751 SymTab.SetWords(dt),
|
|
|
+ 752 SymTab.SetWords(et))
|
|
|
+ 753 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 754 SymTab.ClRecord THEN
|
|
|
+ 755 QbeGen.CopyRecord(qd, qe,
|
|
|
+ 756 dt)
|
|
|
+ 757 ELSIF conv THEN
|
|
|
+ 758 QbeGen.ConvIR(qe, qt);
|
|
|
+ 759 QbeGen.ElemStore(qd, qt,
|
|
|
+ 760 dt)
|
|
|
+ 761 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 762 dt)
|
|
|
+ 763 END
|
|
|
764 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 765 SymTab.ClSet THEN
|
|
|
- 766 QbeGen.CopySet(qd, qe,
|
|
|
- 767 SymTab.SetWords(dt),
|
|
|
- 768 SymTab.SetWords(et))
|
|
|
- 769 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 770 SymTab.ClRecord THEN
|
|
|
- 771 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
+ 765 SymTab.ClArray THEN
|
|
|
+ 766 QbeGen.CopyArray(qd, qe, dt)
|
|
|
+ 767 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 768 SymTab.ClSet THEN
|
|
|
+ 769 QbeGen.CopySet(qd, qe,
|
|
|
+ 770 SymTab.SetWords(dt),
|
|
|
+ 771 SymTab.SetWords(et))
|
|
|
772 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 773 SymTab.ClPtr THEN
|
|
|
- 774 QbeGen.StorePtr(qn, qe)
|
|
|
- 775 ELSIF conv THEN
|
|
|
- 776 QbeGen.ConvIR(qe, qt);
|
|
|
- 777 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
- 778 ELSE
|
|
|
- 779 QbeGen.StoreVar(qn, qe, isR)
|
|
|
- 780 END
|
|
|
- 781 END; .)
|
|
|
- 782 | ArgList<qn, FALSE, ct2, q2, called>
|
|
|
- 783 | (* bare `P;`: proper parameterless
|
|
|
- 784 procedure call; anything else
|
|
|
- 785 here is 233 (was a bare syntax
|
|
|
- 786 error before 4.2) *)
|
|
|
- 787 (. IF (dk = SymTab.KindProc)
|
|
|
- 788 & ~sfx THEN
|
|
|
- 789 res0 := SymTab.ProcRes(qn);
|
|
|
- 790 IF res0 #
|
|
|
- 791 SymTab.InvalidType THEN
|
|
|
- 792 SemError(233)
|
|
|
- 793 ELSIF SymTab.ProcNPar(qn) #
|
|
|
- 794 0 THEN
|
|
|
+ 773 SymTab.ClRecord THEN
|
|
|
+ 774 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
+ 775 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 776 SymTab.ClPtr THEN
|
|
|
+ 777 QbeGen.StorePtr(qn, qe)
|
|
|
+ 778 ELSIF conv THEN
|
|
|
+ 779 QbeGen.ConvIR(qe, qt);
|
|
|
+ 780 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
+ 781 ELSE
|
|
|
+ 782 QbeGen.StoreVar(qn, qe, isR)
|
|
|
+ 783 END
|
|
|
+ 784 END; .)
|
|
|
+ 785 | ArgList<qn, FALSE, ct2, q2, called>
|
|
|
+ 786 | (* bare `P;`: proper parameterless
|
|
|
+ 787 procedure call; anything else
|
|
|
+ 788 here is 233 (was a bare syntax
|
|
|
+ 789 error before 4.2) *)
|
|
|
+ 790 (. IF (dk = SymTab.KindProc)
|
|
|
+ 791 & ~sfx THEN
|
|
|
+ 792 res0 := SymTab.ProcRes(qn);
|
|
|
+ 793 IF res0 #
|
|
|
+ 794 SymTab.InvalidType THEN
|
|
|
795 SemError(233)
|
|
|
- 796 ELSE QbeGen.Mangled(qn,
|
|
|
- 797 SymTab.ProcUid(qn), mg0);
|
|
|
- 798 QbeGen.CallBegin(mg0,
|
|
|
- 799 res0,
|
|
|
- 800 SymTab.ProcDepthOf(qn));
|
|
|
- 801 QbeGen.CallEnd(FALSE, q2)
|
|
|
- 802 END
|
|
|
- 803 ELSE SemError(233)
|
|
|
- 804 END; .) ) .
|
|
|
- 805 (* Actual-parameter list shared by statement and expression calls.
|
|
|
- 806 want selects CallEnd's result handling; t/q carry the call
|
|
|
- 807 value (statement calls discard). Arity/type failures are 233;
|
|
|
- 808 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
- 809 ArgList<pn: SymTab.Name; want: BOOLEAN;
|
|
|
- 810 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 811 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
- 812 res: SymTab.TypeIndex;
|
|
|
- 813 mg: QbeGen.QVal;
|
|
|
- 814 ok: BOOLEAN; .)
|
|
|
- 815 = "(" (. called := TRUE;
|
|
|
- 816 res := SymTab.ProcRes(pn);
|
|
|
- 817 ok := TRUE;
|
|
|
- 818 IF SymTab.SymKind(pn) #
|
|
|
- 819 SymTab.KindProc THEN
|
|
|
- 820 SemError(233); ok := FALSE
|
|
|
- 821 ELSE QbeGen.Mangled(pn,
|
|
|
- 822 SymTab.ProcUid(pn), mg);
|
|
|
- 823 QbeGen.CallBegin(mg, res,
|
|
|
- 824 SymTab.ProcDepthOf(pn))
|
|
|
- 825 END;
|
|
|
- 826 i := 0; .)
|
|
|
- 827 [ ActParam<pn, i> (. INC(i); .)
|
|
|
- 828 { "," ActParam<pn, i> (. INC(i); .) } ]
|
|
|
- 829 ")" (. IF ok THEN
|
|
|
- 830 IF i #
|
|
|
- 831 SymTab.ProcNPar(pn) THEN
|
|
|
- 832 SemError(233); ok := FALSE
|
|
|
- 833 END
|
|
|
- 834 END;
|
|
|
- 835 IF ~ok THEN
|
|
|
- 836 t := SymTab.InvalidType;
|
|
|
- 837 QbeGen.CopyOp("0", q)
|
|
|
- 838 ELSIF want THEN
|
|
|
- 839 IF res =
|
|
|
- 840 SymTab.InvalidType THEN
|
|
|
- 841 SemError(233);
|
|
|
- 842 t := SymTab.InvalidType;
|
|
|
- 843 QbeGen.CopyOp("0", q)
|
|
|
- 844 ELSE t := res;
|
|
|
- 845 QbeGen.CallEnd(TRUE, q)
|
|
|
- 846 END
|
|
|
- 847 ELSE
|
|
|
- 848 IF res #
|
|
|
- 849 SymTab.InvalidType THEN
|
|
|
- 850 SemError(233)
|
|
|
- 851 END;
|
|
|
- 852 t := SymTab.InvalidType;
|
|
|
- 853 QbeGen.CopyOp("0", q);
|
|
|
- 854 QbeGen.CallEnd(FALSE, q)
|
|
|
- 855 END; .) .
|
|
|
- 856 (* One actual: VAR formals take recorded designator addresses
|
|
|
- 857 (233 otherwise); value formals take converted expressions. *)
|
|
|
- 858 ActParam<pn: SymTab.Name; i: CARDINAL>(. VAR at, ft: SymTab.TypeIndex;
|
|
|
- 859 qe, qa, qt: QbeGen.QVal;
|
|
|
- 860 isV, conv: BOOLEAN; .)
|
|
|
- 861 = Expr<at, qe> (. ft := SymTab.ParamType(pn, i);
|
|
|
- 862 isV := SymTab.ParamIsVar(pn, i);
|
|
|
- 863 IF (at = SymTab.InvalidType)
|
|
|
- 864 OR (ft =
|
|
|
- 865 SymTab.InvalidType) THEN
|
|
|
- 866 ELSIF isV THEN
|
|
|
- 867 IF ~QbeGen.AddrOfVal(qe,
|
|
|
- 868 qa) THEN
|
|
|
- 869 SemError(233)
|
|
|
- 870 ELSIF ~SymTab.VarParamOk(at,
|
|
|
- 871 ft) THEN
|
|
|
- 872 SemError(233)
|
|
|
- 873 ELSIF ~QbeGen.CallArg(qa,
|
|
|
- 874 "l") THEN
|
|
|
- 875 SemError(233)
|
|
|
- 876 END
|
|
|
- 877 ELSE
|
|
|
- 878 IF ~SymTab.Assignable(at,
|
|
|
- 879 ft) THEN
|
|
|
+ 796 ELSIF SymTab.ProcNPar(qn) #
|
|
|
+ 797 0 THEN
|
|
|
+ 798 SemError(233)
|
|
|
+ 799 ELSE QbeGen.Mangled(qn,
|
|
|
+ 800 SymTab.ProcUid(qn), mg0);
|
|
|
+ 801 QbeGen.CallBegin(mg0,
|
|
|
+ 802 res0,
|
|
|
+ 803 SymTab.ProcDepthOf(qn),
|
|
|
+ 804 SymTab.IsExternal(qn));
|
|
|
+ 805 QbeGen.CallEnd(FALSE, q2)
|
|
|
+ 806 END
|
|
|
+ 807 ELSE SemError(233)
|
|
|
+ 808 END; .) ) .
|
|
|
+ 809 (* Actual-parameter list shared by statement and expression calls.
|
|
|
+ 810 want selects CallEnd's result handling; t/q carry the call
|
|
|
+ 811 value (statement calls discard). Arity/type failures are 233;
|
|
|
+ 812 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
+ 813 ArgList<pn: SymTab.Name; want: BOOLEAN;
|
|
|
+ 814 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 815 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
+ 816 res: SymTab.TypeIndex;
|
|
|
+ 817 mg: QbeGen.QVal;
|
|
|
+ 818 ok: BOOLEAN; .)
|
|
|
+ 819 = "(" (. called := TRUE;
|
|
|
+ 820 res := SymTab.ProcRes(pn);
|
|
|
+ 821 ok := TRUE;
|
|
|
+ 822 IF SymTab.SymKind(pn) #
|
|
|
+ 823 SymTab.KindProc THEN
|
|
|
+ 824 SemError(233); ok := FALSE
|
|
|
+ 825 ELSE QbeGen.Mangled(pn,
|
|
|
+ 826 SymTab.ProcUid(pn), mg);
|
|
|
+ 827 QbeGen.CallBegin(mg, res,
|
|
|
+ 828 SymTab.ProcDepthOf(pn),
|
|
|
+ 829 SymTab.IsExternal(pn))
|
|
|
+ 830 END;
|
|
|
+ 831 i := 0; .)
|
|
|
+ 832 [ ActParam<pn, i> (. INC(i); .)
|
|
|
+ 833 { "," ActParam<pn, i> (. INC(i); .) } ]
|
|
|
+ 834 ")" (. IF ok THEN
|
|
|
+ 835 IF i #
|
|
|
+ 836 SymTab.ProcNPar(pn) THEN
|
|
|
+ 837 SemError(233); ok := FALSE
|
|
|
+ 838 END
|
|
|
+ 839 END;
|
|
|
+ 840 IF ~ok THEN
|
|
|
+ 841 t := SymTab.InvalidType;
|
|
|
+ 842 QbeGen.CopyOp("0", q)
|
|
|
+ 843 ELSIF want THEN
|
|
|
+ 844 IF res =
|
|
|
+ 845 SymTab.InvalidType THEN
|
|
|
+ 846 SemError(233);
|
|
|
+ 847 t := SymTab.InvalidType;
|
|
|
+ 848 QbeGen.CopyOp("0", q)
|
|
|
+ 849 ELSE t := res;
|
|
|
+ 850 QbeGen.CallEnd(TRUE, q)
|
|
|
+ 851 END
|
|
|
+ 852 ELSE
|
|
|
+ 853 IF res #
|
|
|
+ 854 SymTab.InvalidType THEN
|
|
|
+ 855 SemError(233)
|
|
|
+ 856 END;
|
|
|
+ 857 t := SymTab.InvalidType;
|
|
|
+ 858 QbeGen.CopyOp("0", q);
|
|
|
+ 859 QbeGen.CallEnd(FALSE, q)
|
|
|
+ 860 END; .) .
|
|
|
+ 861 (* One actual: VAR formals take recorded designator addresses
|
|
|
+ 862 (233 otherwise); value formals take converted expressions. *)
|
|
|
+ 863 ActParam<pn: SymTab.Name; i: CARDINAL>(. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ 864 qe, qa, qt: QbeGen.QVal;
|
|
|
+ 865 isV, conv: BOOLEAN; .)
|
|
|
+ 866 = Expr<at, qe> (. ft := SymTab.ParamType(pn, i);
|
|
|
+ 867 isV := SymTab.ParamIsVar(pn, i);
|
|
|
+ 868 IF (at = SymTab.InvalidType)
|
|
|
+ 869 OR (ft =
|
|
|
+ 870 SymTab.InvalidType) THEN
|
|
|
+ 871 ELSIF isV THEN
|
|
|
+ 872 IF ~QbeGen.AddrOfVal(qe,
|
|
|
+ 873 qa) THEN
|
|
|
+ 874 SemError(233)
|
|
|
+ 875 ELSIF ~SymTab.VarParamOk(at,
|
|
|
+ 876 ft) THEN
|
|
|
+ 877 SemError(233)
|
|
|
+ 878 ELSIF ~QbeGen.CallArg(qa,
|
|
|
+ 879 "l") THEN
|
|
|
880 SemError(233)
|
|
|
- 881 ELSE
|
|
|
- 882 conv := (SymTab.ClassOf(
|
|
|
- 883 ft) = SymTab.ClReal)
|
|
|
- 884 & SymTab.IsIntFamily(at);
|
|
|
- 885 IF conv THEN
|
|
|
- 886 QbeGen.ConvIR(qe, qt);
|
|
|
- 887 IF ~QbeGen.CallArg(qt,
|
|
|
- 888 "d") THEN
|
|
|
- 889 SemError(233)
|
|
|
- 890 END
|
|
|
- 891 ELSIF ~QbeGen.CallArg(qe,
|
|
|
- 892 QbeGen.ArgClass(ft)) THEN
|
|
|
- 893 SemError(233)
|
|
|
- 894 END
|
|
|
- 895 END
|
|
|
- 896 END; .) .
|
|
|
- 897 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 898 q, lThen, lElse, lEnd:
|
|
|
- 899 QbeGen.QVal;
|
|
|
- 900 hasElse: BOOLEAN; .)
|
|
|
- 901 = "IF" (. hasElse := FALSE; .)
|
|
|
- 902 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 903 SemError(214) END;
|
|
|
- 904 QbeGen.NewLabel(lThen);
|
|
|
- 905 QbeGen.NewLabel(lElse);
|
|
|
- 906 QbeGen.NewLabel(lEnd);
|
|
|
- 907 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 908 QbeGen.EmitLabel(lThen); .)
|
|
|
- 909 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .)
|
|
|
- 910 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
- 911 QbeGen.NewLabel(lElse); .)
|
|
|
- 912 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 913 SemError(214) END;
|
|
|
- 914 QbeGen.NewLabel(lThen);
|
|
|
- 915 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 916 QbeGen.EmitLabel(lThen); .)
|
|
|
- 917 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .) }
|
|
|
- 918 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
- 919 hasElse := TRUE; .)
|
|
|
- 920 StatSeq ]
|
|
|
- 921 "END" (. IF hasElse THEN
|
|
|
- 922 QbeGen.EmitLabel(lEnd)
|
|
|
- 923 ELSE QbeGen.EmitLabel(lElse);
|
|
|
- 924 QbeGen.EmitLabel(lEnd)
|
|
|
- 925 END; .) .
|
|
|
- 926 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 927 q, lTop, lBody, lEnd:
|
|
|
- 928 QbeGen.QVal; .)
|
|
|
- 929 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
- 930 QbeGen.NewLabel(lBody);
|
|
|
- 931 QbeGen.NewLabel(lEnd);
|
|
|
- 932 QbeGen.EmitLabel(lTop); .)
|
|
|
- 933 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 934 SemError(214) END;
|
|
|
- 935 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
- 936 QbeGen.EmitLabel(lBody); .)
|
|
|
- 937 "DO" StatSeq (. QbeGen.Jmp(lTop); .)
|
|
|
- 938 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 939 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 940 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 941 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
- 942 QbeGen.NewLabel(lEnd);
|
|
|
- 943 QbeGen.EmitLabel(lTop); .)
|
|
|
- 944 StatSeq
|
|
|
- 945 "UNTIL" Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 946 SemError(214) END;
|
|
|
- 947 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
- 948 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 949 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 950 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
- 951 QbeGen.NewLabel(lEnd);
|
|
|
- 952 QbeGen.PushLoop(lEnd);
|
|
|
- 953 QbeGen.EmitLabel(lTop); .)
|
|
|
- 954 StatSeq
|
|
|
- 955 "END" (. QbeGen.Jmp(lTop);
|
|
|
- 956 QbeGen.PopLoop;
|
|
|
- 957 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 958 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
- 959 Runtime direction would need a compare-select; the literal
|
|
|
- 960 sign picks cslew/csegew at "DO" time. *)
|
|
|
- 961 ForStat (. VAR lv: SymTab.Name;
|
|
|
- 962 tlo, thi, tby:
|
|
|
- 963 SymTab.TypeIndex;
|
|
|
- 964 qlo, qhi, qby, qt, qk, qb:
|
|
|
- 965 QbeGen.QVal;
|
|
|
- 966 lTop, lBody, lEnd:
|
|
|
- 967 QbeGen.QVal;
|
|
|
- 968 by: INTEGER;
|
|
|
- 969 ok: BOOLEAN; .)
|
|
|
- 970 = "FOR" (. by := 1; .)
|
|
|
- 971 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
- 972 IF ~ok THEN
|
|
|
- 973 SemError(201)
|
|
|
- 974 ELSIF (SymTab.SymKind(lv) #
|
|
|
- 975 SymTab.KindVar)
|
|
|
- 976 & (SymTab.SymKind(lv) #
|
|
|
- 977 SymTab.KindParam) THEN
|
|
|
- 978 SemError(220); ok := FALSE
|
|
|
- 979 ELSIF ~SymTab.IsIntFamily(
|
|
|
- 980 SymTab.SymType(lv)) THEN
|
|
|
- 981 SemError(220); ok := FALSE
|
|
|
- 982 END; .)
|
|
|
- 983 ":=" Expr<tlo, qlo> (. IF ~SymTab.IsIntFamily(tlo) THEN
|
|
|
- 984 SemError(220); ok := FALSE
|
|
|
- 985 END; .)
|
|
|
- 986 "TO" Expr<thi, qhi> (. IF ~SymTab.IsIntFamily(thi) THEN
|
|
|
- 987 SemError(220); ok := FALSE
|
|
|
- 988 END; .)
|
|
|
- 989 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
- 990 SymTab.InvalidType)
|
|
|
- 991 & ~SymTab.IsIntFamily(tby) THEN
|
|
|
+ 881 END
|
|
|
+ 882 ELSE
|
|
|
+ 883 IF ~SymTab.Assignable(at,
|
|
|
+ 884 ft) THEN
|
|
|
+ 885 SemError(233)
|
|
|
+ 886 ELSE
|
|
|
+ 887 conv := (SymTab.ClassOf(
|
|
|
+ 888 ft) = SymTab.ClReal)
|
|
|
+ 889 & SymTab.IsIntFamily(at);
|
|
|
+ 890 IF conv THEN
|
|
|
+ 891 QbeGen.ConvIR(qe, qt);
|
|
|
+ 892 IF ~QbeGen.CallArg(qt,
|
|
|
+ 893 "d") THEN
|
|
|
+ 894 SemError(233)
|
|
|
+ 895 END
|
|
|
+ 896 ELSIF ~QbeGen.CallArg(qe,
|
|
|
+ 897 QbeGen.ArgClass(ft)) THEN
|
|
|
+ 898 SemError(233)
|
|
|
+ 899 END
|
|
|
+ 900 END
|
|
|
+ 901 END; .) .
|
|
|
+ 902 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 903 q, lThen, lElse, lEnd:
|
|
|
+ 904 QbeGen.QVal;
|
|
|
+ 905 hasElse: BOOLEAN; .)
|
|
|
+ 906 = "IF" (. hasElse := FALSE; .)
|
|
|
+ 907 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 908 SemError(214) END;
|
|
|
+ 909 QbeGen.NewLabel(lThen);
|
|
|
+ 910 QbeGen.NewLabel(lElse);
|
|
|
+ 911 QbeGen.NewLabel(lEnd);
|
|
|
+ 912 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 913 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 914 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .)
|
|
|
+ 915 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 916 QbeGen.NewLabel(lElse); .)
|
|
|
+ 917 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 918 SemError(214) END;
|
|
|
+ 919 QbeGen.NewLabel(lThen);
|
|
|
+ 920 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 921 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 922 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .) }
|
|
|
+ 923 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 924 hasElse := TRUE; .)
|
|
|
+ 925 StatSeq ]
|
|
|
+ 926 "END" (. IF hasElse THEN
|
|
|
+ 927 QbeGen.EmitLabel(lEnd)
|
|
|
+ 928 ELSE QbeGen.EmitLabel(lElse);
|
|
|
+ 929 QbeGen.EmitLabel(lEnd)
|
|
|
+ 930 END; .) .
|
|
|
+ 931 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 932 q, lTop, lBody, lEnd:
|
|
|
+ 933 QbeGen.QVal; .)
|
|
|
+ 934 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
+ 935 QbeGen.NewLabel(lBody);
|
|
|
+ 936 QbeGen.NewLabel(lEnd);
|
|
|
+ 937 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 938 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 939 SemError(214) END;
|
|
|
+ 940 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
+ 941 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 942 "DO" StatSeq (. QbeGen.Jmp(lTop); .)
|
|
|
+ 943 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 944 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 945 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 946 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
+ 947 QbeGen.NewLabel(lEnd);
|
|
|
+ 948 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 949 StatSeq
|
|
|
+ 950 "UNTIL" Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 951 SemError(214) END;
|
|
|
+ 952 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
+ 953 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 954 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 955 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
+ 956 QbeGen.NewLabel(lEnd);
|
|
|
+ 957 QbeGen.PushLoop(lEnd);
|
|
|
+ 958 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 959 StatSeq
|
|
|
+ 960 "END" (. QbeGen.Jmp(lTop);
|
|
|
+ 961 QbeGen.PopLoop;
|
|
|
+ 962 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 963 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
+ 964 Runtime direction would need a compare-select; the literal
|
|
|
+ 965 sign picks cslew/csegew at "DO" time. *)
|
|
|
+ 966 ForStat (. VAR lv: SymTab.Name;
|
|
|
+ 967 tlo, thi, tby:
|
|
|
+ 968 SymTab.TypeIndex;
|
|
|
+ 969 qlo, qhi, qby, qt, qk, qb:
|
|
|
+ 970 QbeGen.QVal;
|
|
|
+ 971 lTop, lBody, lEnd:
|
|
|
+ 972 QbeGen.QVal;
|
|
|
+ 973 by: INTEGER;
|
|
|
+ 974 ok: BOOLEAN; .)
|
|
|
+ 975 = "FOR" (. by := 1; .)
|
|
|
+ 976 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
+ 977 IF ~ok THEN
|
|
|
+ 978 SemError(201)
|
|
|
+ 979 ELSIF (SymTab.SymKind(lv) #
|
|
|
+ 980 SymTab.KindVar)
|
|
|
+ 981 & (SymTab.SymKind(lv) #
|
|
|
+ 982 SymTab.KindParam) THEN
|
|
|
+ 983 SemError(220); ok := FALSE
|
|
|
+ 984 ELSIF ~SymTab.IsIntFamily(
|
|
|
+ 985 SymTab.SymType(lv)) THEN
|
|
|
+ 986 SemError(220); ok := FALSE
|
|
|
+ 987 END; .)
|
|
|
+ 988 ":=" Expr<tlo, qlo> (. IF ~SymTab.IsIntFamily(tlo) THEN
|
|
|
+ 989 SemError(220); ok := FALSE
|
|
|
+ 990 END; .)
|
|
|
+ 991 "TO" Expr<thi, qhi> (. IF ~SymTab.IsIntFamily(thi) THEN
|
|
|
992 SemError(220); ok := FALSE
|
|
|
- 993 END;
|
|
|
- 994 IF ~SymTab.ConstInt(qby, by) THEN
|
|
|
- 995 SemError(230); by := 1
|
|
|
- 996 ELSIF by = 0 THEN
|
|
|
- 997 SemError(220); by := 1
|
|
|
- 998 END; .) ]
|
|
|
- 999 "DO" (. IF ok THEN
|
|
|
- 1000 QbeGen.StoreVar(lv, qlo,
|
|
|
- 1001 FALSE) END;
|
|
|
- 1002 QbeGen.NewLabel(lTop);
|
|
|
- 1003 QbeGen.NewLabel(lBody);
|
|
|
- 1004 QbeGen.NewLabel(lEnd);
|
|
|
- 1005 QbeGen.EmitLabel(lTop);
|
|
|
- 1006 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
- 1007 QbeGen.NewTemp(qk);
|
|
|
- 1008 IF by > 0 THEN
|
|
|
- 1009 QbeGen.Op3("cslew", qk,
|
|
|
- 1010 qt, qhi, FALSE)
|
|
|
- 1011 ELSE QbeGen.Op3("csgew", qk,
|
|
|
- 1012 qt, qhi, FALSE)
|
|
|
- 1013 END;
|
|
|
- 1014 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
- 1015 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1016 StatSeq
|
|
|
- 1017 "END" (. IF ok THEN
|
|
|
- 1018 QbeGen.LoadVar(lv, FALSE,
|
|
|
- 1019 qt);
|
|
|
- 1020 QbeGen.IntStr(by, qb);
|
|
|
- 1021 QbeGen.NewTemp(qk);
|
|
|
- 1022 QbeGen.Op3("add", qk,
|
|
|
- 1023 qt, qb, FALSE);
|
|
|
- 1024 QbeGen.StoreVar(lv, qk,
|
|
|
- 1025 FALSE) END;
|
|
|
- 1026 QbeGen.Jmp(lTop);
|
|
|
- 1027 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1028 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
- 1029 qsel, lEnd: QbeGen.QVal; .)
|
|
|
- 1030 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
- 1031 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
- 1032 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
- 1033 [ "ELSE" StatSeq ]
|
|
|
- 1034 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1035 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 1036 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 1037 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 1038 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 1039 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1040 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
- 1041 = (. QbeGen.NewLabel(lBody);
|
|
|
- 1042 QbeGen.NewLabel(lAfter); .)
|
|
|
- 1043 CaseLabel<tsel, qsel, lBody>
|
|
|
- 1044 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
- 1045 ":" (. QbeGen.Jmp(lAfter);
|
|
|
- 1046 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1047 StatSeq (. QbeGen.Jmp(lEnd);
|
|
|
- 1048 QbeGen.EmitLabel(lAfter); .) .
|
|
|
- 1049 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1050 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 1051 q2, q3, qc, qd, qe:
|
|
|
- 1052 QbeGen.QVal;
|
|
|
- 1053 lNext: QbeGen.QVal; .)
|
|
|
- 1054 = Expr<t2, q2> (. IF (t2 #
|
|
|
- 1055 SymTab.InvalidType)
|
|
|
- 1056 & (tsel #
|
|
|
- 1057 SymTab.InvalidType)
|
|
|
- 1058 & ((SymTab.ClassOf(t2) =
|
|
|
- 1059 SymTab.ClSet)
|
|
|
- 1060 OR (SymTab.ClassOf(tsel) =
|
|
|
- 1061 SymTab.ClSet)) THEN
|
|
|
- 1062 SemError(230)
|
|
|
- 1063 ELSIF (t2 #
|
|
|
- 1064 SymTab.InvalidType)
|
|
|
- 1065 & (tsel #
|
|
|
- 1066 SymTab.InvalidType)
|
|
|
- 1067 & ~SymTab.EqCheck(t2,
|
|
|
- 1068 tsel) THEN
|
|
|
- 1069 SemError(213) END;
|
|
|
- 1070 IF ~QbeGen.IsImm(q2) THEN
|
|
|
- 1071 SemError(230);
|
|
|
- 1072 QbeGen.CopyOp("0", q2)
|
|
|
- 1073 END;
|
|
|
- 1074 QbeGen.NewLabel(lNext);
|
|
|
- 1075 QbeGen.Cmp(SymTab.OpEq,
|
|
|
- 1076 qsel, q2, qc, FALSE);
|
|
|
- 1077 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
- 1078 QbeGen.EmitLabel(lNext); .)
|
|
|
- 1079 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
- 1080 SymTab.InvalidType)
|
|
|
- 1081 & (tsel #
|
|
|
- 1082 SymTab.InvalidType)
|
|
|
- 1083 & ~SymTab.EqCheck(t3,
|
|
|
- 1084 tsel) THEN
|
|
|
- 1085 SemError(213) END;
|
|
|
- 1086 IF ~QbeGen.IsImm(q3) THEN
|
|
|
- 1087 SemError(230);
|
|
|
- 1088 QbeGen.CopyOp("0", q3)
|
|
|
- 1089 END;
|
|
|
- 1090 QbeGen.Cmp(SymTab.OpGe,
|
|
|
- 1091 qsel, q2, qc, FALSE);
|
|
|
- 1092 QbeGen.Cmp(SymTab.OpLe,
|
|
|
- 1093 qsel, q3, qd, FALSE);
|
|
|
- 1094 QbeGen.NewTemp(qe);
|
|
|
- 1095 QbeGen.Op3("and", qe, qc, qd,
|
|
|
- 1096 FALSE);
|
|
|
- 1097 QbeGen.NewLabel(lNext);
|
|
|
- 1098 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
- 1099 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
- 1100 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1101 q, qt: QbeGen.QVal;
|
|
|
- 1102 res: SymTab.TypeIndex;
|
|
|
- 1103 hadE, conv: BOOLEAN; .)
|
|
|
- 1104 = "RETURN" (. hadE := FALSE; .)
|
|
|
- 1105 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
- 1106 (. conv := FALSE;
|
|
|
- 1107 IF ~SymTab.InProc() THEN
|
|
|
- 1108 SemError(232)
|
|
|
- 1109 ELSE res := SymTab.CurRes();
|
|
|
- 1110 IF ~hadE THEN
|
|
|
- 1111 IF res #
|
|
|
- 1112 SymTab.InvalidType THEN
|
|
|
- 1113 SemError(232)
|
|
|
- 1114 ELSE QbeGen.EmitRet(q,
|
|
|
- 1115 FALSE)
|
|
|
- 1116 END
|
|
|
- 1117 ELSIF (res =
|
|
|
- 1118 SymTab.InvalidType)
|
|
|
- 1119 OR (t #
|
|
|
- 1120 SymTab.InvalidType)
|
|
|
- 1121 & ~SymTab.Assignable(t,
|
|
|
- 1122 res) THEN
|
|
|
- 1123 SemError(232)
|
|
|
- 1124 ELSE
|
|
|
- 1125 conv := (SymTab.ClassOf(
|
|
|
- 1126 res) = SymTab.ClReal)
|
|
|
- 1127 & SymTab.IsIntFamily(t);
|
|
|
- 1128 IF conv THEN
|
|
|
- 1129 QbeGen.ConvIR(q, qt);
|
|
|
- 1130 QbeGen.EmitRet(qt, TRUE)
|
|
|
- 1131 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
- 1132 END
|
|
|
- 1133 END
|
|
|
- 1134 END; .) .
|
|
|
- 1135 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 1136 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 1137 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 1138 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 1139 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 1140 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 1141 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 1142 (. VAR n, fn: SymTab.Name;
|
|
|
- 1143 cls: INTEGER;
|
|
|
- 1144 curT, it, eT, bt:
|
|
|
- 1145 SymTab.TypeIndex;
|
|
|
- 1146 iq, ql, qlo, qhi, qe:
|
|
|
- 1147 QbeGen.QVal;
|
|
|
- 1148 lo, hi: INTEGER;
|
|
|
- 1149 fo: INTEGER;
|
|
|
- 1150 isOpen: BOOLEAN;
|
|
|
- 1151 qb: QbeGen.QVal; .)
|
|
|
- 1152 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
- 1153 sfx := FALSE;
|
|
|
- 1154 IF ~SymTab.Lookup(n) THEN
|
|
|
- 1155 SemError(201);
|
|
|
- 1156 t := SymTab.InvalidType;
|
|
|
- 1157 k := -1;
|
|
|
- 1158 QbeGen.CopyOp("0", q)
|
|
|
- 1159 ELSE
|
|
|
- 1160 t := SymTab.SymType(n);
|
|
|
- 1161 k := SymTab.SymKind(n);
|
|
|
- 1162 IF k = SymTab.KindConst THEN
|
|
|
- 1163 IF SymTab.Equal(n,
|
|
|
- 1164 "TRUE") THEN
|
|
|
- 1165 t := SymTab.BoolType();
|
|
|
- 1166 QbeGen.CopyOp("1", q)
|
|
|
- 1167 ELSIF SymTab.Equal(n,
|
|
|
- 1168 "FALSE") THEN
|
|
|
- 1169 t := SymTab.BoolType();
|
|
|
- 1170 QbeGen.CopyOp("0", q)
|
|
|
- 1171 ELSIF SymTab.Equal(n,
|
|
|
- 1172 "NIL") THEN
|
|
|
- 1173 QbeGen.CopyOp("0", q)
|
|
|
- 1174 ELSE
|
|
|
- 1175 cls :=
|
|
|
- 1176 SymTab.ClassOf(t);
|
|
|
- 1177 IF (t #
|
|
|
- 1178 SymTab.InvalidType)
|
|
|
- 1179 & ((cls = SymTab.ClInt)
|
|
|
- 1180 OR (cls
|
|
|
- 1181 = SymTab.ClChar)
|
|
|
- 1182 OR (cls
|
|
|
- 1183 = SymTab.ClReal)
|
|
|
- 1184 OR (cls
|
|
|
- 1185 = SymTab.ClNil)) THEN
|
|
|
- 1186 IF cls = SymTab.ClNil THEN
|
|
|
- 1187 QbeGen.CopyOp("0", q)
|
|
|
- 1188 ELSE
|
|
|
- 1189 QbeGen.LoadVar(n,
|
|
|
- 1190 cls = SymTab.ClReal,
|
|
|
- 1191 q)
|
|
|
- 1192 END
|
|
|
- 1193 ELSE
|
|
|
- 1194 IF t #
|
|
|
- 1195 SymTab.InvalidType THEN
|
|
|
- 1196 SemError(230)
|
|
|
- 1197 END;
|
|
|
- 1198 QbeGen.CopyOp("0", q)
|
|
|
- 1199 END
|
|
|
- 1200 END
|
|
|
- 1201 ELSIF (k = SymTab.KindVar)
|
|
|
- 1202 OR (k = SymTab.KindParam) THEN
|
|
|
- 1203 cls :=
|
|
|
- 1204 SymTab.ClassOf(t);
|
|
|
- 1205 IF (cls = SymTab.ClInt)
|
|
|
- 1206 OR (cls = SymTab.ClBool)
|
|
|
- 1207 OR (cls = SymTab.ClChar)
|
|
|
- 1208 OR (cls
|
|
|
- 1209 = SymTab.ClReal) THEN
|
|
|
- 1210 QbeGen.LoadVar(n,
|
|
|
- 1211 cls = SymTab.ClReal, q)
|
|
|
- 1212 ELSIF cls = SymTab.ClPtr THEN
|
|
|
- 1213 QbeGen.LoadPtr(n, q)
|
|
|
- 1214 ELSIF (cls
|
|
|
- 1215 = SymTab.ClArray)
|
|
|
- 1216 OR (cls
|
|
|
- 1217 = SymTab.ClSet)
|
|
|
- 1218 OR (cls
|
|
|
- 1219 = SymTab.ClRecord)
|
|
|
- 1220 OR (cls
|
|
|
- 1221 = SymTab.ClClass) THEN
|
|
|
- 1222 QbeGen.AddrOf(n, q)
|
|
|
- 1223 ELSE SemError(230);
|
|
|
- 1224 QbeGen.CopyOp("0", q)
|
|
|
- 1225 END
|
|
|
- 1226 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 1227 IF k = SymTab.KindImport THEN
|
|
|
- 1228 SemError(230)
|
|
|
- 1229 ELSIF k =
|
|
|
- 1230 SymTab.KindProc THEN
|
|
|
- 1231 (* bare procedure name:
|
|
|
- 1232 a following ArgList
|
|
|
- 1233 makes it a call;
|
|
|
- 1234 otherwise Fact
|
|
|
- 1235 reports 230 *)
|
|
|
- 1236 ELSE
|
|
|
- 1237 IF k = SymTab.KindField THEN
|
|
|
- 1238 IF QbeGen.TopWith(qb) THEN
|
|
|
- 1239 fo :=
|
|
|
- 1240 SymTab.FieldOffset(
|
|
|
- 1241 SymTab.FieldOwner(n),
|
|
|
- 1242 n);
|
|
|
- 1243 QbeGen.FieldAddr(qb,
|
|
|
- 1244 fo, q);
|
|
|
- 1245 sfx := TRUE
|
|
|
- 1246 ELSE SemError(230);
|
|
|
- 1247 QbeGen.CopyOp("0", q)
|
|
|
- 1248 END
|
|
|
- 1249 END
|
|
|
- 1250 END
|
|
|
- 1251 END
|
|
|
- 1252 END; .)
|
|
|
- 1253 { "[" Expr<it, iq>
|
|
|
- 1254 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1255 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1256 SymTab.ClArray THEN
|
|
|
- 1257 SemError(217);
|
|
|
- 1258 t := SymTab.InvalidType
|
|
|
- 1259 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
- 1260 & (SymTab.ClassOf(it) #
|
|
|
- 1261 SymTab.ClChar) THEN
|
|
|
- 1262 SemError(218);
|
|
|
+ 993 END; .)
|
|
|
+ 994 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
+ 995 SymTab.InvalidType)
|
|
|
+ 996 & ~SymTab.IsIntFamily(tby) THEN
|
|
|
+ 997 SemError(220); ok := FALSE
|
|
|
+ 998 END;
|
|
|
+ 999 IF ~SymTab.ConstInt(qby, by) THEN
|
|
|
+ 1000 SemError(230); by := 1
|
|
|
+ 1001 ELSIF by = 0 THEN
|
|
|
+ 1002 SemError(220); by := 1
|
|
|
+ 1003 END; .) ]
|
|
|
+ 1004 "DO" (. IF ok THEN
|
|
|
+ 1005 QbeGen.StoreVar(lv, qlo,
|
|
|
+ 1006 FALSE) END;
|
|
|
+ 1007 QbeGen.NewLabel(lTop);
|
|
|
+ 1008 QbeGen.NewLabel(lBody);
|
|
|
+ 1009 QbeGen.NewLabel(lEnd);
|
|
|
+ 1010 QbeGen.EmitLabel(lTop);
|
|
|
+ 1011 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
+ 1012 QbeGen.NewTemp(qk);
|
|
|
+ 1013 IF by > 0 THEN
|
|
|
+ 1014 QbeGen.Op3("cslew", qk,
|
|
|
+ 1015 qt, qhi, FALSE)
|
|
|
+ 1016 ELSE QbeGen.Op3("csgew", qk,
|
|
|
+ 1017 qt, qhi, FALSE)
|
|
|
+ 1018 END;
|
|
|
+ 1019 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
+ 1020 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1021 StatSeq
|
|
|
+ 1022 "END" (. IF ok THEN
|
|
|
+ 1023 QbeGen.LoadVar(lv, FALSE,
|
|
|
+ 1024 qt);
|
|
|
+ 1025 QbeGen.IntStr(by, qb);
|
|
|
+ 1026 QbeGen.NewTemp(qk);
|
|
|
+ 1027 QbeGen.Op3("add", qk,
|
|
|
+ 1028 qt, qb, FALSE);
|
|
|
+ 1029 QbeGen.StoreVar(lv, qk,
|
|
|
+ 1030 FALSE) END;
|
|
|
+ 1031 QbeGen.Jmp(lTop);
|
|
|
+ 1032 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1033 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
+ 1034 qsel, lEnd: QbeGen.QVal; .)
|
|
|
+ 1035 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
+ 1036 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
+ 1037 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
+ 1038 [ "ELSE" StatSeq ]
|
|
|
+ 1039 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1040 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 1041 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 1042 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 1043 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 1044 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1045 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
+ 1046 = (. QbeGen.NewLabel(lBody);
|
|
|
+ 1047 QbeGen.NewLabel(lAfter); .)
|
|
|
+ 1048 CaseLabel<tsel, qsel, lBody>
|
|
|
+ 1049 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
+ 1050 ":" (. QbeGen.Jmp(lAfter);
|
|
|
+ 1051 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1052 StatSeq (. QbeGen.Jmp(lEnd);
|
|
|
+ 1053 QbeGen.EmitLabel(lAfter); .) .
|
|
|
+ 1054 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1055 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 1056 q2, q3, qc, qd, qe:
|
|
|
+ 1057 QbeGen.QVal;
|
|
|
+ 1058 lNext: QbeGen.QVal; .)
|
|
|
+ 1059 = Expr<t2, q2> (. IF (t2 #
|
|
|
+ 1060 SymTab.InvalidType)
|
|
|
+ 1061 & (tsel #
|
|
|
+ 1062 SymTab.InvalidType)
|
|
|
+ 1063 & ((SymTab.ClassOf(t2) =
|
|
|
+ 1064 SymTab.ClSet)
|
|
|
+ 1065 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 1066 SymTab.ClSet)) THEN
|
|
|
+ 1067 SemError(230)
|
|
|
+ 1068 ELSIF (t2 #
|
|
|
+ 1069 SymTab.InvalidType)
|
|
|
+ 1070 & (tsel #
|
|
|
+ 1071 SymTab.InvalidType)
|
|
|
+ 1072 & ~SymTab.EqCheck(t2,
|
|
|
+ 1073 tsel) THEN
|
|
|
+ 1074 SemError(213) END;
|
|
|
+ 1075 IF ~QbeGen.IsImm(q2) THEN
|
|
|
+ 1076 SemError(230);
|
|
|
+ 1077 QbeGen.CopyOp("0", q2)
|
|
|
+ 1078 END;
|
|
|
+ 1079 QbeGen.NewLabel(lNext);
|
|
|
+ 1080 QbeGen.Cmp(SymTab.OpEq,
|
|
|
+ 1081 qsel, q2, qc, FALSE);
|
|
|
+ 1082 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
+ 1083 QbeGen.EmitLabel(lNext); .)
|
|
|
+ 1084 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
+ 1085 SymTab.InvalidType)
|
|
|
+ 1086 & (tsel #
|
|
|
+ 1087 SymTab.InvalidType)
|
|
|
+ 1088 & ~SymTab.EqCheck(t3,
|
|
|
+ 1089 tsel) THEN
|
|
|
+ 1090 SemError(213) END;
|
|
|
+ 1091 IF ~QbeGen.IsImm(q3) THEN
|
|
|
+ 1092 SemError(230);
|
|
|
+ 1093 QbeGen.CopyOp("0", q3)
|
|
|
+ 1094 END;
|
|
|
+ 1095 QbeGen.Cmp(SymTab.OpGe,
|
|
|
+ 1096 qsel, q2, qc, FALSE);
|
|
|
+ 1097 QbeGen.Cmp(SymTab.OpLe,
|
|
|
+ 1098 qsel, q3, qd, FALSE);
|
|
|
+ 1099 QbeGen.NewTemp(qe);
|
|
|
+ 1100 QbeGen.Op3("and", qe, qc, qd,
|
|
|
+ 1101 FALSE);
|
|
|
+ 1102 QbeGen.NewLabel(lNext);
|
|
|
+ 1103 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
+ 1104 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
+ 1105 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1106 q, qt: QbeGen.QVal;
|
|
|
+ 1107 res: SymTab.TypeIndex;
|
|
|
+ 1108 hadE, conv: BOOLEAN; .)
|
|
|
+ 1109 = "RETURN" (. hadE := FALSE; .)
|
|
|
+ 1110 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
+ 1111 (. conv := FALSE;
|
|
|
+ 1112 IF ~SymTab.InProc() THEN
|
|
|
+ 1113 SemError(232)
|
|
|
+ 1114 ELSE res := SymTab.CurRes();
|
|
|
+ 1115 IF ~hadE THEN
|
|
|
+ 1116 IF res #
|
|
|
+ 1117 SymTab.InvalidType THEN
|
|
|
+ 1118 SemError(232)
|
|
|
+ 1119 ELSE QbeGen.EmitRet(q,
|
|
|
+ 1120 FALSE)
|
|
|
+ 1121 END
|
|
|
+ 1122 ELSIF (res =
|
|
|
+ 1123 SymTab.InvalidType)
|
|
|
+ 1124 OR (t #
|
|
|
+ 1125 SymTab.InvalidType)
|
|
|
+ 1126 & ~SymTab.Assignable(t,
|
|
|
+ 1127 res) THEN
|
|
|
+ 1128 SemError(232)
|
|
|
+ 1129 ELSE
|
|
|
+ 1130 conv := (SymTab.ClassOf(
|
|
|
+ 1131 res) = SymTab.ClReal)
|
|
|
+ 1132 & SymTab.IsIntFamily(t);
|
|
|
+ 1133 IF conv THEN
|
|
|
+ 1134 QbeGen.ConvIR(q, qt);
|
|
|
+ 1135 QbeGen.EmitRet(qt, TRUE)
|
|
|
+ 1136 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
+ 1137 END
|
|
|
+ 1138 END
|
|
|
+ 1139 END; .) .
|
|
|
+ 1140 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 1141 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 1142 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 1143 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 1144 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 1145 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 1146 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 1147 (. VAR n, fn: SymTab.Name;
|
|
|
+ 1148 cls: INTEGER;
|
|
|
+ 1149 curT, it, eT, bt:
|
|
|
+ 1150 SymTab.TypeIndex;
|
|
|
+ 1151 iq, ql, qlo, qhi, qe:
|
|
|
+ 1152 QbeGen.QVal;
|
|
|
+ 1153 lo, hi: INTEGER;
|
|
|
+ 1154 fo: INTEGER;
|
|
|
+ 1155 isOpen: BOOLEAN;
|
|
|
+ 1156 qb: QbeGen.QVal; .)
|
|
|
+ 1157 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
+ 1158 sfx := FALSE;
|
|
|
+ 1159 IF ~SymTab.Lookup(n) THEN
|
|
|
+ 1160 SemError(201);
|
|
|
+ 1161 t := SymTab.InvalidType;
|
|
|
+ 1162 k := -1;
|
|
|
+ 1163 QbeGen.CopyOp("0", q)
|
|
|
+ 1164 ELSE
|
|
|
+ 1165 t := SymTab.SymType(n);
|
|
|
+ 1166 k := SymTab.SymKind(n);
|
|
|
+ 1167 IF k = SymTab.KindConst THEN
|
|
|
+ 1168 IF SymTab.Equal(n,
|
|
|
+ 1169 "TRUE") THEN
|
|
|
+ 1170 t := SymTab.BoolType();
|
|
|
+ 1171 QbeGen.CopyOp("1", q)
|
|
|
+ 1172 ELSIF SymTab.Equal(n,
|
|
|
+ 1173 "FALSE") THEN
|
|
|
+ 1174 t := SymTab.BoolType();
|
|
|
+ 1175 QbeGen.CopyOp("0", q)
|
|
|
+ 1176 ELSIF SymTab.Equal(n,
|
|
|
+ 1177 "NIL") THEN
|
|
|
+ 1178 QbeGen.CopyOp("0", q)
|
|
|
+ 1179 ELSE
|
|
|
+ 1180 cls :=
|
|
|
+ 1181 SymTab.ClassOf(t);
|
|
|
+ 1182 IF (t #
|
|
|
+ 1183 SymTab.InvalidType)
|
|
|
+ 1184 & ((cls = SymTab.ClInt)
|
|
|
+ 1185 OR (cls
|
|
|
+ 1186 = SymTab.ClChar)
|
|
|
+ 1187 OR (cls
|
|
|
+ 1188 = SymTab.ClReal)
|
|
|
+ 1189 OR (cls
|
|
|
+ 1190 = SymTab.ClNil)) THEN
|
|
|
+ 1191 IF cls = SymTab.ClNil THEN
|
|
|
+ 1192 QbeGen.CopyOp("0", q)
|
|
|
+ 1193 ELSE
|
|
|
+ 1194 QbeGen.LoadVar(n,
|
|
|
+ 1195 cls = SymTab.ClReal,
|
|
|
+ 1196 q)
|
|
|
+ 1197 END
|
|
|
+ 1198 ELSE
|
|
|
+ 1199 IF t #
|
|
|
+ 1200 SymTab.InvalidType THEN
|
|
|
+ 1201 SemError(230)
|
|
|
+ 1202 END;
|
|
|
+ 1203 QbeGen.CopyOp("0", q)
|
|
|
+ 1204 END
|
|
|
+ 1205 END
|
|
|
+ 1206 ELSIF (k = SymTab.KindVar)
|
|
|
+ 1207 OR (k = SymTab.KindParam) THEN
|
|
|
+ 1208 cls :=
|
|
|
+ 1209 SymTab.ClassOf(t);
|
|
|
+ 1210 IF (cls = SymTab.ClInt)
|
|
|
+ 1211 OR (cls = SymTab.ClBool)
|
|
|
+ 1212 OR (cls = SymTab.ClChar)
|
|
|
+ 1213 OR (cls
|
|
|
+ 1214 = SymTab.ClReal) THEN
|
|
|
+ 1215 QbeGen.LoadVar(n,
|
|
|
+ 1216 cls = SymTab.ClReal, q)
|
|
|
+ 1217 ELSIF cls = SymTab.ClPtr THEN
|
|
|
+ 1218 QbeGen.LoadPtr(n, q)
|
|
|
+ 1219 ELSIF (cls
|
|
|
+ 1220 = SymTab.ClArray)
|
|
|
+ 1221 OR (cls
|
|
|
+ 1222 = SymTab.ClSet)
|
|
|
+ 1223 OR (cls
|
|
|
+ 1224 = SymTab.ClRecord)
|
|
|
+ 1225 OR (cls
|
|
|
+ 1226 = SymTab.ClClass) THEN
|
|
|
+ 1227 QbeGen.AddrOf(n, q)
|
|
|
+ 1228 ELSE SemError(230);
|
|
|
+ 1229 QbeGen.CopyOp("0", q)
|
|
|
+ 1230 END
|
|
|
+ 1231 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 1232 IF k = SymTab.KindImport THEN
|
|
|
+ 1233 SemError(230)
|
|
|
+ 1234 ELSIF k =
|
|
|
+ 1235 SymTab.KindProc THEN
|
|
|
+ 1236 (* bare procedure name:
|
|
|
+ 1237 a following ArgList
|
|
|
+ 1238 makes it a call;
|
|
|
+ 1239 otherwise Fact
|
|
|
+ 1240 reports 230 *)
|
|
|
+ 1241 ELSE
|
|
|
+ 1242 IF k = SymTab.KindField THEN
|
|
|
+ 1243 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 1244 fo :=
|
|
|
+ 1245 SymTab.FieldOffset(
|
|
|
+ 1246 SymTab.FieldOwner(n),
|
|
|
+ 1247 n);
|
|
|
+ 1248 QbeGen.FieldAddr(qb,
|
|
|
+ 1249 fo, q);
|
|
|
+ 1250 sfx := TRUE
|
|
|
+ 1251 ELSE SemError(230);
|
|
|
+ 1252 QbeGen.CopyOp("0", q)
|
|
|
+ 1253 END
|
|
|
+ 1254 END
|
|
|
+ 1255 END
|
|
|
+ 1256 END
|
|
|
+ 1257 END; .)
|
|
|
+ 1258 { "[" Expr<it, iq>
|
|
|
+ 1259 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1260 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1261 SymTab.ClArray THEN
|
|
|
+ 1262 SemError(217);
|
|
|
1263 t := SymTab.InvalidType
|
|
|
- 1264 ELSE
|
|
|
- 1265 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1266 isOpen :=
|
|
|
- 1267 SymTab.IsOpenArray(t);
|
|
|
- 1268 IF isOpen THEN
|
|
|
- 1269 QbeGen.CopyOp("0", qlo);
|
|
|
- 1270 QbeGen.OpenHi(q, qhi)
|
|
|
- 1271 ELSE
|
|
|
- 1272 lo := SymTab.ArrayLo(t);
|
|
|
- 1273 hi := SymTab.ArrayHi(t);
|
|
|
- 1274 QbeGen.IntStr(lo, qlo);
|
|
|
- 1275 QbeGen.IntStr(hi, qhi)
|
|
|
- 1276 END;
|
|
|
- 1277 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1278 qhi);
|
|
|
- 1279 eT := SymTab.ArrayElem(t);
|
|
|
- 1280 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1281 t, qe);
|
|
|
- 1282 IF SymTab.ClassOf(eT) =
|
|
|
- 1283 SymTab.ClArray THEN
|
|
|
- 1284 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1285 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1286 END;
|
|
|
- 1287 t := eT; sfx := TRUE
|
|
|
- 1288 END; .)
|
|
|
- 1289 { "," Expr<it, iq>
|
|
|
- 1290 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1291 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1292 SymTab.ClArray THEN
|
|
|
- 1293 SemError(217);
|
|
|
- 1294 t := SymTab.InvalidType
|
|
|
- 1295 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
- 1296 & (SymTab.ClassOf(it) #
|
|
|
- 1297 SymTab.ClChar) THEN
|
|
|
- 1298 SemError(218);
|
|
|
+ 1264 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
+ 1265 & (SymTab.ClassOf(it) #
|
|
|
+ 1266 SymTab.ClChar) THEN
|
|
|
+ 1267 SemError(218);
|
|
|
+ 1268 t := SymTab.InvalidType
|
|
|
+ 1269 ELSE
|
|
|
+ 1270 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1271 isOpen :=
|
|
|
+ 1272 SymTab.IsOpenArray(t);
|
|
|
+ 1273 IF isOpen THEN
|
|
|
+ 1274 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1275 QbeGen.OpenHi(q, qhi)
|
|
|
+ 1276 ELSE
|
|
|
+ 1277 lo := SymTab.ArrayLo(t);
|
|
|
+ 1278 hi := SymTab.ArrayHi(t);
|
|
|
+ 1279 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1280 QbeGen.IntStr(hi, qhi)
|
|
|
+ 1281 END;
|
|
|
+ 1282 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1283 qhi);
|
|
|
+ 1284 eT := SymTab.ArrayElem(t);
|
|
|
+ 1285 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1286 t, qe);
|
|
|
+ 1287 IF SymTab.ClassOf(eT) =
|
|
|
+ 1288 SymTab.ClArray THEN
|
|
|
+ 1289 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1290 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1291 END;
|
|
|
+ 1292 t := eT; sfx := TRUE
|
|
|
+ 1293 END; .)
|
|
|
+ 1294 { "," Expr<it, iq>
|
|
|
+ 1295 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1296 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1297 SymTab.ClArray THEN
|
|
|
+ 1298 SemError(217);
|
|
|
1299 t := SymTab.InvalidType
|
|
|
- 1300 ELSE
|
|
|
- 1301 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1302 isOpen :=
|
|
|
- 1303 SymTab.IsOpenArray(t);
|
|
|
- 1304 IF isOpen THEN
|
|
|
- 1305 QbeGen.CopyOp("0", qlo);
|
|
|
- 1306 QbeGen.OpenHi(q, qhi)
|
|
|
- 1307 ELSE
|
|
|
- 1308 lo := SymTab.ArrayLo(t);
|
|
|
- 1309 hi := SymTab.ArrayHi(t);
|
|
|
- 1310 QbeGen.IntStr(lo, qlo);
|
|
|
- 1311 QbeGen.IntStr(hi, qhi)
|
|
|
- 1312 END;
|
|
|
- 1313 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1314 qhi);
|
|
|
- 1315 eT := SymTab.ArrayElem(t);
|
|
|
- 1316 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1317 t, qe);
|
|
|
- 1318 IF SymTab.ClassOf(eT) =
|
|
|
- 1319 SymTab.ClArray THEN
|
|
|
- 1320 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1321 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1322 END;
|
|
|
- 1323 t := eT; sfx := TRUE
|
|
|
- 1324 END; .) }
|
|
|
- 1325 "]"
|
|
|
- 1326 | "." GetIdent<fn>
|
|
|
- 1327 (. IF k = SymTab.KindModule THEN
|
|
|
- 1328 (* qualified L.x: materialize
|
|
|
- 1329 the export, then load it *)
|
|
|
- 1330 IF ~SymTab.Materialize(n,
|
|
|
- 1331 fn) THEN
|
|
|
- 1332 SemError(201);
|
|
|
- 1333 t := SymTab.InvalidType;
|
|
|
- 1334 QbeGen.CopyOp("0", q)
|
|
|
- 1335 ELSE
|
|
|
- 1336 QbeGen.CopyOp(fn, qn);
|
|
|
- 1337 t := SymTab.SymType(fn);
|
|
|
- 1338 k := SymTab.SymKind(fn);
|
|
|
- 1339 sfx := FALSE;
|
|
|
- 1340 IF k = SymTab.KindProc THEN
|
|
|
- 1341 (* call: ArgList supplies
|
|
|
- 1342 the value *)
|
|
|
- 1343 QbeGen.CopyOp("0", q)
|
|
|
- 1344 ELSIF ~QbeGen.LoadDesignator(
|
|
|
- 1345 fn, t, k, q) THEN
|
|
|
- 1346 SemError(230);
|
|
|
- 1347 QbeGen.CopyOp("0", q)
|
|
|
- 1348 END
|
|
|
- 1349 END
|
|
|
- 1350 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 1351 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 1352 SymTab.ClRecord)
|
|
|
- 1353 & (SymTab.ClassOf(t) #
|
|
|
- 1354 SymTab.ClClass) THEN
|
|
|
- 1355 SemError(215);
|
|
|
- 1356 t := SymTab.InvalidType
|
|
|
- 1357 ELSIF ~SymTab.FieldExists(t,
|
|
|
- 1358 fn) THEN
|
|
|
- 1359 SemError(216);
|
|
|
- 1360 t := SymTab.InvalidType
|
|
|
- 1361 ELSE
|
|
|
- 1362 fo := SymTab.FieldOffset(t,
|
|
|
- 1363 fn);
|
|
|
- 1364 t := SymTab.FieldType(t, fn);
|
|
|
- 1365 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 1366 IF SymTab.ClassOf(t) =
|
|
|
- 1367 SymTab.ClArray THEN
|
|
|
- 1368 QbeGen.ElemLoad(qe, t, q)
|
|
|
- 1369 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1370 END;
|
|
|
- 1371 sfx := TRUE
|
|
|
- 1372 END; .)
|
|
|
- 1373 | "^"
|
|
|
- 1374 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1375 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1376 SymTab.ClPtr THEN
|
|
|
- 1377 SemError(219);
|
|
|
- 1378 t := SymTab.InvalidType
|
|
|
- 1379 ELSE
|
|
|
- 1380 bt := SymTab.PtrBase(t);
|
|
|
- 1381 IF bt = SymTab.InvalidType THEN
|
|
|
- 1382 ELSE
|
|
|
- 1383 IF sfx THEN
|
|
|
- 1384 QbeGen.ElemLoad(q, t,
|
|
|
- 1385 qb);
|
|
|
- 1386 QbeGen.CopyOp(qb, q)
|
|
|
- 1387 END;
|
|
|
- 1388 t := bt;
|
|
|
- 1389 IF (SymTab.ClassOf(bt) =
|
|
|
- 1390 SymTab.ClInt)
|
|
|
- 1391 OR (SymTab.ClassOf(bt) =
|
|
|
- 1392 SymTab.ClBool)
|
|
|
- 1393 OR (SymTab.ClassOf(bt) =
|
|
|
- 1394 SymTab.ClChar)
|
|
|
- 1395 OR (SymTab.ClassOf(bt) =
|
|
|
- 1396 SymTab.ClReal) THEN
|
|
|
- 1397 sfx := TRUE
|
|
|
- 1398 ELSE sfx := FALSE
|
|
|
- 1399 END
|
|
|
- 1400 END
|
|
|
- 1401 END; .) } .
|
|
|
- 1402 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1403 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 1404 op: INTEGER;
|
|
|
- 1405 q2, qt: QbeGen.QVal;
|
|
|
- 1406 isR: BOOLEAN; .)
|
|
|
- 1407 = SimExpr<t, q>
|
|
|
- 1408 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 1409 (. IF op = SymTab.OpIn THEN
|
|
|
- 1410 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 1411 IF (t = SymTab.InvalidType)
|
|
|
- 1412 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1413 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1414 ELSE
|
|
|
- 1415 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 1416 SymTab.SetCount(t2), qt);
|
|
|
- 1417 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1418 END
|
|
|
- 1419 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 1420 QbeGen.CopyOp("0", q)
|
|
|
- 1421 END
|
|
|
- 1422 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 1423 IF (t = SymTab.InvalidType)
|
|
|
- 1424 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1425 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1426 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 1427 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 1428 IF (op # SymTab.OpEq) & (op # SymTab.OpNeq1)
|
|
|
- 1429 & (op # SymTab.OpNeq2) THEN
|
|
|
- 1430 SemError(213); t := SymTab.InvalidType;
|
|
|
- 1431 QbeGen.CopyOp("0", q)
|
|
|
- 1432 ELSE
|
|
|
- 1433 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 1434 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1435 END
|
|
|
- 1436 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1437 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1438 QbeGen.CmpSet(op, q, q2,
|
|
|
- 1439 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 1440 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1441 ELSE
|
|
|
- 1442 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1443 t := SymTab.BoolType();
|
|
|
- 1444 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 1445 QbeGen.CopyOp(qt, q)
|
|
|
- 1446 END
|
|
|
- 1447 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 1448 QbeGen.CopyOp("0", q)
|
|
|
- 1449 END; .) ] .
|
|
|
- 1450 Rel<VAR op: INTEGER>
|
|
|
- 1451 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 1452 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 1453 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 1454 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 1455 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 1456 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 1457 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 1458 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1459 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
- 1460 op: INTEGER;
|
|
|
- 1461 q2, qt: QbeGen.QVal;
|
|
|
- 1462 neg, isR: BOOLEAN;
|
|
|
- 1463 lw, rw, mw: CARDINAL; .)
|
|
|
- 1464 = (. neg := FALSE; .)
|
|
|
- 1465 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
- 1466 Term<t, q> (. IF neg THEN
|
|
|
- 1467 IF QbeGen.IsImm(q) THEN
|
|
|
- 1468 QbeGen.NegFold(q, q)
|
|
|
- 1469 ELSE QbeGen.NewTemp(qt);
|
|
|
- 1470 QbeGen.NegQ(q, qt,
|
|
|
- 1471 SymTab.ClassOf(t)
|
|
|
- 1472 = SymTab.ClReal);
|
|
|
- 1473 QbeGen.CopyOp(qt, q)
|
|
|
- 1474 END
|
|
|
- 1475 END; .)
|
|
|
- 1476 { AddOp<op> Term<t2, q2>
|
|
|
- 1477 (. IF op = SymTab.OpOr THEN
|
|
|
- 1478 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
- 1479 t := SymTab.BoolType()
|
|
|
- 1480 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1481 IF t # SymTab.InvalidType THEN
|
|
|
- 1482 QbeGen.NewTemp(qt);
|
|
|
- 1483 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
- 1484 QbeGen.CopyOp(qt, q)
|
|
|
- 1485 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1486 END
|
|
|
- 1487 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
- 1488 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1489 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1490 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1491 mw := lw;
|
|
|
- 1492 IF rw > mw THEN mw := rw END;
|
|
|
- 1493 IF op = SymTab.OpAdd THEN
|
|
|
- 1494 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 1495 ELSE
|
|
|
- 1496 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 1497 END;
|
|
|
- 1498 t := SymTab.NewSet(
|
|
|
- 1499 SymTab.NewSubR(0,
|
|
|
- 1500 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1501 QbeGen.CopyOp(qt, q)
|
|
|
- 1502 ELSE
|
|
|
- 1503 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 1504 t := res2
|
|
|
- 1505 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1506 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1507 IF t # SymTab.InvalidType THEN
|
|
|
- 1508 QbeGen.NewTemp(qt);
|
|
|
- 1509 IF op = SymTab.OpAdd THEN
|
|
|
- 1510 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 1511 ELSE
|
|
|
- 1512 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 1513 END;
|
|
|
- 1514 QbeGen.CopyOp(qt, q)
|
|
|
- 1515 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1516 END
|
|
|
- 1517 END; .) } .
|
|
|
- 1518 AddOp<VAR op: INTEGER>
|
|
|
- 1519 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 1520 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 1521 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 1522 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1523 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
- 1524 op: INTEGER;
|
|
|
- 1525 q2, qt: QbeGen.QVal;
|
|
|
- 1526 isR: BOOLEAN;
|
|
|
- 1527 lw, rw, mw: CARDINAL; .)
|
|
|
- 1528 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
- 1529 (. IF op = SymTab.OpAnd THEN
|
|
|
- 1530 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
- 1531 t := SymTab.BoolType()
|
|
|
- 1532 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1533 IF t # SymTab.InvalidType THEN
|
|
|
- 1534 QbeGen.NewTemp(qt);
|
|
|
- 1535 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
- 1536 QbeGen.CopyOp(qt, q)
|
|
|
- 1537 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1538 END
|
|
|
- 1539 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
- 1540 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1541 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1542 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1543 mw := lw;
|
|
|
- 1544 IF rw > mw THEN mw := rw END;
|
|
|
- 1545 IF op = SymTab.OpTimes THEN
|
|
|
- 1546 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 1547 ELSE
|
|
|
- 1548 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 1549 END;
|
|
|
- 1550 t := SymTab.NewSet(
|
|
|
- 1551 SymTab.NewSubR(0,
|
|
|
- 1552 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1553 QbeGen.CopyOp(qt, q)
|
|
|
- 1554 ELSE
|
|
|
- 1555 IF SymTab.ArithCheck(t, t2,
|
|
|
- 1556 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 1557 res2) THEN t := res2
|
|
|
- 1558 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1559 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1560 IF t # SymTab.InvalidType THEN
|
|
|
- 1561 QbeGen.NewTemp(qt);
|
|
|
- 1562 IF op = SymTab.OpTimes THEN
|
|
|
- 1563 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 1564 ELSIF (op = SymTab.OpDiv)
|
|
|
- 1565 OR (op = SymTab.OpSlash) THEN
|
|
|
- 1566 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 1567 ELSE
|
|
|
- 1568 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 1569 END;
|
|
|
- 1570 QbeGen.CopyOp(qt, q)
|
|
|
- 1571 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1572 END
|
|
|
- 1573 END; .) } .
|
|
|
- 1574 MulOp<VAR op: INTEGER>
|
|
|
- 1575 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 1576 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 1577 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 1578 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 1579 | "AND" (. op := SymTab.OpAnd; .) .
|
|
|
- 1580 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1581 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 1582 et, dt, t2, st, ct2:
|
|
|
- 1583 SymTab.TypeIndex;
|
|
|
- 1584 dk: INTEGER;
|
|
|
- 1585 qd, q2, sq, qa, qm0:
|
|
|
- 1586 QbeGen.QVal;
|
|
|
- 1587 qn: SymTab.Name;
|
|
|
- 1588 called, sfx: BOOLEAN; .)
|
|
|
- 1589 = integer (. LexString(s);
|
|
|
- 1590 QbeGen.NormInt(s, q);
|
|
|
- 1591 t := SymTab.IntType(); .)
|
|
|
- 1592 | real (. LexString(s);
|
|
|
- 1593 QbeGen.NormReal(s, q);
|
|
|
- 1594 t := SymTab.RealType(); .)
|
|
|
- 1595 | string (. LexString(s);
|
|
|
- 1596 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 1597 t := SymTab.CharType();
|
|
|
- 1598 QbeGen.IntStr(
|
|
|
- 1599 QbeGen.CharVal(s), q)
|
|
|
- 1600 ELSE t := SymTab.NewStr();
|
|
|
- 1601 QbeGen.DeclStr(s, q)
|
|
|
- 1602 END; .)
|
|
|
- 1603 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
- 1604 t := dt;
|
|
|
- 1605 IF sfx THEN
|
|
|
- 1606 IF dt =
|
|
|
- 1607 SymTab.InvalidType THEN
|
|
|
- 1608 QbeGen.CopyOp("0", q)
|
|
|
- 1609 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1610 SymTab.ClRecord)
|
|
|
- 1611 OR (SymTab.ClassOf(dt) =
|
|
|
- 1612 SymTab.ClSet)
|
|
|
- 1613 OR (SymTab.ClassOf(dt) =
|
|
|
- 1614 SymTab.ClClass) THEN
|
|
|
- 1615 QbeGen.CopyOp(qd, q)
|
|
|
- 1616 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 1617 q)
|
|
|
- 1618 END
|
|
|
- 1619 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 1620 END;
|
|
|
- 1621 IF (dk = SymTab.KindVar)
|
|
|
- 1622 OR (dk = SymTab.KindParam)
|
|
|
- 1623 OR (dk =
|
|
|
- 1624 SymTab.KindField) THEN
|
|
|
- 1625 IF sfx THEN
|
|
|
- 1626 QbeGen.NoteAddr(q, qd)
|
|
|
- 1627 ELSE
|
|
|
- 1628 QbeGen.AddrOf(qn, qa);
|
|
|
- 1629 QbeGen.NoteAddr(q, qa)
|
|
|
- 1630 END
|
|
|
- 1631 ELSIF sfx
|
|
|
- 1632 & (dt #
|
|
|
- 1633 SymTab.InvalidType)
|
|
|
- 1634 & ((SymTab.ClassOf(dt) =
|
|
|
- 1635 SymTab.ClArray)
|
|
|
- 1636 OR (SymTab.ClassOf(dt) =
|
|
|
- 1637 SymTab.ClSet)
|
|
|
- 1638 OR (SymTab.ClassOf(dt) =
|
|
|
- 1639 SymTab.ClRecord)) THEN
|
|
|
- 1640 QbeGen.NoteAddr(qd, qd)
|
|
|
- 1641 END; .)
|
|
|
- 1642 [ ArgList<qn, TRUE, ct2, q2, called>
|
|
|
- 1643 (. t := ct2;
|
|
|
- 1644 QbeGen.CopyOp(q2, q); .) ]
|
|
|
- 1645 (. IF ~called
|
|
|
- 1646 & (dk = SymTab.KindProc) THEN
|
|
|
- 1647 (* bare zero-arg function
|
|
|
- 1648 call (parentheses may be
|
|
|
- 1649 omitted); a proper or
|
|
|
- 1650 parameterised proc here
|
|
|
- 1651 is 230 *)
|
|
|
- 1652 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 1653 & (SymTab.ProcRes(qn) #
|
|
|
- 1654 SymTab.InvalidType) THEN
|
|
|
- 1655 QbeGen.Mangled(qn,
|
|
|
- 1656 SymTab.ProcUid(qn), qm0);
|
|
|
- 1657 QbeGen.CallBegin(qm0,
|
|
|
- 1658 SymTab.ProcRes(qn),
|
|
|
- 1659 SymTab.ProcDepthOf(qn));
|
|
|
- 1660 QbeGen.CallEnd(TRUE, q);
|
|
|
- 1661 t := SymTab.ProcRes(qn)
|
|
|
- 1662 ELSE SemError(230)
|
|
|
- 1663 END
|
|
|
- 1664 END; .)
|
|
|
- 1665 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
- 1666 | SetLit<st, sq> (. t := st;
|
|
|
- 1667 QbeGen.CopyOp(sq, q); .)
|
|
|
- 1668 | "NOT" Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
- 1669 t := SymTab.BoolType()
|
|
|
- 1670 ELSE SemError(212);
|
|
|
- 1671 t := SymTab.InvalidType END;
|
|
|
- 1672 IF t # SymTab.InvalidType THEN
|
|
|
- 1673 QbeGen.NotQ(q2, q)
|
|
|
- 1674 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1675 END; .) .
|
|
|
- 1676 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 1677 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 1678 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 1679 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1680 = "{" (. t := SymTab.NewSet(
|
|
|
- 1681 SymTab.NewSubR(0, 255));
|
|
|
- 1682 QbeGen.NewSetTemp(8, q);
|
|
|
- 1683 QbeGen.SetZero(q, 8); .)
|
|
|
- 1684 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
- 1685 "}" .
|
|
|
- 1686 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 1687 qe, q2: QbeGen.QVal;
|
|
|
- 1688 v, v2: INTEGER;
|
|
|
- 1689 lo: INTEGER;
|
|
|
- 1690 span: CARDINAL;
|
|
|
- 1691 cl, cl2: INTEGER;
|
|
|
- 1692 hasR: BOOLEAN; .)
|
|
|
- 1693 = (. hasR := FALSE; .)
|
|
|
- 1694 Expr<et, qe>
|
|
|
- 1695 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
- 1696 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 1697 span := SymTab.SetCount(st);
|
|
|
- 1698 IF (et = SymTab.InvalidType)
|
|
|
- 1699 OR (hasR & (et2 =
|
|
|
- 1700 SymTab.InvalidType)) THEN
|
|
|
- 1701 ELSE cl :=
|
|
|
- 1702 SymTab.ClassOf(et);
|
|
|
- 1703 IF hasR THEN
|
|
|
- 1704 cl2 :=
|
|
|
- 1705 SymTab.ClassOf(et2)
|
|
|
- 1706 ELSE cl2 := SymTab.ClInt
|
|
|
- 1707 END;
|
|
|
- 1708 IF ((cl # SymTab.ClInt)
|
|
|
- 1709 & (cl # SymTab.ClChar)
|
|
|
- 1710 & (cl # SymTab.ClBool))
|
|
|
- 1711 OR (hasR &
|
|
|
- 1712 ((cl2
|
|
|
- 1713 # SymTab.ClInt)
|
|
|
- 1714 & (cl2
|
|
|
- 1715 # SymTab.ClChar)
|
|
|
- 1716 & (cl2
|
|
|
- 1717 # SymTab.ClBool))) THEN
|
|
|
- 1718 SemError(222)
|
|
|
- 1719 ELSIF hasR
|
|
|
- 1720 & SymTab.ConstInt(qe, v)
|
|
|
- 1721 & SymTab.ConstInt(q2,
|
|
|
- 1722 v2)
|
|
|
- 1723 & ((v < lo)
|
|
|
- 1724 OR (v2 < lo)
|
|
|
- 1725 OR (v >= lo +
|
|
|
- 1726 VAL(INTEGER, span))
|
|
|
- 1727 OR (v2 >= lo +
|
|
|
- 1728 VAL(INTEGER, span))
|
|
|
- 1729 OR (v > v2)) THEN
|
|
|
- 1730 SemError(222)
|
|
|
- 1731 ELSIF hasR THEN
|
|
|
- 1732 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 1733 lo, span)
|
|
|
- 1734 ELSIF SymTab.ConstInt(qe,
|
|
|
- 1735 v)
|
|
|
- 1736 & ((v < lo)
|
|
|
- 1737 OR (v >= lo +
|
|
|
- 1738 VAL(INTEGER,
|
|
|
- 1739 span))) THEN
|
|
|
- 1740 SemError(222)
|
|
|
- 1741 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 1742 lo, span)
|
|
|
- 1743 END
|
|
|
- 1744 END; .) .
|
|
|
- 1745 GetIdent<VAR n: SymTab.Name>
|
|
|
- 1746 = ident (. LexName(n); .) .
|
|
|
- 1747
|
|
|
- 1748 END M2.
|
|
|
+ 1300 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
+ 1301 & (SymTab.ClassOf(it) #
|
|
|
+ 1302 SymTab.ClChar) THEN
|
|
|
+ 1303 SemError(218);
|
|
|
+ 1304 t := SymTab.InvalidType
|
|
|
+ 1305 ELSE
|
|
|
+ 1306 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1307 isOpen :=
|
|
|
+ 1308 SymTab.IsOpenArray(t);
|
|
|
+ 1309 IF isOpen THEN
|
|
|
+ 1310 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1311 QbeGen.OpenHi(q, qhi)
|
|
|
+ 1312 ELSE
|
|
|
+ 1313 lo := SymTab.ArrayLo(t);
|
|
|
+ 1314 hi := SymTab.ArrayHi(t);
|
|
|
+ 1315 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1316 QbeGen.IntStr(hi, qhi)
|
|
|
+ 1317 END;
|
|
|
+ 1318 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1319 qhi);
|
|
|
+ 1320 eT := SymTab.ArrayElem(t);
|
|
|
+ 1321 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1322 t, qe);
|
|
|
+ 1323 IF SymTab.ClassOf(eT) =
|
|
|
+ 1324 SymTab.ClArray THEN
|
|
|
+ 1325 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1326 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1327 END;
|
|
|
+ 1328 t := eT; sfx := TRUE
|
|
|
+ 1329 END; .) }
|
|
|
+ 1330 "]"
|
|
|
+ 1331 | "." GetIdent<fn>
|
|
|
+ 1332 (. IF k = SymTab.KindModule THEN
|
|
|
+ 1333 (* qualified L.x: materialize
|
|
|
+ 1334 the export, then load it *)
|
|
|
+ 1335 IF ~SymTab.Materialize(n,
|
|
|
+ 1336 fn) THEN
|
|
|
+ 1337 SemError(201);
|
|
|
+ 1338 t := SymTab.InvalidType;
|
|
|
+ 1339 QbeGen.CopyOp("0", q)
|
|
|
+ 1340 ELSE
|
|
|
+ 1341 QbeGen.CopyOp(fn, qn);
|
|
|
+ 1342 t := SymTab.SymType(fn);
|
|
|
+ 1343 k := SymTab.SymKind(fn);
|
|
|
+ 1344 sfx := FALSE;
|
|
|
+ 1345 IF k = SymTab.KindProc THEN
|
|
|
+ 1346 (* call: ArgList supplies
|
|
|
+ 1347 the value *)
|
|
|
+ 1348 QbeGen.CopyOp("0", q)
|
|
|
+ 1349 ELSIF ~QbeGen.LoadDesignator(
|
|
|
+ 1350 fn, t, k, q) THEN
|
|
|
+ 1351 SemError(230);
|
|
|
+ 1352 QbeGen.CopyOp("0", q)
|
|
|
+ 1353 END
|
|
|
+ 1354 END
|
|
|
+ 1355 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 1356 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 1357 SymTab.ClRecord)
|
|
|
+ 1358 & (SymTab.ClassOf(t) #
|
|
|
+ 1359 SymTab.ClClass) THEN
|
|
|
+ 1360 SemError(215);
|
|
|
+ 1361 t := SymTab.InvalidType
|
|
|
+ 1362 ELSIF ~SymTab.FieldExists(t,
|
|
|
+ 1363 fn) THEN
|
|
|
+ 1364 SemError(216);
|
|
|
+ 1365 t := SymTab.InvalidType
|
|
|
+ 1366 ELSE
|
|
|
+ 1367 fo := SymTab.FieldOffset(t,
|
|
|
+ 1368 fn);
|
|
|
+ 1369 t := SymTab.FieldType(t, fn);
|
|
|
+ 1370 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 1371 IF SymTab.ClassOf(t) =
|
|
|
+ 1372 SymTab.ClArray THEN
|
|
|
+ 1373 QbeGen.ElemLoad(qe, t, q)
|
|
|
+ 1374 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1375 END;
|
|
|
+ 1376 sfx := TRUE
|
|
|
+ 1377 END; .)
|
|
|
+ 1378 | "^"
|
|
|
+ 1379 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1380 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1381 SymTab.ClPtr THEN
|
|
|
+ 1382 SemError(219);
|
|
|
+ 1383 t := SymTab.InvalidType
|
|
|
+ 1384 ELSE
|
|
|
+ 1385 bt := SymTab.PtrBase(t);
|
|
|
+ 1386 IF bt = SymTab.InvalidType THEN
|
|
|
+ 1387 ELSE
|
|
|
+ 1388 IF sfx THEN
|
|
|
+ 1389 QbeGen.ElemLoad(q, t,
|
|
|
+ 1390 qb);
|
|
|
+ 1391 QbeGen.CopyOp(qb, q)
|
|
|
+ 1392 END;
|
|
|
+ 1393 t := bt;
|
|
|
+ 1394 IF (SymTab.ClassOf(bt) =
|
|
|
+ 1395 SymTab.ClInt)
|
|
|
+ 1396 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1397 SymTab.ClBool)
|
|
|
+ 1398 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1399 SymTab.ClChar)
|
|
|
+ 1400 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1401 SymTab.ClReal) THEN
|
|
|
+ 1402 sfx := TRUE
|
|
|
+ 1403 ELSE sfx := FALSE
|
|
|
+ 1404 END
|
|
|
+ 1405 END
|
|
|
+ 1406 END; .) } .
|
|
|
+ 1407 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1408 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 1409 op: INTEGER;
|
|
|
+ 1410 q2, qt: QbeGen.QVal;
|
|
|
+ 1411 isR: BOOLEAN; .)
|
|
|
+ 1412 = SimExpr<t, q>
|
|
|
+ 1413 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 1414 (. IF op = SymTab.OpIn THEN
|
|
|
+ 1415 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 1416 IF (t = SymTab.InvalidType)
|
|
|
+ 1417 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1418 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1419 ELSE
|
|
|
+ 1420 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 1421 SymTab.SetCount(t2), qt);
|
|
|
+ 1422 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1423 END
|
|
|
+ 1424 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 1425 QbeGen.CopyOp("0", q)
|
|
|
+ 1426 END
|
|
|
+ 1427 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 1428 IF (t = SymTab.InvalidType)
|
|
|
+ 1429 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1430 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1431 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 1432 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 1433 IF (op # SymTab.OpEq) & (op # SymTab.OpNeq1)
|
|
|
+ 1434 & (op # SymTab.OpNeq2) THEN
|
|
|
+ 1435 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1436 QbeGen.CopyOp("0", q)
|
|
|
+ 1437 ELSE
|
|
|
+ 1438 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 1439 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1440 END
|
|
|
+ 1441 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1442 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1443 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 1444 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 1445 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1446 ELSE
|
|
|
+ 1447 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1448 t := SymTab.BoolType();
|
|
|
+ 1449 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 1450 QbeGen.CopyOp(qt, q)
|
|
|
+ 1451 END
|
|
|
+ 1452 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1453 QbeGen.CopyOp("0", q)
|
|
|
+ 1454 END; .) ] .
|
|
|
+ 1455 Rel<VAR op: INTEGER>
|
|
|
+ 1456 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 1457 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 1458 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 1459 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 1460 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 1461 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 1462 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 1463 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1464 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
+ 1465 op: INTEGER;
|
|
|
+ 1466 q2, qt: QbeGen.QVal;
|
|
|
+ 1467 neg, isR: BOOLEAN;
|
|
|
+ 1468 lw, rw, mw: CARDINAL; .)
|
|
|
+ 1469 = (. neg := FALSE; .)
|
|
|
+ 1470 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
+ 1471 Term<t, q> (. IF neg THEN
|
|
|
+ 1472 IF QbeGen.IsImm(q) THEN
|
|
|
+ 1473 QbeGen.NegFold(q, q)
|
|
|
+ 1474 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 1475 QbeGen.NegQ(q, qt,
|
|
|
+ 1476 SymTab.ClassOf(t)
|
|
|
+ 1477 = SymTab.ClReal);
|
|
|
+ 1478 QbeGen.CopyOp(qt, q)
|
|
|
+ 1479 END
|
|
|
+ 1480 END; .)
|
|
|
+ 1481 { AddOp<op> Term<t2, q2>
|
|
|
+ 1482 (. IF op = SymTab.OpOr THEN
|
|
|
+ 1483 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
+ 1484 t := SymTab.BoolType()
|
|
|
+ 1485 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1486 IF t # SymTab.InvalidType THEN
|
|
|
+ 1487 QbeGen.NewTemp(qt);
|
|
|
+ 1488 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
+ 1489 QbeGen.CopyOp(qt, q)
|
|
|
+ 1490 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1491 END
|
|
|
+ 1492 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
+ 1493 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1494 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1495 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1496 mw := lw;
|
|
|
+ 1497 IF rw > mw THEN mw := rw END;
|
|
|
+ 1498 IF op = SymTab.OpAdd THEN
|
|
|
+ 1499 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 1500 ELSE
|
|
|
+ 1501 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 1502 END;
|
|
|
+ 1503 t := SymTab.NewSet(
|
|
|
+ 1504 SymTab.NewSubR(0,
|
|
|
+ 1505 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1506 QbeGen.CopyOp(qt, q)
|
|
|
+ 1507 ELSE
|
|
|
+ 1508 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 1509 t := res2
|
|
|
+ 1510 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1511 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1512 IF t # SymTab.InvalidType THEN
|
|
|
+ 1513 QbeGen.NewTemp(qt);
|
|
|
+ 1514 IF op = SymTab.OpAdd THEN
|
|
|
+ 1515 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 1516 ELSE
|
|
|
+ 1517 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 1518 END;
|
|
|
+ 1519 QbeGen.CopyOp(qt, q)
|
|
|
+ 1520 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1521 END
|
|
|
+ 1522 END; .) } .
|
|
|
+ 1523 AddOp<VAR op: INTEGER>
|
|
|
+ 1524 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 1525 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 1526 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 1527 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1528 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
+ 1529 op: INTEGER;
|
|
|
+ 1530 q2, qt: QbeGen.QVal;
|
|
|
+ 1531 isR: BOOLEAN;
|
|
|
+ 1532 lw, rw, mw: CARDINAL; .)
|
|
|
+ 1533 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
+ 1534 (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1535 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
+ 1536 t := SymTab.BoolType()
|
|
|
+ 1537 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1538 IF t # SymTab.InvalidType THEN
|
|
|
+ 1539 QbeGen.NewTemp(qt);
|
|
|
+ 1540 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
+ 1541 QbeGen.CopyOp(qt, q)
|
|
|
+ 1542 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1543 END
|
|
|
+ 1544 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
+ 1545 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1546 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1547 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1548 mw := lw;
|
|
|
+ 1549 IF rw > mw THEN mw := rw END;
|
|
|
+ 1550 IF op = SymTab.OpTimes THEN
|
|
|
+ 1551 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 1552 ELSE
|
|
|
+ 1553 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 1554 END;
|
|
|
+ 1555 t := SymTab.NewSet(
|
|
|
+ 1556 SymTab.NewSubR(0,
|
|
|
+ 1557 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1558 QbeGen.CopyOp(qt, q)
|
|
|
+ 1559 ELSE
|
|
|
+ 1560 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 1561 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 1562 res2) THEN t := res2
|
|
|
+ 1563 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1564 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1565 IF t # SymTab.InvalidType THEN
|
|
|
+ 1566 QbeGen.NewTemp(qt);
|
|
|
+ 1567 IF op = SymTab.OpTimes THEN
|
|
|
+ 1568 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 1569 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 1570 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 1571 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 1572 ELSE
|
|
|
+ 1573 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 1574 END;
|
|
|
+ 1575 QbeGen.CopyOp(qt, q)
|
|
|
+ 1576 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1577 END
|
|
|
+ 1578 END; .) } .
|
|
|
+ 1579 MulOp<VAR op: INTEGER>
|
|
|
+ 1580 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 1581 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 1582 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 1583 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 1584 | "AND" (. op := SymTab.OpAnd; .) .
|
|
|
+ 1585 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1586 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 1587 et, dt, t2, st, ct2:
|
|
|
+ 1588 SymTab.TypeIndex;
|
|
|
+ 1589 dk: INTEGER;
|
|
|
+ 1590 qd, q2, sq, qa, qm0:
|
|
|
+ 1591 QbeGen.QVal;
|
|
|
+ 1592 qn: SymTab.Name;
|
|
|
+ 1593 called, sfx: BOOLEAN; .)
|
|
|
+ 1594 = integer (. LexString(s);
|
|
|
+ 1595 QbeGen.NormInt(s, q);
|
|
|
+ 1596 t := SymTab.IntType(); .)
|
|
|
+ 1597 | real (. LexString(s);
|
|
|
+ 1598 QbeGen.NormReal(s, q);
|
|
|
+ 1599 t := SymTab.RealType(); .)
|
|
|
+ 1600 | string (. LexString(s);
|
|
|
+ 1601 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 1602 t := SymTab.CharType();
|
|
|
+ 1603 QbeGen.IntStr(
|
|
|
+ 1604 QbeGen.CharVal(s), q)
|
|
|
+ 1605 ELSE t := SymTab.NewStr();
|
|
|
+ 1606 QbeGen.DeclStr(s, q);
|
|
|
+ 1607 (* a literal's value IS its
|
|
|
+ 1608 static descriptor address *)
|
|
|
+ 1609 QbeGen.NoteAddr(q, q)
|
|
|
+ 1610 END; .)
|
|
|
+ 1611 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
+ 1612 t := dt;
|
|
|
+ 1613 IF sfx THEN
|
|
|
+ 1614 IF dt =
|
|
|
+ 1615 SymTab.InvalidType THEN
|
|
|
+ 1616 QbeGen.CopyOp("0", q)
|
|
|
+ 1617 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1618 SymTab.ClRecord)
|
|
|
+ 1619 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1620 SymTab.ClSet)
|
|
|
+ 1621 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1622 SymTab.ClClass) THEN
|
|
|
+ 1623 QbeGen.CopyOp(qd, q)
|
|
|
+ 1624 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 1625 q)
|
|
|
+ 1626 END
|
|
|
+ 1627 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 1628 END;
|
|
|
+ 1629 IF (dk = SymTab.KindVar)
|
|
|
+ 1630 OR (dk = SymTab.KindParam)
|
|
|
+ 1631 OR (dk =
|
|
|
+ 1632 SymTab.KindField) THEN
|
|
|
+ 1633 IF sfx THEN
|
|
|
+ 1634 QbeGen.NoteAddr(q, qd)
|
|
|
+ 1635 ELSE
|
|
|
+ 1636 QbeGen.AddrOf(qn, qa);
|
|
|
+ 1637 QbeGen.NoteAddr(q, qa)
|
|
|
+ 1638 END
|
|
|
+ 1639 ELSIF sfx
|
|
|
+ 1640 & (dt #
|
|
|
+ 1641 SymTab.InvalidType)
|
|
|
+ 1642 & ((SymTab.ClassOf(dt) =
|
|
|
+ 1643 SymTab.ClArray)
|
|
|
+ 1644 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1645 SymTab.ClSet)
|
|
|
+ 1646 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1647 SymTab.ClRecord)) THEN
|
|
|
+ 1648 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 1649 END; .)
|
|
|
+ 1650 [ ArgList<qn, TRUE, ct2, q2, called>
|
|
|
+ 1651 (. t := ct2;
|
|
|
+ 1652 QbeGen.CopyOp(q2, q); .) ]
|
|
|
+ 1653 (. IF ~called
|
|
|
+ 1654 & (dk = SymTab.KindProc) THEN
|
|
|
+ 1655 (* bare zero-arg function
|
|
|
+ 1656 call (parentheses may be
|
|
|
+ 1657 omitted); a proper or
|
|
|
+ 1658 parameterised proc here
|
|
|
+ 1659 is 230 *)
|
|
|
+ 1660 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 1661 & (SymTab.ProcRes(qn) #
|
|
|
+ 1662 SymTab.InvalidType) THEN
|
|
|
+ 1663 QbeGen.Mangled(qn,
|
|
|
+ 1664 SymTab.ProcUid(qn), qm0);
|
|
|
+ 1665 QbeGen.CallBegin(qm0,
|
|
|
+ 1666 SymTab.ProcRes(qn),
|
|
|
+ 1667 SymTab.ProcDepthOf(qn),
|
|
|
+ 1668 SymTab.IsExternal(qn));
|
|
|
+ 1669 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 1670 t := SymTab.ProcRes(qn)
|
|
|
+ 1671 ELSE SemError(230)
|
|
|
+ 1672 END
|
|
|
+ 1673 END; .)
|
|
|
+ 1674 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
+ 1675 | SetLit<st, sq> (. t := st;
|
|
|
+ 1676 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 1677 | "NOT" Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 1678 t := SymTab.BoolType()
|
|
|
+ 1679 ELSE SemError(212);
|
|
|
+ 1680 t := SymTab.InvalidType END;
|
|
|
+ 1681 IF t # SymTab.InvalidType THEN
|
|
|
+ 1682 QbeGen.NotQ(q2, q)
|
|
|
+ 1683 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1684 END; .) .
|
|
|
+ 1685 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 1686 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 1687 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 1688 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1689 = "{" (. t := SymTab.NewSet(
|
|
|
+ 1690 SymTab.NewSubR(0, 255));
|
|
|
+ 1691 QbeGen.NewSetTemp(8, q);
|
|
|
+ 1692 QbeGen.SetZero(q, 8); .)
|
|
|
+ 1693 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
+ 1694 "}" .
|
|
|
+ 1695 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 1696 qe, q2: QbeGen.QVal;
|
|
|
+ 1697 v, v2: INTEGER;
|
|
|
+ 1698 lo: INTEGER;
|
|
|
+ 1699 span: CARDINAL;
|
|
|
+ 1700 cl, cl2: INTEGER;
|
|
|
+ 1701 hasR: BOOLEAN; .)
|
|
|
+ 1702 = (. hasR := FALSE; .)
|
|
|
+ 1703 Expr<et, qe>
|
|
|
+ 1704 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
+ 1705 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 1706 span := SymTab.SetCount(st);
|
|
|
+ 1707 IF (et = SymTab.InvalidType)
|
|
|
+ 1708 OR (hasR & (et2 =
|
|
|
+ 1709 SymTab.InvalidType)) THEN
|
|
|
+ 1710 ELSE cl :=
|
|
|
+ 1711 SymTab.ClassOf(et);
|
|
|
+ 1712 IF hasR THEN
|
|
|
+ 1713 cl2 :=
|
|
|
+ 1714 SymTab.ClassOf(et2)
|
|
|
+ 1715 ELSE cl2 := SymTab.ClInt
|
|
|
+ 1716 END;
|
|
|
+ 1717 IF ((cl # SymTab.ClInt)
|
|
|
+ 1718 & (cl # SymTab.ClChar)
|
|
|
+ 1719 & (cl # SymTab.ClBool))
|
|
|
+ 1720 OR (hasR &
|
|
|
+ 1721 ((cl2
|
|
|
+ 1722 # SymTab.ClInt)
|
|
|
+ 1723 & (cl2
|
|
|
+ 1724 # SymTab.ClChar)
|
|
|
+ 1725 & (cl2
|
|
|
+ 1726 # SymTab.ClBool))) THEN
|
|
|
+ 1727 SemError(222)
|
|
|
+ 1728 ELSIF hasR
|
|
|
+ 1729 & SymTab.ConstInt(qe, v)
|
|
|
+ 1730 & SymTab.ConstInt(q2,
|
|
|
+ 1731 v2)
|
|
|
+ 1732 & ((v < lo)
|
|
|
+ 1733 OR (v2 < lo)
|
|
|
+ 1734 OR (v >= lo +
|
|
|
+ 1735 VAL(INTEGER, span))
|
|
|
+ 1736 OR (v2 >= lo +
|
|
|
+ 1737 VAL(INTEGER, span))
|
|
|
+ 1738 OR (v > v2)) THEN
|
|
|
+ 1739 SemError(222)
|
|
|
+ 1740 ELSIF hasR THEN
|
|
|
+ 1741 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 1742 lo, span)
|
|
|
+ 1743 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 1744 v)
|
|
|
+ 1745 & ((v < lo)
|
|
|
+ 1746 OR (v >= lo +
|
|
|
+ 1747 VAL(INTEGER,
|
|
|
+ 1748 span))) THEN
|
|
|
+ 1749 SemError(222)
|
|
|
+ 1750 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 1751 lo, span)
|
|
|
+ 1752 END
|
|
|
+ 1753 END; .) .
|
|
|
+ 1754 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 1755 = ident (. LexName(n); .) .
|
|
|
+ 1756
|
|
|
+ 1757 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|
|
|
|
|
|
Statistics:
|
|
|
|
|
|
- nr of terminals: 75 (limit 400)
|
|
|
+ nr of terminals: 76 (limit 400)
|
|
|
nr of non-terminals: 73 (limit 210)
|
|
|
- nr of pragmas: 0 (limit 425)
|
|
|
- nr of symbolnodes: 148 (limit 500)
|
|
|
- nr of graphnodes: 667 (limit 1500)
|
|
|
+ nr of pragmas: 0 (limit 424)
|
|
|
+ nr of symbolnodes: 149 (limit 500)
|
|
|
+ nr of graphnodes: 670 (limit 1500)
|
|
|
nr of conditionsets: 7 (limit 100)
|
|
|
nr of charactersets: 11 (limit 250)
|
|
|
|