|
|
@@ -671,2155 +671,2165 @@ Listing:
|
|
|
653 "="
|
|
|
654 Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
655 cls := SymTab.ClassOf(t);
|
|
|
- 656 IF cls = SymTab.ClArray THEN
|
|
|
- 657 (* an array constructor: qv is
|
|
|
- 658 its pooled descriptor
|
|
|
- 659 address; no scalar data *)
|
|
|
- 660 SymTab.SetSymVal(n, qv)
|
|
|
- 661 ELSIF cls = SymTab.ClStr THEN
|
|
|
- 662 SemError(230)
|
|
|
- 663 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
- 664 SemError(230)
|
|
|
- 665 ELSE
|
|
|
- 666 SymTab.SetSymVal(n, qv);
|
|
|
- 667 QbeGen.DeclConst(n, qv, t)
|
|
|
- 668 END; .) .
|
|
|
- 669 VarBlock
|
|
|
- 670 = "VAR" { VarDecl ";" } .
|
|
|
- 671 VarDecl (. VAR nm: SymTab.Name;
|
|
|
- 672 t: SymTab.TypeIndex;
|
|
|
- 673 i: CARDINAL;
|
|
|
- 674 cls: INTEGER; .)
|
|
|
- 675 = VarIdents ":"
|
|
|
- 676 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
- 677 IF (t # SymTab.InvalidType)
|
|
|
- 678 AND (cls # SymTab.ClInt)
|
|
|
- 679 AND (cls # SymTab.ClBool)
|
|
|
- 680 AND (cls # SymTab.ClChar)
|
|
|
- 681 AND (cls # SymTab.ClReal)
|
|
|
- 682 AND (cls # SymTab.ClArray)
|
|
|
- 683 AND (cls # SymTab.ClSet)
|
|
|
- 684 AND (cls # SymTab.ClRecord)
|
|
|
- 685 AND (cls # SymTab.ClPtr)
|
|
|
- 686 AND (cls # SymTab.ClLong)
|
|
|
- 687 AND (cls # SymTab.ClProc)
|
|
|
- 688 AND (cls # SymTab.ClUChar)
|
|
|
- 689 AND (cls # SymTab.ClUStr)
|
|
|
- 690 AND (cls # SymTab.ClEnum)
|
|
|
- 691 AND (cls # SymTab.ClClass) THEN
|
|
|
- 692 SemError(230) END;
|
|
|
- 693 IF QbeGen.LocFull() THEN
|
|
|
- 694 SemError(233) END;
|
|
|
- 695 i := 0;
|
|
|
- 696 WHILE i < SymTab.PendCount() DO
|
|
|
- 697 SymTab.PendName(i, nm);
|
|
|
- 698 QbeGen.DeclVar(nm, t);
|
|
|
- 699 INC(i)
|
|
|
- 700 END;
|
|
|
- 701 (* a plain VAR list, not a
|
|
|
- 702 heading: the signature
|
|
|
- 703 result is discarded *)
|
|
|
- 704 IF NOT SymTab.FixPending(t) THEN
|
|
|
- 705 END; .) .
|
|
|
- 706 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
- 707 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
- 708 SymTab.KindVar) THEN
|
|
|
- 709 SemError(200) END; .)
|
|
|
- 710 { ","
|
|
|
- 711 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
- 712 SymTab.KindVar) THEN
|
|
|
- 713 SemError(200) END; .) } .
|
|
|
- 714 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
- 715 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
- 716 SemError(200) END; .)
|
|
|
- 717 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
- 718 SemError(200) END; .) } .
|
|
|
- 719 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
- 720 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
- 721 FORWARD marks; the body heading re-enters (signature compare
|
|
|
- 722 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
- 723 ProcHeading<VAR pn: SymTab.Name; methCls: SymTab.TypeIndex>
|
|
|
- 724 (. VAR t: SymTab.TypeIndex;
|
|
|
- 725 mg: QbeGen.QVal; .)
|
|
|
- 726 = "PROCEDURE"
|
|
|
- 727 GetIdent<pn> (. IF methCls #
|
|
|
- 728 SymTab.InvalidType THEN
|
|
|
- 729 (* a method: resume the
|
|
|
- 730 declared symbol (reuse
|
|
|
- 731 its uid) *)
|
|
|
- 732 IF NOT SymTab.ResumeMethod(
|
|
|
- 733 methCls, pn) THEN
|
|
|
- 734 SemError(200) END
|
|
|
- 735 ELSIF NOT SymTab.EnterProc(pn) THEN
|
|
|
- 736 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
- 737 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
- 738 SemError(200) END
|
|
|
- 739 END
|
|
|
- 740 END;
|
|
|
- 741 IF methCls #
|
|
|
- 742 SymTab.InvalidType THEN
|
|
|
- 743 QbeGen.Mangled(pn,
|
|
|
- 744 SymTab.MethUid(), mg)
|
|
|
- 745 ELSE
|
|
|
+ 656 IF (cls = SymTab.ClArray)
|
|
|
+ 657 OR (cls = SymTab.ClRecord)
|
|
|
+ 658 OR (cls = SymTab.ClClass) THEN
|
|
|
+ 659 (* an aggregate constructor:
|
|
|
+ 660 qv is its pooled
|
|
|
+ 661 descriptor address; no
|
|
|
+ 662 scalar data *)
|
|
|
+ 663 SymTab.SetSymVal(n, qv)
|
|
|
+ 664 ELSIF cls = SymTab.ClStr THEN
|
|
|
+ 665 SemError(230)
|
|
|
+ 666 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
+ 667 SemError(230)
|
|
|
+ 668 ELSE
|
|
|
+ 669 SymTab.SetSymVal(n, qv);
|
|
|
+ 670 QbeGen.DeclConst(n, qv, t)
|
|
|
+ 671 END; .) .
|
|
|
+ 672 VarBlock
|
|
|
+ 673 = "VAR" { VarDecl ";" } .
|
|
|
+ 674 VarDecl (. VAR nm: SymTab.Name;
|
|
|
+ 675 t: SymTab.TypeIndex;
|
|
|
+ 676 i: CARDINAL;
|
|
|
+ 677 cls: INTEGER; .)
|
|
|
+ 678 = VarIdents ":"
|
|
|
+ 679 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
+ 680 IF (t # SymTab.InvalidType)
|
|
|
+ 681 AND (cls # SymTab.ClInt)
|
|
|
+ 682 AND (cls # SymTab.ClBool)
|
|
|
+ 683 AND (cls # SymTab.ClChar)
|
|
|
+ 684 AND (cls # SymTab.ClReal)
|
|
|
+ 685 AND (cls # SymTab.ClArray)
|
|
|
+ 686 AND (cls # SymTab.ClSet)
|
|
|
+ 687 AND (cls # SymTab.ClRecord)
|
|
|
+ 688 AND (cls # SymTab.ClPtr)
|
|
|
+ 689 AND (cls # SymTab.ClLong)
|
|
|
+ 690 AND (cls # SymTab.ClProc)
|
|
|
+ 691 AND (cls # SymTab.ClUChar)
|
|
|
+ 692 AND (cls # SymTab.ClUStr)
|
|
|
+ 693 AND (cls # SymTab.ClEnum)
|
|
|
+ 694 AND (cls # SymTab.ClClass) THEN
|
|
|
+ 695 SemError(230) END;
|
|
|
+ 696 IF QbeGen.LocFull() THEN
|
|
|
+ 697 SemError(233) END;
|
|
|
+ 698 i := 0;
|
|
|
+ 699 WHILE i < SymTab.PendCount() DO
|
|
|
+ 700 SymTab.PendName(i, nm);
|
|
|
+ 701 QbeGen.DeclVar(nm, t);
|
|
|
+ 702 INC(i)
|
|
|
+ 703 END;
|
|
|
+ 704 (* a plain VAR list, not a
|
|
|
+ 705 heading: the signature
|
|
|
+ 706 result is discarded *)
|
|
|
+ 707 IF NOT SymTab.FixPending(t) THEN
|
|
|
+ 708 END; .) .
|
|
|
+ 709 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
+ 710 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
+ 711 SymTab.KindVar) THEN
|
|
|
+ 712 SemError(200) END; .)
|
|
|
+ 713 { ","
|
|
|
+ 714 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
+ 715 SymTab.KindVar) THEN
|
|
|
+ 716 SemError(200) END; .) } .
|
|
|
+ 717 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
+ 718 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
+ 719 SemError(200) END; .)
|
|
|
+ 720 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
+ 721 SemError(200) END; .) } .
|
|
|
+ 722 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
+ 723 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
+ 724 FORWARD marks; the body heading re-enters (signature compare
|
|
|
+ 725 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
+ 726 ProcHeading<VAR pn: SymTab.Name; methCls: SymTab.TypeIndex>
|
|
|
+ 727 (. VAR t: SymTab.TypeIndex;
|
|
|
+ 728 mg: QbeGen.QVal; .)
|
|
|
+ 729 = "PROCEDURE"
|
|
|
+ 730 GetIdent<pn> (. IF methCls #
|
|
|
+ 731 SymTab.InvalidType THEN
|
|
|
+ 732 (* a method: resume the
|
|
|
+ 733 declared symbol (reuse
|
|
|
+ 734 its uid) *)
|
|
|
+ 735 IF NOT SymTab.ResumeMethod(
|
|
|
+ 736 methCls, pn) THEN
|
|
|
+ 737 SemError(200) END
|
|
|
+ 738 ELSIF NOT SymTab.EnterProc(pn) THEN
|
|
|
+ 739 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
+ 740 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
+ 741 SemError(200) END
|
|
|
+ 742 END
|
|
|
+ 743 END;
|
|
|
+ 744 IF methCls #
|
|
|
+ 745 SymTab.InvalidType THEN
|
|
|
746 QbeGen.Mangled(pn,
|
|
|
- 747 SymTab.ProcUid(pn), mg)
|
|
|
- 748 END;
|
|
|
- 749 QbeGen.BeginFunc(mg);
|
|
|
- 750 IF methCls #
|
|
|
- 751 SymTab.InvalidType THEN
|
|
|
- 752 (* hidden THIS receiver:
|
|
|
- 753 a VAR param of the
|
|
|
- 754 class type, pushed as
|
|
|
- 755 the WITH base *)
|
|
|
- 756 IF NOT SymTab.EnterThisParam(
|
|
|
- 757 methCls) THEN
|
|
|
- 758 SemError(200) END;
|
|
|
- 759 IF NOT QbeGen.FuncParam(
|
|
|
- 760 "THIS", TRUE,
|
|
|
- 761 methCls) THEN
|
|
|
- 762 SemError(233) END
|
|
|
- 763 END; .)
|
|
|
- 764 [ FormalParams ]
|
|
|
- 765 [ ":" TypeIdent<t> (. IF NOT SymTab.SetProcRes(t) THEN
|
|
|
- 766 SemError(235) END;
|
|
|
- 767 QbeGen.SetFuncRes(t);
|
|
|
- 768 IF (t #
|
|
|
- 769 SymTab.InvalidType)
|
|
|
- 770 AND ((SymTab.ClassOf(t)
|
|
|
- 771 = SymTab.ClArray)
|
|
|
- 772 OR (SymTab.ClassOf(t)
|
|
|
- 773 = SymTab.ClRecord)
|
|
|
- 774 OR (SymTab.ClassOf(t)
|
|
|
- 775 = SymTab.ClSet)
|
|
|
- 776 OR (SymTab.ClassOf(t)
|
|
|
- 777 = SymTab.ClClass)) THEN
|
|
|
- 778 SemError(230) END; .) ] .
|
|
|
- 779 FormalParams
|
|
|
- 780 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
- 781 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
- 782 nm: SymTab.Name;
|
|
|
- 783 i: CARDINAL;
|
|
|
- 784 isV: BOOLEAN; .)
|
|
|
- 785 = (. isV := FALSE; .)
|
|
|
- 786 [ "VAR" (. isV := TRUE; .) ]
|
|
|
- 787 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
- 788 WHILE i < SymTab.PendCount() DO
|
|
|
- 789 SymTab.PendName(i, nm);
|
|
|
- 790 (* value open arrays are
|
|
|
- 791 passed as descriptor
|
|
|
- 792 addresses (no copy):
|
|
|
- 793 same representation as
|
|
|
- 794 VAR formals *)
|
|
|
- 795 IF NOT QbeGen.FuncParam(nm,
|
|
|
- 796 isV
|
|
|
- 797 OR SymTab.IsOpenArray(t),
|
|
|
- 798 t) THEN
|
|
|
- 799 SemError(233) END;
|
|
|
- 800 INC(i)
|
|
|
- 801 END;
|
|
|
- 802 IF NOT SymTab.FixPending(t) THEN
|
|
|
- 803 SemError(235) END; .) .
|
|
|
- 804 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
- 805 static link gives them their parent's frame. Methods keep
|
|
|
- 806 parse-now/230-later. *)
|
|
|
- 807 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
- 808 = ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
- 809 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
- 810 SymTab.CloseProc;
|
|
|
- 811 QbeGen.AbortFunc; .)
|
|
|
- 812 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
+ 747 SymTab.MethUid(), mg)
|
|
|
+ 748 ELSE
|
|
|
+ 749 QbeGen.Mangled(pn,
|
|
|
+ 750 SymTab.ProcUid(pn), mg)
|
|
|
+ 751 END;
|
|
|
+ 752 QbeGen.BeginFunc(mg);
|
|
|
+ 753 IF methCls #
|
|
|
+ 754 SymTab.InvalidType THEN
|
|
|
+ 755 (* hidden THIS receiver:
|
|
|
+ 756 a VAR param of the
|
|
|
+ 757 class type, pushed as
|
|
|
+ 758 the WITH base *)
|
|
|
+ 759 IF NOT SymTab.EnterThisParam(
|
|
|
+ 760 methCls) THEN
|
|
|
+ 761 SemError(200) END;
|
|
|
+ 762 IF NOT QbeGen.FuncParam(
|
|
|
+ 763 "THIS", TRUE,
|
|
|
+ 764 methCls) THEN
|
|
|
+ 765 SemError(233) END
|
|
|
+ 766 END; .)
|
|
|
+ 767 [ FormalParams ]
|
|
|
+ 768 [ ":" TypeIdent<t> (. IF NOT SymTab.SetProcRes(t) THEN
|
|
|
+ 769 SemError(235) END;
|
|
|
+ 770 QbeGen.SetFuncRes(t);
|
|
|
+ 771 IF (t #
|
|
|
+ 772 SymTab.InvalidType)
|
|
|
+ 773 AND ((SymTab.ClassOf(t)
|
|
|
+ 774 = SymTab.ClArray)
|
|
|
+ 775 OR (SymTab.ClassOf(t)
|
|
|
+ 776 = SymTab.ClRecord)
|
|
|
+ 777 OR (SymTab.ClassOf(t)
|
|
|
+ 778 = SymTab.ClSet)
|
|
|
+ 779 OR (SymTab.ClassOf(t)
|
|
|
+ 780 = SymTab.ClClass)) THEN
|
|
|
+ 781 SemError(230) END; .) ] .
|
|
|
+ 782 FormalParams
|
|
|
+ 783 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
+ 784 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
+ 785 nm: SymTab.Name;
|
|
|
+ 786 i: CARDINAL;
|
|
|
+ 787 isV: BOOLEAN; .)
|
|
|
+ 788 = (. isV := FALSE; .)
|
|
|
+ 789 [ "VAR" (. isV := TRUE; .) ]
|
|
|
+ 790 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
+ 791 WHILE i < SymTab.PendCount() DO
|
|
|
+ 792 SymTab.PendName(i, nm);
|
|
|
+ 793 (* value open arrays are
|
|
|
+ 794 passed as descriptor
|
|
|
+ 795 addresses (no copy):
|
|
|
+ 796 same representation as
|
|
|
+ 797 VAR formals *)
|
|
|
+ 798 IF NOT QbeGen.FuncParam(nm,
|
|
|
+ 799 isV
|
|
|
+ 800 OR SymTab.IsOpenArray(t),
|
|
|
+ 801 t) THEN
|
|
|
+ 802 SemError(233) END;
|
|
|
+ 803 INC(i)
|
|
|
+ 804 END;
|
|
|
+ 805 IF NOT SymTab.FixPending(t) THEN
|
|
|
+ 806 SemError(235) END; .) .
|
|
|
+ 807 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
+ 808 static link gives them their parent's frame. Methods keep
|
|
|
+ 809 parse-now/230-later. *)
|
|
|
+ 810 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
+ 811 = ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
+ 812 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
813 SymTab.CloseProc;
|
|
|
814 QbeGen.AbortFunc; .)
|
|
|
- 815 | (. QbeGen.EndFuncHeader; .)
|
|
|
- 816 Block<pn> (. SymTab.CloseProc;
|
|
|
- 817 QbeGen.EndFunc(
|
|
|
- 818 SymTab.ProcRes(pn)); .) ) .
|
|
|
- 819 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
- 820 = DeclSeq
|
|
|
- 821 [ "BEGIN"
|
|
|
- 822 [ StatSeq ] ]
|
|
|
- 823 "END"
|
|
|
- 824 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
- 825 SemError(202) END; .) .
|
|
|
- 826 StatSeq
|
|
|
- 827 = Statement { ";" [ Statement ] } .
|
|
|
- 828 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
- 829 are accepted: the statement after ';' is optional. *)
|
|
|
- 830 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
- 831 = AssOrCall
|
|
|
- 832 | IfStat
|
|
|
- 833 | WhileStat
|
|
|
- 834 | RepeatStat
|
|
|
- 835 | LoopStat
|
|
|
- 836 | ForStat
|
|
|
- 837 | CaseStat
|
|
|
- 838 | WithStat
|
|
|
- 839 | ReturnStat
|
|
|
- 840 | HaltStat
|
|
|
- 841 | NewStat
|
|
|
- 842 | DisposeStat
|
|
|
- 843 | IncDecStat
|
|
|
- 844 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
- 845 QbeGen.Jmp(lx)
|
|
|
- 846 ELSE SemError(230) END; .) .
|
|
|
- 847 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
- 848 integer designator. *)
|
|
|
- 849 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
- 850 dk: INTEGER;
|
|
|
- 851 qd, qv, qn2, qstep:
|
|
|
- 852 QbeGen.QVal;
|
|
|
- 853 qn: SymTab.Name;
|
|
|
- 854 sfx, isInc: BOOLEAN; .)
|
|
|
- 855 = (. isInc := TRUE; .)
|
|
|
- 856 ( "INC" (. isInc := TRUE; .)
|
|
|
- 857 | "DEC" (. isInc := FALSE; .) )
|
|
|
- 858 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
- 859 Design<dt, dk, qd, qn, sfx>
|
|
|
- 860 [ "," Expr<et2, qstep> ]
|
|
|
- 861 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
- 862 ELSIF (dk # SymTab.KindVar)
|
|
|
- 863 AND (dk # SymTab.KindParam)
|
|
|
- 864 AND (dk # SymTab.KindField) THEN
|
|
|
- 865 SemError(210)
|
|
|
- 866 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
- 867 SemError(211)
|
|
|
- 868 ELSE
|
|
|
- 869 IF sfx
|
|
|
- 870 OR (dk = SymTab.KindField) THEN
|
|
|
- 871 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
- 872 ELSE QbeGen.LoadVar(qn,
|
|
|
- 873 FALSE, qv)
|
|
|
- 874 END;
|
|
|
- 875 QbeGen.NewTemp(qn2);
|
|
|
- 876 IF isInc THEN
|
|
|
- 877 QbeGen.Op3("add", qn2, qv,
|
|
|
- 878 qstep, FALSE)
|
|
|
- 879 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
- 880 qstep, FALSE)
|
|
|
- 881 END;
|
|
|
- 882 IF sfx
|
|
|
- 883 OR (dk = SymTab.KindField) THEN
|
|
|
- 884 QbeGen.ElemStore(qd, qn2,
|
|
|
- 885 dt)
|
|
|
- 886 ELSE QbeGen.StoreVar(qn,
|
|
|
- 887 qn2, FALSE)
|
|
|
- 888 END
|
|
|
- 889 END; .) .
|
|
|
- 890 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
- 891 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
- 892 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
- 893 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 894 dk: INTEGER;
|
|
|
- 895 qd, qm: QbeGen.QVal;
|
|
|
- 896 qn: SymTab.Name;
|
|
|
- 897 sfx: BOOLEAN;
|
|
|
- 898 bt: SymTab.TypeIndex; .)
|
|
|
- 899 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 900 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 901 ELSIF (dk # SymTab.KindVar)
|
|
|
- 902 AND (dk # SymTab.KindParam)
|
|
|
- 903 AND (dk # SymTab.KindField) THEN
|
|
|
- 904 SemError(210)
|
|
|
- 905 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 906 SymTab.ClPtr THEN
|
|
|
- 907 SemError(219)
|
|
|
- 908 ELSE bt := SymTab.PtrBase(dt);
|
|
|
- 909 IF bt #
|
|
|
- 910 SymTab.InvalidType THEN
|
|
|
- 911 QbeGen.NewHeap(bt, qm);
|
|
|
- 912 QbeGen.InitHeap(qm, bt);
|
|
|
- 913 IF sfx
|
|
|
- 914 OR (dk =
|
|
|
- 915 SymTab.KindField) THEN
|
|
|
- 916 QbeGen.ElemStore(qd, qm,
|
|
|
- 917 dt)
|
|
|
- 918 ELSE QbeGen.StorePtr(qn,
|
|
|
- 919 qm)
|
|
|
- 920 END
|
|
|
- 921 END
|
|
|
- 922 END; .) .
|
|
|
- 923 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 924 dk: INTEGER;
|
|
|
- 925 qd, qv: QbeGen.QVal;
|
|
|
- 926 qn: SymTab.Name;
|
|
|
- 927 sfx: BOOLEAN; .)
|
|
|
- 928 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 929 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 930 ELSIF (dk # SymTab.KindVar)
|
|
|
- 931 AND (dk # SymTab.KindParam)
|
|
|
- 932 AND (dk # SymTab.KindField) THEN
|
|
|
- 933 SemError(210)
|
|
|
- 934 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 935 SymTab.ClPtr THEN
|
|
|
- 936 SemError(219)
|
|
|
- 937 ELSE
|
|
|
- 938 IF sfx
|
|
|
- 939 OR (dk =
|
|
|
- 940 SymTab.KindField) THEN
|
|
|
- 941 QbeGen.ElemLoad(qd, dt,
|
|
|
- 942 qv)
|
|
|
- 943 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
- 944 END;
|
|
|
- 945 QbeGen.FreeHeap(qv);
|
|
|
- 946 IF sfx
|
|
|
- 947 OR (dk =
|
|
|
- 948 SymTab.KindField) THEN
|
|
|
- 949 QbeGen.ElemStore(qd, "0",
|
|
|
- 950 dt)
|
|
|
- 951 ELSE QbeGen.StorePtr(qn,
|
|
|
- 952 "0")
|
|
|
- 953 END
|
|
|
- 954 END; .) .
|
|
|
- 955 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
- 956 address; field designators resolve through both stacks. *)
|
|
|
- 957 WithStat (. VAR nW: CARDINAL; .)
|
|
|
- 958 = "WITH" (. nW := 0; .)
|
|
|
- 959 WithItem<nW> { "," WithItem<nW> }
|
|
|
- 960 "DO" [ StatSeq ] "END"
|
|
|
- 961 (. WHILE nW > 0 DO
|
|
|
- 962 SymTab.PopScope;
|
|
|
- 963 QbeGen.PopWith;
|
|
|
- 964 DEC(nW)
|
|
|
- 965 END; .) .
|
|
|
- 966 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
- 967 dk: INTEGER;
|
|
|
- 968 qd, qe: QbeGen.QVal;
|
|
|
- 969 qn: SymTab.Name;
|
|
|
- 970 sfx: BOOLEAN; .)
|
|
|
- 971 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 972 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 973 ELSIF (SymTab.ClassOf(dt) #
|
|
|
- 974 SymTab.ClRecord)
|
|
|
- 975 AND (SymTab.ClassOf(dt) #
|
|
|
- 976 SymTab.ClClass) THEN
|
|
|
- 977 SemError(215)
|
|
|
- 978 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
- 979 QbeGen.PushWith(qd);
|
|
|
- 980 INC(nW)
|
|
|
- 981 END; .) .
|
|
|
- 982 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
- 983 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
- 984 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
- 985 dk: INTEGER;
|
|
|
- 986 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
- 987 qn: SymTab.Name;
|
|
|
- 988 ct2, res0: SymTab.TypeIndex;
|
|
|
- 989 q2, mg0: QbeGen.QVal;
|
|
|
- 990 isR, conv, wconv: BOOLEAN;
|
|
|
- 991 called, sfx: BOOLEAN; .)
|
|
|
- 992 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 993 ( ":="
|
|
|
- 994 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
- 995 AND (dk # SymTab.KindVar)
|
|
|
- 996 AND (dk # SymTab.KindParam)
|
|
|
- 997 AND (dk # SymTab.KindField) THEN
|
|
|
- 998 SemError(210)
|
|
|
- 999 ELSIF NOT SymTab.Assignable(et,
|
|
|
- 1000 dt) THEN
|
|
|
+ 815 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
+ 816 SymTab.CloseProc;
|
|
|
+ 817 QbeGen.AbortFunc; .)
|
|
|
+ 818 | (. QbeGen.EndFuncHeader; .)
|
|
|
+ 819 Block<pn> (. SymTab.CloseProc;
|
|
|
+ 820 QbeGen.EndFunc(
|
|
|
+ 821 SymTab.ProcRes(pn)); .) ) .
|
|
|
+ 822 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
+ 823 = DeclSeq
|
|
|
+ 824 [ "BEGIN"
|
|
|
+ 825 [ StatSeq ] ]
|
|
|
+ 826 "END"
|
|
|
+ 827 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
+ 828 SemError(202) END; .) .
|
|
|
+ 829 StatSeq
|
|
|
+ 830 = Statement { ";" [ Statement ] } .
|
|
|
+ 831 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
+ 832 are accepted: the statement after ';' is optional. *)
|
|
|
+ 833 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
+ 834 = AssOrCall
|
|
|
+ 835 | IfStat
|
|
|
+ 836 | WhileStat
|
|
|
+ 837 | RepeatStat
|
|
|
+ 838 | LoopStat
|
|
|
+ 839 | ForStat
|
|
|
+ 840 | CaseStat
|
|
|
+ 841 | WithStat
|
|
|
+ 842 | ReturnStat
|
|
|
+ 843 | HaltStat
|
|
|
+ 844 | NewStat
|
|
|
+ 845 | DisposeStat
|
|
|
+ 846 | IncDecStat
|
|
|
+ 847 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
+ 848 QbeGen.Jmp(lx)
|
|
|
+ 849 ELSE SemError(230) END; .) .
|
|
|
+ 850 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
+ 851 integer designator. *)
|
|
|
+ 852 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
+ 853 dk: INTEGER;
|
|
|
+ 854 qd, qv, qn2, qstep:
|
|
|
+ 855 QbeGen.QVal;
|
|
|
+ 856 qn: SymTab.Name;
|
|
|
+ 857 sfx, isInc: BOOLEAN; .)
|
|
|
+ 858 = (. isInc := TRUE; .)
|
|
|
+ 859 ( "INC" (. isInc := TRUE; .)
|
|
|
+ 860 | "DEC" (. isInc := FALSE; .) )
|
|
|
+ 861 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
+ 862 Design<dt, dk, qd, qn, sfx>
|
|
|
+ 863 [ "," Expr<et2, qstep> ]
|
|
|
+ 864 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 865 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 866 AND (dk # SymTab.KindParam)
|
|
|
+ 867 AND (dk # SymTab.KindField) THEN
|
|
|
+ 868 SemError(210)
|
|
|
+ 869 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
+ 870 SemError(211)
|
|
|
+ 871 ELSE
|
|
|
+ 872 IF sfx
|
|
|
+ 873 OR (dk = SymTab.KindField) THEN
|
|
|
+ 874 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
+ 875 ELSE QbeGen.LoadVar(qn,
|
|
|
+ 876 FALSE, qv)
|
|
|
+ 877 END;
|
|
|
+ 878 QbeGen.NewTemp(qn2);
|
|
|
+ 879 IF isInc THEN
|
|
|
+ 880 QbeGen.Op3("add", qn2, qv,
|
|
|
+ 881 qstep, FALSE)
|
|
|
+ 882 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
+ 883 qstep, FALSE)
|
|
|
+ 884 END;
|
|
|
+ 885 IF sfx
|
|
|
+ 886 OR (dk = SymTab.KindField) THEN
|
|
|
+ 887 QbeGen.ElemStore(qd, qn2,
|
|
|
+ 888 dt)
|
|
|
+ 889 ELSE QbeGen.StoreVar(qn,
|
|
|
+ 890 qn2, FALSE)
|
|
|
+ 891 END
|
|
|
+ 892 END; .) .
|
|
|
+ 893 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
+ 894 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
+ 895 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
+ 896 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 897 dk: INTEGER;
|
|
|
+ 898 qd, qm: QbeGen.QVal;
|
|
|
+ 899 qn: SymTab.Name;
|
|
|
+ 900 sfx: BOOLEAN;
|
|
|
+ 901 bt: SymTab.TypeIndex; .)
|
|
|
+ 902 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 903 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 904 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 905 AND (dk # SymTab.KindParam)
|
|
|
+ 906 AND (dk # SymTab.KindField) THEN
|
|
|
+ 907 SemError(210)
|
|
|
+ 908 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 909 SymTab.ClPtr THEN
|
|
|
+ 910 SemError(219)
|
|
|
+ 911 ELSE bt := SymTab.PtrBase(dt);
|
|
|
+ 912 IF bt #
|
|
|
+ 913 SymTab.InvalidType THEN
|
|
|
+ 914 QbeGen.NewHeap(bt, qm);
|
|
|
+ 915 QbeGen.InitHeap(qm, bt);
|
|
|
+ 916 IF sfx
|
|
|
+ 917 OR (dk =
|
|
|
+ 918 SymTab.KindField) THEN
|
|
|
+ 919 QbeGen.ElemStore(qd, qm,
|
|
|
+ 920 dt)
|
|
|
+ 921 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 922 qm)
|
|
|
+ 923 END
|
|
|
+ 924 END
|
|
|
+ 925 END; .) .
|
|
|
+ 926 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 927 dk: INTEGER;
|
|
|
+ 928 qd, qv: QbeGen.QVal;
|
|
|
+ 929 qn: SymTab.Name;
|
|
|
+ 930 sfx: BOOLEAN; .)
|
|
|
+ 931 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 932 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 933 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 934 AND (dk # SymTab.KindParam)
|
|
|
+ 935 AND (dk # SymTab.KindField) THEN
|
|
|
+ 936 SemError(210)
|
|
|
+ 937 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 938 SymTab.ClPtr THEN
|
|
|
+ 939 SemError(219)
|
|
|
+ 940 ELSE
|
|
|
+ 941 IF sfx
|
|
|
+ 942 OR (dk =
|
|
|
+ 943 SymTab.KindField) THEN
|
|
|
+ 944 QbeGen.ElemLoad(qd, dt,
|
|
|
+ 945 qv)
|
|
|
+ 946 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
+ 947 END;
|
|
|
+ 948 QbeGen.FreeHeap(qv);
|
|
|
+ 949 IF sfx
|
|
|
+ 950 OR (dk =
|
|
|
+ 951 SymTab.KindField) THEN
|
|
|
+ 952 QbeGen.ElemStore(qd, "0",
|
|
|
+ 953 dt)
|
|
|
+ 954 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 955 "0")
|
|
|
+ 956 END
|
|
|
+ 957 END; .) .
|
|
|
+ 958 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
+ 959 address; field designators resolve through both stacks. *)
|
|
|
+ 960 WithStat (. VAR nW: CARDINAL; .)
|
|
|
+ 961 = "WITH" (. nW := 0; .)
|
|
|
+ 962 WithItem<nW> { "," WithItem<nW> }
|
|
|
+ 963 "DO" [ StatSeq ] "END"
|
|
|
+ 964 (. WHILE nW > 0 DO
|
|
|
+ 965 SymTab.PopScope;
|
|
|
+ 966 QbeGen.PopWith;
|
|
|
+ 967 DEC(nW)
|
|
|
+ 968 END; .) .
|
|
|
+ 969 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 970 dk: INTEGER;
|
|
|
+ 971 qd, qe: QbeGen.QVal;
|
|
|
+ 972 qn: SymTab.Name;
|
|
|
+ 973 sfx: BOOLEAN; .)
|
|
|
+ 974 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 975 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 976 ELSIF (SymTab.ClassOf(dt) #
|
|
|
+ 977 SymTab.ClRecord)
|
|
|
+ 978 AND (SymTab.ClassOf(dt) #
|
|
|
+ 979 SymTab.ClClass) THEN
|
|
|
+ 980 SemError(215)
|
|
|
+ 981 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
+ 982 QbeGen.PushWith(qd);
|
|
|
+ 983 INC(nW)
|
|
|
+ 984 END; .) .
|
|
|
+ 985 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
+ 986 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
+ 987 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
+ 988 dk: INTEGER;
|
|
|
+ 989 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
+ 990 qn: SymTab.Name;
|
|
|
+ 991 ct2, res0: SymTab.TypeIndex;
|
|
|
+ 992 q2, mg0: QbeGen.QVal;
|
|
|
+ 993 isR, conv, wconv: BOOLEAN;
|
|
|
+ 994 called, sfx: BOOLEAN; .)
|
|
|
+ 995 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 996 ( ":="
|
|
|
+ 997 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
+ 998 AND (dk # SymTab.KindVar)
|
|
|
+ 999 AND (dk # SymTab.KindParam)
|
|
|
+ 1000 AND (dk # SymTab.KindField) THEN
|
|
|
1001 SemError(210)
|
|
|
- 1002 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 1003 AND (SymTab.ClassOf(dt) =
|
|
|
- 1004 SymTab.ClClass) THEN
|
|
|
- 1005 SemError(230) END;
|
|
|
- 1006 isR := (dt #
|
|
|
- 1007 SymTab.InvalidType)
|
|
|
- 1008 AND (SymTab.ClassOf(dt)
|
|
|
- 1009 = SymTab.ClReal);
|
|
|
- 1010 conv := isR
|
|
|
- 1011 AND SymTab.IsIntFamily(et);
|
|
|
- 1012 wconv := (dt #
|
|
|
- 1013 SymTab.InvalidType)
|
|
|
- 1014 AND SymTab.IsLongFamily(dt)
|
|
|
- 1015 AND SymTab.IsIntFamily(et);
|
|
|
- 1016 IF ((dk = SymTab.KindVar)
|
|
|
- 1017 OR (dk = SymTab.KindParam)
|
|
|
- 1018 OR (dk = SymTab.KindField))
|
|
|
- 1019 AND (dt # SymTab.InvalidType)
|
|
|
- 1020 AND (et # SymTab.InvalidType)
|
|
|
- 1021 AND (SymTab.ClassOf(dt) #
|
|
|
- 1022 SymTab.ClClass) THEN
|
|
|
- 1023 IF sfx
|
|
|
- 1024 OR (dk = SymTab.KindField) THEN
|
|
|
- 1025 IF SymTab.ClassOf(dt) =
|
|
|
- 1026 SymTab.ClArray THEN
|
|
|
- 1027 IF (et # SymTab.InvalidType)
|
|
|
- 1028 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
- 1029 AND SymTab.IsUCharArray(dt) THEN
|
|
|
- 1030 QbeGen.UAssign(qd, qe)
|
|
|
- 1031 ELSIF SymTab.StrCompat(dt,
|
|
|
- 1032 et) THEN
|
|
|
- 1033 QbeGen.StrAssign(qd,
|
|
|
- 1034 qe)
|
|
|
- 1035 ELSE
|
|
|
- 1036 QbeGen.CopyArray(qd,
|
|
|
- 1037 qe, dt)
|
|
|
- 1038 END
|
|
|
- 1039 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1040 SymTab.ClSet THEN
|
|
|
- 1041 QbeGen.CopySet(qd, qe,
|
|
|
- 1042 SymTab.SetWords(dt),
|
|
|
- 1043 SymTab.SetWords(et))
|
|
|
- 1044 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1045 SymTab.ClRecord THEN
|
|
|
- 1046 QbeGen.CopyRecord(qd, qe,
|
|
|
- 1047 dt)
|
|
|
- 1048 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 1049 IF wconv THEN
|
|
|
- 1050 QbeGen.WidenLong(qe, ql);
|
|
|
- 1051 QbeGen.ElemStore(qd, ql,
|
|
|
- 1052 dt)
|
|
|
- 1053 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 1054 dt)
|
|
|
- 1055 END
|
|
|
- 1056 ELSIF conv THEN
|
|
|
- 1057 QbeGen.ConvIR(qe, qt);
|
|
|
- 1058 QbeGen.ElemStore(qd, qt,
|
|
|
- 1059 dt)
|
|
|
- 1060 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 1061 dt)
|
|
|
- 1062 END
|
|
|
- 1063 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1064 SymTab.ClArray THEN
|
|
|
- 1065 IF (et # SymTab.InvalidType)
|
|
|
- 1066 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
- 1067 AND SymTab.IsUCharArray(dt) THEN
|
|
|
- 1068 QbeGen.UAssign(qd, qe)
|
|
|
- 1069 ELSIF SymTab.StrCompat(dt,
|
|
|
- 1070 et) THEN
|
|
|
- 1071 QbeGen.StrAssign(qd, qe)
|
|
|
- 1072 ELSE
|
|
|
- 1073 QbeGen.CopyArray(qd, qe,
|
|
|
- 1074 dt)
|
|
|
- 1075 END
|
|
|
- 1076 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1077 SymTab.ClSet THEN
|
|
|
- 1078 QbeGen.CopySet(qd, qe,
|
|
|
- 1079 SymTab.SetWords(dt),
|
|
|
- 1080 SymTab.SetWords(et))
|
|
|
- 1081 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1082 SymTab.ClRecord THEN
|
|
|
- 1083 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
- 1084 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1085 SymTab.ClPtr)
|
|
|
- 1086 OR (SymTab.ClassOf(dt) =
|
|
|
- 1087 SymTab.ClProc) THEN
|
|
|
- 1088 QbeGen.StorePtr(qn, qe)
|
|
|
- 1089 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 1090 IF wconv THEN
|
|
|
- 1091 QbeGen.WidenLong(qe, ql);
|
|
|
- 1092 QbeGen.StoreLong(qn, ql)
|
|
|
- 1093 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
- 1094 END
|
|
|
- 1095 ELSIF conv THEN
|
|
|
- 1096 QbeGen.ConvIR(qe, qt);
|
|
|
- 1097 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
- 1098 ELSE
|
|
|
- 1099 QbeGen.StoreVar(qn, qe, isR)
|
|
|
- 1100 END
|
|
|
- 1101 END; .)
|
|
|
- 1102 | ArgList<qn, dt, qd, FALSE, methCls, ct2, q2, called>
|
|
|
- 1103 | (* bare `P;`: proper parameterless
|
|
|
- 1104 procedure call; anything else
|
|
|
- 1105 here is 233 (was a bare syntax
|
|
|
- 1106 error before 4.2) *)
|
|
|
- 1107 (. IF (dk = SymTab.KindProc)
|
|
|
- 1108 AND NOT sfx THEN
|
|
|
- 1109 res0 := SymTab.ProcRes(qn);
|
|
|
- 1110 IF res0 #
|
|
|
- 1111 SymTab.InvalidType THEN
|
|
|
- 1112 SemError(233)
|
|
|
- 1113 ELSIF SymTab.ProcNPar(qn) #
|
|
|
- 1114 0 THEN
|
|
|
+ 1002 ELSIF NOT SymTab.Assignable(et,
|
|
|
+ 1003 dt) THEN
|
|
|
+ 1004 SemError(210)
|
|
|
+ 1005 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 1006 AND (SymTab.ClassOf(dt) =
|
|
|
+ 1007 SymTab.ClClass) THEN
|
|
|
+ 1008 SemError(230) END;
|
|
|
+ 1009 isR := (dt #
|
|
|
+ 1010 SymTab.InvalidType)
|
|
|
+ 1011 AND (SymTab.ClassOf(dt)
|
|
|
+ 1012 = SymTab.ClReal);
|
|
|
+ 1013 conv := isR
|
|
|
+ 1014 AND SymTab.IsIntFamily(et);
|
|
|
+ 1015 wconv := (dt #
|
|
|
+ 1016 SymTab.InvalidType)
|
|
|
+ 1017 AND SymTab.IsLongFamily(dt)
|
|
|
+ 1018 AND SymTab.IsIntFamily(et);
|
|
|
+ 1019 IF ((dk = SymTab.KindVar)
|
|
|
+ 1020 OR (dk = SymTab.KindParam)
|
|
|
+ 1021 OR (dk = SymTab.KindField))
|
|
|
+ 1022 AND (dt # SymTab.InvalidType)
|
|
|
+ 1023 AND (et # SymTab.InvalidType)
|
|
|
+ 1024 AND (SymTab.ClassOf(dt) #
|
|
|
+ 1025 SymTab.ClClass) THEN
|
|
|
+ 1026 IF sfx
|
|
|
+ 1027 OR (dk = SymTab.KindField) THEN
|
|
|
+ 1028 IF SymTab.ClassOf(dt) =
|
|
|
+ 1029 SymTab.ClArray THEN
|
|
|
+ 1030 IF (et # SymTab.InvalidType)
|
|
|
+ 1031 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 1032 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 1033 QbeGen.UAssign(qd, qe)
|
|
|
+ 1034 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 1035 et) THEN
|
|
|
+ 1036 QbeGen.StrAssign(qd,
|
|
|
+ 1037 qe)
|
|
|
+ 1038 ELSE
|
|
|
+ 1039 QbeGen.CopyArray(qd,
|
|
|
+ 1040 qe, dt)
|
|
|
+ 1041 END
|
|
|
+ 1042 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1043 SymTab.ClSet THEN
|
|
|
+ 1044 QbeGen.CopySet(qd, qe,
|
|
|
+ 1045 SymTab.SetWords(dt),
|
|
|
+ 1046 SymTab.SetWords(et))
|
|
|
+ 1047 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1048 SymTab.ClRecord THEN
|
|
|
+ 1049 QbeGen.CopyRecord(qd, qe,
|
|
|
+ 1050 dt)
|
|
|
+ 1051 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 1052 IF wconv THEN
|
|
|
+ 1053 QbeGen.WidenLong(qe, ql);
|
|
|
+ 1054 QbeGen.ElemStore(qd, ql,
|
|
|
+ 1055 dt)
|
|
|
+ 1056 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 1057 dt)
|
|
|
+ 1058 END
|
|
|
+ 1059 ELSIF conv THEN
|
|
|
+ 1060 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1061 QbeGen.ElemStore(qd, qt,
|
|
|
+ 1062 dt)
|
|
|
+ 1063 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 1064 dt)
|
|
|
+ 1065 END
|
|
|
+ 1066 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1067 SymTab.ClArray THEN
|
|
|
+ 1068 IF (et # SymTab.InvalidType)
|
|
|
+ 1069 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 1070 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 1071 QbeGen.UAssign(qd, qe)
|
|
|
+ 1072 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 1073 et) THEN
|
|
|
+ 1074 QbeGen.StrAssign(qd, qe)
|
|
|
+ 1075 ELSE
|
|
|
+ 1076 QbeGen.CopyArray(qd, qe,
|
|
|
+ 1077 dt)
|
|
|
+ 1078 END
|
|
|
+ 1079 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1080 SymTab.ClSet THEN
|
|
|
+ 1081 QbeGen.CopySet(qd, qe,
|
|
|
+ 1082 SymTab.SetWords(dt),
|
|
|
+ 1083 SymTab.SetWords(et))
|
|
|
+ 1084 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1085 SymTab.ClRecord THEN
|
|
|
+ 1086 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
+ 1087 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1088 SymTab.ClPtr)
|
|
|
+ 1089 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1090 SymTab.ClProc) THEN
|
|
|
+ 1091 QbeGen.StorePtr(qn, qe)
|
|
|
+ 1092 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 1093 IF wconv THEN
|
|
|
+ 1094 QbeGen.WidenLong(qe, ql);
|
|
|
+ 1095 QbeGen.StoreLong(qn, ql)
|
|
|
+ 1096 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
+ 1097 END
|
|
|
+ 1098 ELSIF conv THEN
|
|
|
+ 1099 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1100 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
+ 1101 ELSE
|
|
|
+ 1102 QbeGen.StoreVar(qn, qe, isR)
|
|
|
+ 1103 END
|
|
|
+ 1104 END; .)
|
|
|
+ 1105 | ArgList<qn, dt, qd, FALSE, methCls, ct2, q2, called>
|
|
|
+ 1106 | (* bare `P;`: proper parameterless
|
|
|
+ 1107 procedure call; anything else
|
|
|
+ 1108 here is 233 (was a bare syntax
|
|
|
+ 1109 error before 4.2) *)
|
|
|
+ 1110 (. IF (dk = SymTab.KindProc)
|
|
|
+ 1111 AND NOT sfx THEN
|
|
|
+ 1112 res0 := SymTab.ProcRes(qn);
|
|
|
+ 1113 IF res0 #
|
|
|
+ 1114 SymTab.InvalidType THEN
|
|
|
1115 SemError(233)
|
|
|
- 1116 ELSE QbeGen.Mangled(qn,
|
|
|
- 1117 SymTab.ProcUid(qn), mg0);
|
|
|
- 1118 QbeGen.CallBegin(mg0,
|
|
|
- 1119 res0,
|
|
|
- 1120 SymTab.ProcDepthOf(qn),
|
|
|
- 1121 SymTab.IsExternal(qn));
|
|
|
- 1122 QbeGen.CallEnd(FALSE, q2)
|
|
|
- 1123 END
|
|
|
- 1124 ELSE SemError(233)
|
|
|
- 1125 END; .) ) .
|
|
|
- 1126 (* Actual-parameter list shared by statement and expression calls.
|
|
|
- 1127 want selects CallEnd's result handling; t/q carry the call
|
|
|
- 1128 value (statement calls discard). Arity/type failures are 233;
|
|
|
- 1129 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
- 1130 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
- 1131 want: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
- 1132 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 1133 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
- 1134 vs: INTEGER;
|
|
|
- 1135 res: SymTab.TypeIndex;
|
|
|
- 1136 mg: QbeGen.QVal;
|
|
|
- 1137 ok, ind, isMeth: BOOLEAN; .)
|
|
|
- 1138 = "(" (. called := TRUE;
|
|
|
- 1139 ok := TRUE;
|
|
|
- 1140 ind := FALSE;
|
|
|
- 1141 isMeth := methCls #
|
|
|
- 1142 SymTab.InvalidType;
|
|
|
- 1143 IF isMeth THEN
|
|
|
- 1144 (* class method: the
|
|
|
- 1145 receiver is armed.
|
|
|
- 1146 Virtual -> dispatch
|
|
|
- 1147 through the vtable;
|
|
|
- 1148 otherwise a static
|
|
|
- 1149 call. *)
|
|
|
- 1150 res := SymTab.ClassMethodRes(
|
|
|
- 1151 methCls, pn);
|
|
|
- 1152 vs := SymTab.VirtSlot(
|
|
|
- 1153 methCls, pn);
|
|
|
- 1154 IF vs >= 0 THEN
|
|
|
- 1155 QbeGen.VirtCallBegin(
|
|
|
- 1156 callee, vs, res)
|
|
|
- 1157 ELSE
|
|
|
- 1158 QbeGen.Mangled(pn,
|
|
|
- 1159 SymTab.ClassMethodUid(
|
|
|
- 1160 methCls, pn), mg);
|
|
|
- 1161 QbeGen.CallBegin(mg, res, 0,
|
|
|
- 1162 FALSE)
|
|
|
- 1163 END
|
|
|
- 1164 ELSIF SymTab.SymKind(pn) =
|
|
|
- 1165 SymTab.KindProc THEN
|
|
|
- 1166 res := SymTab.ProcRes(pn);
|
|
|
- 1167 QbeGen.Mangled(pn,
|
|
|
- 1168 SymTab.ProcUid(pn), mg);
|
|
|
- 1169 QbeGen.CallBegin(mg, res,
|
|
|
- 1170 SymTab.ProcDepthOf(pn),
|
|
|
- 1171 SymTab.IsExternal(pn))
|
|
|
- 1172 ELSIF (pt # SymTab.InvalidType)
|
|
|
- 1173 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
- 1174 ind := TRUE;
|
|
|
- 1175 res :=
|
|
|
- 1176 SymTab.ProcTypeRes(pt);
|
|
|
- 1177 QbeGen.CallBeginInd(callee,
|
|
|
- 1178 res, FALSE)
|
|
|
- 1179 ELSE SemError(233);
|
|
|
- 1180 ok := FALSE;
|
|
|
- 1181 res := SymTab.InvalidType
|
|
|
- 1182 END;
|
|
|
- 1183 i := 0; .)
|
|
|
- 1184 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
- 1185 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
- 1186 ")" (. IF ok THEN
|
|
|
- 1187 IF isMeth THEN
|
|
|
- 1188 np := SymTab.ClassMethodNPar(
|
|
|
- 1189 methCls, pn)
|
|
|
- 1190 ELSIF ind THEN
|
|
|
- 1191 np := SymTab.ProcTypeNPar(pt)
|
|
|
- 1192 ELSE np := SymTab.ProcNPar(pn)
|
|
|
- 1193 END;
|
|
|
- 1194 IF i # np THEN
|
|
|
- 1195 SemError(233); ok := FALSE
|
|
|
- 1196 END
|
|
|
- 1197 END;
|
|
|
- 1198 IF NOT ok THEN
|
|
|
- 1199 t := SymTab.InvalidType;
|
|
|
- 1200 QbeGen.CopyOp("0", q)
|
|
|
- 1201 ELSIF want THEN
|
|
|
- 1202 IF res =
|
|
|
- 1203 SymTab.InvalidType THEN
|
|
|
- 1204 SemError(233);
|
|
|
- 1205 t := SymTab.InvalidType;
|
|
|
- 1206 QbeGen.CopyOp("0", q)
|
|
|
- 1207 ELSE t := res;
|
|
|
- 1208 QbeGen.CallEnd(TRUE, q)
|
|
|
- 1209 END
|
|
|
- 1210 ELSE
|
|
|
- 1211 IF res #
|
|
|
- 1212 SymTab.InvalidType THEN
|
|
|
- 1213 SemError(233)
|
|
|
- 1214 END;
|
|
|
- 1215 t := SymTab.InvalidType;
|
|
|
- 1216 QbeGen.CopyOp("0", q);
|
|
|
- 1217 QbeGen.CallEnd(FALSE, q)
|
|
|
- 1218 END; .) .
|
|
|
- 1219 (* One actual: VAR formals take recorded designator addresses
|
|
|
- 1220 (233 otherwise); value formals take converted expressions. *)
|
|
|
- 1221 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
- 1222 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
- 1223 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
- 1224 qe, qa, qt: QbeGen.QVal;
|
|
|
- 1225 isV, conv: BOOLEAN; .)
|
|
|
- 1226 = Expr<at, qe> (. IF ind THEN
|
|
|
- 1227 ft :=
|
|
|
- 1228 SymTab.ProcTypeParamType(pt,
|
|
|
- 1229 i);
|
|
|
- 1230 isV :=
|
|
|
- 1231 SymTab.ProcTypeParamIsVar(pt,
|
|
|
- 1232 i)
|
|
|
- 1233 ELSIF methCls #
|
|
|
- 1234 SymTab.InvalidType THEN
|
|
|
- 1235 ft :=
|
|
|
- 1236 SymTab.ClassMethodParamType(
|
|
|
- 1237 methCls, pn, i);
|
|
|
- 1238 isV :=
|
|
|
- 1239 SymTab.ClassMethodParamIsVar(
|
|
|
- 1240 methCls, pn, i)
|
|
|
- 1241 ELSE
|
|
|
- 1242 ft := SymTab.ParamType(pn, i);
|
|
|
- 1243 isV := SymTab.ParamIsVar(pn, i)
|
|
|
- 1244 END;
|
|
|
- 1245 IF (at = SymTab.InvalidType)
|
|
|
- 1246 OR (ft =
|
|
|
- 1247 SymTab.InvalidType) THEN
|
|
|
- 1248 ELSIF isV THEN
|
|
|
- 1249 IF (SymTab.ClassOf(at)
|
|
|
- 1250 = SymTab.ClChar)
|
|
|
- 1251 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1252 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1253 = SymTab.ClChar)
|
|
|
- 1254 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1255 (* 1-char string
|
|
|
- 1256 literal passed to
|
|
|
- 1257 a VAR ARRAY OF CHAR *)
|
|
|
- 1258 QbeGen.DeclCharStr(qe,
|
|
|
- 1259 qa);
|
|
|
- 1260 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1261 "l") THEN
|
|
|
- 1262 SemError(233)
|
|
|
- 1263 END
|
|
|
- 1264 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
- 1265 qa) THEN
|
|
|
- 1266 SemError(233)
|
|
|
- 1267 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
- 1268 ft) THEN
|
|
|
+ 1116 ELSIF SymTab.ProcNPar(qn) #
|
|
|
+ 1117 0 THEN
|
|
|
+ 1118 SemError(233)
|
|
|
+ 1119 ELSE QbeGen.Mangled(qn,
|
|
|
+ 1120 SymTab.ProcUid(qn), mg0);
|
|
|
+ 1121 QbeGen.CallBegin(mg0,
|
|
|
+ 1122 res0,
|
|
|
+ 1123 SymTab.ProcDepthOf(qn),
|
|
|
+ 1124 SymTab.IsExternal(qn));
|
|
|
+ 1125 QbeGen.CallEnd(FALSE, q2)
|
|
|
+ 1126 END
|
|
|
+ 1127 ELSE SemError(233)
|
|
|
+ 1128 END; .) ) .
|
|
|
+ 1129 (* Actual-parameter list shared by statement and expression calls.
|
|
|
+ 1130 want selects CallEnd's result handling; t/q carry the call
|
|
|
+ 1131 value (statement calls discard). Arity/type failures are 233;
|
|
|
+ 1132 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
+ 1133 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
+ 1134 want: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
+ 1135 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 1136 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
+ 1137 vs: INTEGER;
|
|
|
+ 1138 res: SymTab.TypeIndex;
|
|
|
+ 1139 mg: QbeGen.QVal;
|
|
|
+ 1140 ok, ind, isMeth: BOOLEAN; .)
|
|
|
+ 1141 = "(" (. called := TRUE;
|
|
|
+ 1142 ok := TRUE;
|
|
|
+ 1143 ind := FALSE;
|
|
|
+ 1144 isMeth := methCls #
|
|
|
+ 1145 SymTab.InvalidType;
|
|
|
+ 1146 IF isMeth THEN
|
|
|
+ 1147 (* class method: the
|
|
|
+ 1148 receiver is armed.
|
|
|
+ 1149 Virtual -> dispatch
|
|
|
+ 1150 through the vtable;
|
|
|
+ 1151 otherwise a static
|
|
|
+ 1152 call. *)
|
|
|
+ 1153 res := SymTab.ClassMethodRes(
|
|
|
+ 1154 methCls, pn);
|
|
|
+ 1155 vs := SymTab.VirtSlot(
|
|
|
+ 1156 methCls, pn);
|
|
|
+ 1157 IF vs >= 0 THEN
|
|
|
+ 1158 QbeGen.VirtCallBegin(
|
|
|
+ 1159 callee, vs, res)
|
|
|
+ 1160 ELSE
|
|
|
+ 1161 QbeGen.Mangled(pn,
|
|
|
+ 1162 SymTab.ClassMethodUid(
|
|
|
+ 1163 methCls, pn), mg);
|
|
|
+ 1164 QbeGen.CallBegin(mg, res, 0,
|
|
|
+ 1165 FALSE)
|
|
|
+ 1166 END
|
|
|
+ 1167 ELSIF SymTab.SymKind(pn) =
|
|
|
+ 1168 SymTab.KindProc THEN
|
|
|
+ 1169 res := SymTab.ProcRes(pn);
|
|
|
+ 1170 QbeGen.Mangled(pn,
|
|
|
+ 1171 SymTab.ProcUid(pn), mg);
|
|
|
+ 1172 QbeGen.CallBegin(mg, res,
|
|
|
+ 1173 SymTab.ProcDepthOf(pn),
|
|
|
+ 1174 SymTab.IsExternal(pn))
|
|
|
+ 1175 ELSIF (pt # SymTab.InvalidType)
|
|
|
+ 1176 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
+ 1177 ind := TRUE;
|
|
|
+ 1178 res :=
|
|
|
+ 1179 SymTab.ProcTypeRes(pt);
|
|
|
+ 1180 QbeGen.CallBeginInd(callee,
|
|
|
+ 1181 res, FALSE)
|
|
|
+ 1182 ELSE SemError(233);
|
|
|
+ 1183 ok := FALSE;
|
|
|
+ 1184 res := SymTab.InvalidType
|
|
|
+ 1185 END;
|
|
|
+ 1186 i := 0; .)
|
|
|
+ 1187 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
+ 1188 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
+ 1189 ")" (. IF ok THEN
|
|
|
+ 1190 IF isMeth THEN
|
|
|
+ 1191 np := SymTab.ClassMethodNPar(
|
|
|
+ 1192 methCls, pn)
|
|
|
+ 1193 ELSIF ind THEN
|
|
|
+ 1194 np := SymTab.ProcTypeNPar(pt)
|
|
|
+ 1195 ELSE np := SymTab.ProcNPar(pn)
|
|
|
+ 1196 END;
|
|
|
+ 1197 IF i # np THEN
|
|
|
+ 1198 SemError(233); ok := FALSE
|
|
|
+ 1199 END
|
|
|
+ 1200 END;
|
|
|
+ 1201 IF NOT ok THEN
|
|
|
+ 1202 t := SymTab.InvalidType;
|
|
|
+ 1203 QbeGen.CopyOp("0", q)
|
|
|
+ 1204 ELSIF want THEN
|
|
|
+ 1205 IF res =
|
|
|
+ 1206 SymTab.InvalidType THEN
|
|
|
+ 1207 SemError(233);
|
|
|
+ 1208 t := SymTab.InvalidType;
|
|
|
+ 1209 QbeGen.CopyOp("0", q)
|
|
|
+ 1210 ELSE t := res;
|
|
|
+ 1211 QbeGen.CallEnd(TRUE, q)
|
|
|
+ 1212 END
|
|
|
+ 1213 ELSE
|
|
|
+ 1214 IF res #
|
|
|
+ 1215 SymTab.InvalidType THEN
|
|
|
+ 1216 SemError(233)
|
|
|
+ 1217 END;
|
|
|
+ 1218 t := SymTab.InvalidType;
|
|
|
+ 1219 QbeGen.CopyOp("0", q);
|
|
|
+ 1220 QbeGen.CallEnd(FALSE, q)
|
|
|
+ 1221 END; .) .
|
|
|
+ 1222 (* One actual: VAR formals take recorded designator addresses
|
|
|
+ 1223 (233 otherwise); value formals take converted expressions. *)
|
|
|
+ 1224 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
+ 1225 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
+ 1226 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ 1227 qe, qa, qt: QbeGen.QVal;
|
|
|
+ 1228 isV, conv: BOOLEAN; .)
|
|
|
+ 1229 = Expr<at, qe> (. IF ind THEN
|
|
|
+ 1230 ft :=
|
|
|
+ 1231 SymTab.ProcTypeParamType(pt,
|
|
|
+ 1232 i);
|
|
|
+ 1233 isV :=
|
|
|
+ 1234 SymTab.ProcTypeParamIsVar(pt,
|
|
|
+ 1235 i)
|
|
|
+ 1236 ELSIF methCls #
|
|
|
+ 1237 SymTab.InvalidType THEN
|
|
|
+ 1238 ft :=
|
|
|
+ 1239 SymTab.ClassMethodParamType(
|
|
|
+ 1240 methCls, pn, i);
|
|
|
+ 1241 isV :=
|
|
|
+ 1242 SymTab.ClassMethodParamIsVar(
|
|
|
+ 1243 methCls, pn, i)
|
|
|
+ 1244 ELSE
|
|
|
+ 1245 ft := SymTab.ParamType(pn, i);
|
|
|
+ 1246 isV := SymTab.ParamIsVar(pn, i)
|
|
|
+ 1247 END;
|
|
|
+ 1248 IF (at = SymTab.InvalidType)
|
|
|
+ 1249 OR (ft =
|
|
|
+ 1250 SymTab.InvalidType) THEN
|
|
|
+ 1251 ELSIF isV THEN
|
|
|
+ 1252 IF (SymTab.ClassOf(at)
|
|
|
+ 1253 = SymTab.ClChar)
|
|
|
+ 1254 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1255 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1256 = SymTab.ClChar)
|
|
|
+ 1257 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1258 (* 1-char string
|
|
|
+ 1259 literal passed to
|
|
|
+ 1260 a VAR ARRAY OF CHAR *)
|
|
|
+ 1261 QbeGen.DeclCharStr(qe,
|
|
|
+ 1262 qa);
|
|
|
+ 1263 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1264 "l") THEN
|
|
|
+ 1265 SemError(233)
|
|
|
+ 1266 END
|
|
|
+ 1267 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
+ 1268 qa) THEN
|
|
|
1269 SemError(233)
|
|
|
- 1270 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
- 1271 "l") THEN
|
|
|
+ 1270 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
+ 1271 ft) THEN
|
|
|
1272 SemError(233)
|
|
|
- 1273 END
|
|
|
- 1274 ELSE
|
|
|
- 1275 IF (SymTab.ClassOf(at)
|
|
|
- 1276 = SymTab.ClChar)
|
|
|
- 1277 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1278 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1279 = SymTab.ClChar)
|
|
|
- 1280 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1281 (* 1-char string
|
|
|
- 1282 literal passed to
|
|
|
- 1283 ARRAY OF CHAR *)
|
|
|
- 1284 QbeGen.DeclCharStr(qe,
|
|
|
- 1285 qa);
|
|
|
- 1286 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1287 "l") THEN
|
|
|
- 1288 SemError(233)
|
|
|
- 1289 END
|
|
|
- 1290 ELSIF NOT SymTab.Assignable(at,
|
|
|
- 1291 ft) THEN
|
|
|
- 1292 SemError(233)
|
|
|
- 1293 ELSE
|
|
|
- 1294 conv := (SymTab.ClassOf(
|
|
|
- 1295 ft) = SymTab.ClReal)
|
|
|
- 1296 AND SymTab.IsIntFamily(at);
|
|
|
- 1297 IF conv THEN
|
|
|
- 1298 QbeGen.ConvIR(qe, qt);
|
|
|
- 1299 IF NOT QbeGen.CallArg(qt,
|
|
|
- 1300 "d") THEN
|
|
|
- 1301 SemError(233)
|
|
|
- 1302 END
|
|
|
- 1303 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
- 1304 QbeGen.ArgClass(ft)) THEN
|
|
|
- 1305 SemError(233)
|
|
|
- 1306 END
|
|
|
- 1307 END
|
|
|
- 1308 END; .) .
|
|
|
- 1309 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1310 q, lThen, lElse, lEnd:
|
|
|
- 1311 QbeGen.QVal;
|
|
|
- 1312 hasElse: BOOLEAN; .)
|
|
|
- 1313 = "IF" (. hasElse := FALSE; .)
|
|
|
- 1314 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1315 SemError(214) END;
|
|
|
- 1316 QbeGen.NewLabel(lThen);
|
|
|
- 1317 QbeGen.NewLabel(lElse);
|
|
|
- 1318 QbeGen.NewLabel(lEnd);
|
|
|
- 1319 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 1320 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1321 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
- 1322 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1323 QbeGen.NewLabel(lElse); .)
|
|
|
- 1324 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1325 SemError(214) END;
|
|
|
- 1326 QbeGen.NewLabel(lThen);
|
|
|
- 1327 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 1328 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1329 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
- 1330 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1331 hasElse := TRUE; .)
|
|
|
- 1332 [ StatSeq ] ]
|
|
|
- 1333 "END" (. IF hasElse THEN
|
|
|
- 1334 QbeGen.EmitLabel(lEnd)
|
|
|
- 1335 ELSE QbeGen.EmitLabel(lElse);
|
|
|
- 1336 QbeGen.EmitLabel(lEnd)
|
|
|
- 1337 END; .) .
|
|
|
- 1338 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1339 q, lTop, lBody, lEnd:
|
|
|
- 1340 QbeGen.QVal; .)
|
|
|
- 1341 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
- 1342 QbeGen.NewLabel(lBody);
|
|
|
- 1343 QbeGen.NewLabel(lEnd);
|
|
|
- 1344 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1345 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1346 SemError(214) END;
|
|
|
- 1347 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
- 1348 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1349 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
- 1350 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1351 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1352 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 1353 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
- 1354 QbeGen.NewLabel(lEnd);
|
|
|
- 1355 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1356 [ StatSeq ]
|
|
|
- 1357 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1358 SemError(214) END;
|
|
|
- 1359 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
- 1360 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1361 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 1362 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
- 1363 QbeGen.NewLabel(lEnd);
|
|
|
- 1364 QbeGen.PushLoop(lEnd);
|
|
|
- 1365 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1366 [ StatSeq ]
|
|
|
- 1367 "END" (. QbeGen.Jmp(lTop);
|
|
|
- 1368 QbeGen.PopLoop;
|
|
|
- 1369 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1370 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
- 1371 Runtime direction would need a compare-select; the literal
|
|
|
- 1372 sign picks cslew/csegew at "DO" time. *)
|
|
|
- 1373 ForStat (. VAR lv: SymTab.Name;
|
|
|
- 1374 tlo, thi, tby:
|
|
|
- 1375 SymTab.TypeIndex;
|
|
|
- 1376 qlo, qhi, qby, qt, qk, qb:
|
|
|
- 1377 QbeGen.QVal;
|
|
|
- 1378 lTop, lBody, lEnd:
|
|
|
- 1379 QbeGen.QVal;
|
|
|
- 1380 by: INTEGER;
|
|
|
- 1381 ok: BOOLEAN; .)
|
|
|
- 1382 = "FOR" (. by := 1; .)
|
|
|
- 1383 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
- 1384 IF NOT ok THEN
|
|
|
- 1385 SemError(201)
|
|
|
- 1386 ELSIF (SymTab.SymKind(lv) #
|
|
|
- 1387 SymTab.KindVar)
|
|
|
- 1388 AND (SymTab.SymKind(lv) #
|
|
|
- 1389 SymTab.KindParam) THEN
|
|
|
- 1390 SemError(220); ok := FALSE
|
|
|
- 1391 ELSIF NOT SymTab.IsIntFamily(
|
|
|
- 1392 SymTab.SymType(lv)) THEN
|
|
|
+ 1273 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
+ 1274 "l") THEN
|
|
|
+ 1275 SemError(233)
|
|
|
+ 1276 END
|
|
|
+ 1277 ELSE
|
|
|
+ 1278 IF (SymTab.ClassOf(at)
|
|
|
+ 1279 = SymTab.ClChar)
|
|
|
+ 1280 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1281 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1282 = SymTab.ClChar)
|
|
|
+ 1283 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1284 (* 1-char string
|
|
|
+ 1285 literal passed to
|
|
|
+ 1286 ARRAY OF CHAR *)
|
|
|
+ 1287 QbeGen.DeclCharStr(qe,
|
|
|
+ 1288 qa);
|
|
|
+ 1289 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1290 "l") THEN
|
|
|
+ 1291 SemError(233)
|
|
|
+ 1292 END
|
|
|
+ 1293 ELSIF NOT SymTab.Assignable(at,
|
|
|
+ 1294 ft) THEN
|
|
|
+ 1295 SemError(233)
|
|
|
+ 1296 ELSE
|
|
|
+ 1297 conv := (SymTab.ClassOf(
|
|
|
+ 1298 ft) = SymTab.ClReal)
|
|
|
+ 1299 AND SymTab.IsIntFamily(at);
|
|
|
+ 1300 IF conv THEN
|
|
|
+ 1301 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1302 IF NOT QbeGen.CallArg(qt,
|
|
|
+ 1303 "d") THEN
|
|
|
+ 1304 SemError(233)
|
|
|
+ 1305 END
|
|
|
+ 1306 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
+ 1307 QbeGen.ArgClass(ft)) THEN
|
|
|
+ 1308 SemError(233)
|
|
|
+ 1309 END
|
|
|
+ 1310 END
|
|
|
+ 1311 END; .) .
|
|
|
+ 1312 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1313 q, lThen, lElse, lEnd:
|
|
|
+ 1314 QbeGen.QVal;
|
|
|
+ 1315 hasElse: BOOLEAN; .)
|
|
|
+ 1316 = "IF" (. hasElse := FALSE; .)
|
|
|
+ 1317 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1318 SemError(214) END;
|
|
|
+ 1319 QbeGen.NewLabel(lThen);
|
|
|
+ 1320 QbeGen.NewLabel(lElse);
|
|
|
+ 1321 QbeGen.NewLabel(lEnd);
|
|
|
+ 1322 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 1323 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 1324 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
+ 1325 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1326 QbeGen.NewLabel(lElse); .)
|
|
|
+ 1327 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1328 SemError(214) END;
|
|
|
+ 1329 QbeGen.NewLabel(lThen);
|
|
|
+ 1330 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 1331 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 1332 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
+ 1333 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1334 hasElse := TRUE; .)
|
|
|
+ 1335 [ StatSeq ] ]
|
|
|
+ 1336 "END" (. IF hasElse THEN
|
|
|
+ 1337 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1338 ELSE QbeGen.EmitLabel(lElse);
|
|
|
+ 1339 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1340 END; .) .
|
|
|
+ 1341 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1342 q, lTop, lBody, lEnd:
|
|
|
+ 1343 QbeGen.QVal; .)
|
|
|
+ 1344 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1345 QbeGen.NewLabel(lBody);
|
|
|
+ 1346 QbeGen.NewLabel(lEnd);
|
|
|
+ 1347 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1348 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1349 SemError(214) END;
|
|
|
+ 1350 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
+ 1351 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1352 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
+ 1353 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1354 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1355 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 1356 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1357 QbeGen.NewLabel(lEnd);
|
|
|
+ 1358 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1359 [ StatSeq ]
|
|
|
+ 1360 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1361 SemError(214) END;
|
|
|
+ 1362 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
+ 1363 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1364 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 1365 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1366 QbeGen.NewLabel(lEnd);
|
|
|
+ 1367 QbeGen.PushLoop(lEnd);
|
|
|
+ 1368 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1369 [ StatSeq ]
|
|
|
+ 1370 "END" (. QbeGen.Jmp(lTop);
|
|
|
+ 1371 QbeGen.PopLoop;
|
|
|
+ 1372 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1373 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
+ 1374 Runtime direction would need a compare-select; the literal
|
|
|
+ 1375 sign picks cslew/csegew at "DO" time. *)
|
|
|
+ 1376 ForStat (. VAR lv: SymTab.Name;
|
|
|
+ 1377 tlo, thi, tby:
|
|
|
+ 1378 SymTab.TypeIndex;
|
|
|
+ 1379 qlo, qhi, qby, qt, qk, qb:
|
|
|
+ 1380 QbeGen.QVal;
|
|
|
+ 1381 lTop, lBody, lEnd:
|
|
|
+ 1382 QbeGen.QVal;
|
|
|
+ 1383 by: INTEGER;
|
|
|
+ 1384 ok: BOOLEAN; .)
|
|
|
+ 1385 = "FOR" (. by := 1; .)
|
|
|
+ 1386 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
+ 1387 IF NOT ok THEN
|
|
|
+ 1388 SemError(201)
|
|
|
+ 1389 ELSIF (SymTab.SymKind(lv) #
|
|
|
+ 1390 SymTab.KindVar)
|
|
|
+ 1391 AND (SymTab.SymKind(lv) #
|
|
|
+ 1392 SymTab.KindParam) THEN
|
|
|
1393 SemError(220); ok := FALSE
|
|
|
- 1394 END; .)
|
|
|
- 1395 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
+ 1394 ELSIF NOT SymTab.IsIntFamily(
|
|
|
+ 1395 SymTab.SymType(lv)) THEN
|
|
|
1396 SemError(220); ok := FALSE
|
|
|
1397 END; .)
|
|
|
- 1398 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
+ 1398 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
1399 SemError(220); ok := FALSE
|
|
|
1400 END; .)
|
|
|
- 1401 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
- 1402 SymTab.InvalidType)
|
|
|
- 1403 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
- 1404 SemError(220); ok := FALSE
|
|
|
- 1405 END;
|
|
|
- 1406 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
- 1407 SemError(230); by := 1
|
|
|
- 1408 ELSIF by = 0 THEN
|
|
|
- 1409 SemError(220); by := 1
|
|
|
- 1410 END; .) ]
|
|
|
- 1411 "DO" (. IF ok THEN
|
|
|
- 1412 QbeGen.StoreVar(lv, qlo,
|
|
|
- 1413 FALSE) END;
|
|
|
- 1414 QbeGen.NewLabel(lTop);
|
|
|
- 1415 QbeGen.NewLabel(lBody);
|
|
|
- 1416 QbeGen.NewLabel(lEnd);
|
|
|
- 1417 QbeGen.EmitLabel(lTop);
|
|
|
- 1418 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
- 1419 QbeGen.NewTemp(qk);
|
|
|
- 1420 IF by > 0 THEN
|
|
|
- 1421 QbeGen.Op3("cslew", qk,
|
|
|
- 1422 qt, qhi, FALSE)
|
|
|
- 1423 ELSE QbeGen.Op3("csgew", qk,
|
|
|
- 1424 qt, qhi, FALSE)
|
|
|
- 1425 END;
|
|
|
- 1426 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
- 1427 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1428 [ StatSeq ]
|
|
|
- 1429 "END" (. IF ok THEN
|
|
|
- 1430 QbeGen.LoadVar(lv, FALSE,
|
|
|
- 1431 qt);
|
|
|
- 1432 QbeGen.IntStr(by, qb);
|
|
|
- 1433 QbeGen.NewTemp(qk);
|
|
|
- 1434 QbeGen.Op3("add", qk,
|
|
|
- 1435 qt, qb, FALSE);
|
|
|
- 1436 QbeGen.StoreVar(lv, qk,
|
|
|
- 1437 FALSE) END;
|
|
|
- 1438 QbeGen.Jmp(lTop);
|
|
|
- 1439 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1440 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
- 1441 qsel, lEnd: QbeGen.QVal; .)
|
|
|
- 1442 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
- 1443 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
- 1444 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
- 1445 [ "ELSE" [ StatSeq ] ]
|
|
|
- 1446 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1447 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 1448 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 1449 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 1450 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 1451 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1452 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
- 1453 = (. QbeGen.NewLabel(lBody);
|
|
|
- 1454 QbeGen.NewLabel(lAfter); .)
|
|
|
- 1455 CaseLabel<tsel, qsel, lBody>
|
|
|
- 1456 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
- 1457 ":" (. QbeGen.Jmp(lAfter);
|
|
|
- 1458 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1459 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
- 1460 QbeGen.EmitLabel(lAfter); .) .
|
|
|
- 1461 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1462 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 1463 q2, q3, qc, qd, qe:
|
|
|
- 1464 QbeGen.QVal;
|
|
|
- 1465 lNext: QbeGen.QVal; .)
|
|
|
- 1466 = Expr<t2, q2> (. IF (t2 #
|
|
|
- 1467 SymTab.InvalidType)
|
|
|
- 1468 AND (tsel #
|
|
|
- 1469 SymTab.InvalidType)
|
|
|
- 1470 AND ((SymTab.ClassOf(t2) =
|
|
|
- 1471 SymTab.ClSet)
|
|
|
- 1472 OR (SymTab.ClassOf(tsel) =
|
|
|
- 1473 SymTab.ClSet)) THEN
|
|
|
- 1474 SemError(230)
|
|
|
- 1475 ELSIF (t2 #
|
|
|
- 1476 SymTab.InvalidType)
|
|
|
- 1477 AND (tsel #
|
|
|
- 1478 SymTab.InvalidType)
|
|
|
- 1479 AND NOT SymTab.EqCheck(t2,
|
|
|
- 1480 tsel) THEN
|
|
|
- 1481 SemError(213) END;
|
|
|
- 1482 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
- 1483 SemError(230);
|
|
|
- 1484 QbeGen.CopyOp("0", q2)
|
|
|
- 1485 END;
|
|
|
- 1486 QbeGen.NewLabel(lNext);
|
|
|
- 1487 QbeGen.Cmp(SymTab.OpEq,
|
|
|
- 1488 qsel, q2, qc, FALSE);
|
|
|
- 1489 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
- 1490 QbeGen.EmitLabel(lNext); .)
|
|
|
- 1491 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
- 1492 SymTab.InvalidType)
|
|
|
- 1493 AND (tsel #
|
|
|
- 1494 SymTab.InvalidType)
|
|
|
- 1495 AND NOT SymTab.EqCheck(t3,
|
|
|
- 1496 tsel) THEN
|
|
|
- 1497 SemError(213) END;
|
|
|
- 1498 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
- 1499 SemError(230);
|
|
|
- 1500 QbeGen.CopyOp("0", q3)
|
|
|
- 1501 END;
|
|
|
- 1502 QbeGen.Cmp(SymTab.OpGe,
|
|
|
- 1503 qsel, q2, qc, FALSE);
|
|
|
- 1504 QbeGen.Cmp(SymTab.OpLe,
|
|
|
- 1505 qsel, q3, qd, FALSE);
|
|
|
- 1506 QbeGen.NewTemp(qe);
|
|
|
- 1507 QbeGen.Op3("and", qe, qc, qd,
|
|
|
- 1508 FALSE);
|
|
|
- 1509 QbeGen.NewLabel(lNext);
|
|
|
- 1510 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
- 1511 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
- 1512 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1513 q, qt: QbeGen.QVal;
|
|
|
- 1514 res: SymTab.TypeIndex;
|
|
|
- 1515 hadE, conv: BOOLEAN; .)
|
|
|
- 1516 = "RETURN" (. hadE := FALSE; .)
|
|
|
- 1517 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
- 1518 (. conv := FALSE;
|
|
|
- 1519 IF NOT SymTab.InProc() THEN
|
|
|
- 1520 SemError(232)
|
|
|
- 1521 ELSE res := SymTab.CurRes();
|
|
|
- 1522 IF NOT hadE THEN
|
|
|
- 1523 IF res #
|
|
|
- 1524 SymTab.InvalidType THEN
|
|
|
- 1525 SemError(232)
|
|
|
- 1526 ELSE QbeGen.EmitRet(q,
|
|
|
- 1527 FALSE)
|
|
|
- 1528 END
|
|
|
- 1529 ELSIF (res =
|
|
|
- 1530 SymTab.InvalidType)
|
|
|
- 1531 OR (t #
|
|
|
- 1532 SymTab.InvalidType)
|
|
|
- 1533 AND NOT SymTab.Assignable(t,
|
|
|
- 1534 res) THEN
|
|
|
- 1535 SemError(232)
|
|
|
- 1536 ELSE
|
|
|
- 1537 conv := (SymTab.ClassOf(
|
|
|
- 1538 res) = SymTab.ClReal)
|
|
|
- 1539 AND SymTab.IsIntFamily(t);
|
|
|
- 1540 IF conv THEN
|
|
|
- 1541 QbeGen.ConvIR(q, qt);
|
|
|
- 1542 QbeGen.EmitRet(qt, TRUE)
|
|
|
- 1543 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
- 1544 END
|
|
|
- 1545 END
|
|
|
- 1546 END; .) .
|
|
|
- 1547 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1548 q: QbeGen.QVal; .)
|
|
|
- 1549 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
- 1550 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 1551 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 1552 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 1553 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 1554 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 1555 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 1556 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 1557 (. VAR n, fn, mal: SymTab.Name;
|
|
|
- 1558 cls: INTEGER;
|
|
|
- 1559 ic: SymTab.TypeIndex;
|
|
|
- 1560 curT, it, eT, bt:
|
|
|
- 1561 SymTab.TypeIndex;
|
|
|
- 1562 iq, ql, qlo, qhi, qe:
|
|
|
- 1563 QbeGen.QVal;
|
|
|
- 1564 lo, hi: INTEGER;
|
|
|
- 1565 fo: INTEGER;
|
|
|
- 1566 isOpen: BOOLEAN;
|
|
|
- 1567 qb, cv: QbeGen.QVal; .)
|
|
|
- 1568 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
- 1569 QbeGen.CopyOp(n, qn);
|
|
|
- 1570 sfx := FALSE;
|
|
|
- 1571 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 1572 (* a bare method name inside
|
|
|
- 1573 a CLASS IMPLEMENTATION
|
|
|
- 1574 is a sibling call on
|
|
|
- 1575 THIS *)
|
|
|
- 1576 ic := SymTab.CurImplClass();
|
|
|
- 1577 IF (ic #
|
|
|
- 1578 SymTab.InvalidType)
|
|
|
- 1579 AND SymTab.MethodExists(ic, n) THEN
|
|
|
- 1580 sfx := FALSE;
|
|
|
- 1581 QbeGen.ThisBase(q);
|
|
|
- 1582 QbeGen.ArmRecv(q);
|
|
|
- 1583 methCls := ic;
|
|
|
- 1584 k := SymTab.KindProc;
|
|
|
- 1585 t := SymTab.InvalidType
|
|
|
- 1586 ELSE
|
|
|
- 1587 SemError(201);
|
|
|
- 1588 t :=
|
|
|
- 1589 SymTab.InvalidType;
|
|
|
- 1590 k := -1;
|
|
|
- 1591 QbeGen.CopyOp("0", q)
|
|
|
- 1592 END
|
|
|
- 1593 ELSE
|
|
|
- 1594 t := SymTab.SymType(n);
|
|
|
- 1595 k := SymTab.SymKind(n);
|
|
|
- 1596 IF k = SymTab.KindConst THEN
|
|
|
- 1597 IF SymTab.Equal(n,
|
|
|
- 1598 "TRUE") THEN
|
|
|
- 1599 t := SymTab.BoolType();
|
|
|
- 1600 QbeGen.CopyOp("1", q)
|
|
|
- 1601 ELSIF SymTab.Equal(n,
|
|
|
- 1602 "FALSE") THEN
|
|
|
- 1603 t := SymTab.BoolType();
|
|
|
- 1604 QbeGen.CopyOp("0", q)
|
|
|
- 1605 ELSIF SymTab.Equal(n,
|
|
|
- 1606 "NIL") THEN
|
|
|
+ 1401 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
+ 1402 SemError(220); ok := FALSE
|
|
|
+ 1403 END; .)
|
|
|
+ 1404 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
+ 1405 SymTab.InvalidType)
|
|
|
+ 1406 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
+ 1407 SemError(220); ok := FALSE
|
|
|
+ 1408 END;
|
|
|
+ 1409 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
+ 1410 SemError(230); by := 1
|
|
|
+ 1411 ELSIF by = 0 THEN
|
|
|
+ 1412 SemError(220); by := 1
|
|
|
+ 1413 END; .) ]
|
|
|
+ 1414 "DO" (. IF ok THEN
|
|
|
+ 1415 QbeGen.StoreVar(lv, qlo,
|
|
|
+ 1416 FALSE) END;
|
|
|
+ 1417 QbeGen.NewLabel(lTop);
|
|
|
+ 1418 QbeGen.NewLabel(lBody);
|
|
|
+ 1419 QbeGen.NewLabel(lEnd);
|
|
|
+ 1420 QbeGen.EmitLabel(lTop);
|
|
|
+ 1421 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
+ 1422 QbeGen.NewTemp(qk);
|
|
|
+ 1423 IF by > 0 THEN
|
|
|
+ 1424 QbeGen.Op3("cslew", qk,
|
|
|
+ 1425 qt, qhi, FALSE)
|
|
|
+ 1426 ELSE QbeGen.Op3("csgew", qk,
|
|
|
+ 1427 qt, qhi, FALSE)
|
|
|
+ 1428 END;
|
|
|
+ 1429 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
+ 1430 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1431 [ StatSeq ]
|
|
|
+ 1432 "END" (. IF ok THEN
|
|
|
+ 1433 QbeGen.LoadVar(lv, FALSE,
|
|
|
+ 1434 qt);
|
|
|
+ 1435 QbeGen.IntStr(by, qb);
|
|
|
+ 1436 QbeGen.NewTemp(qk);
|
|
|
+ 1437 QbeGen.Op3("add", qk,
|
|
|
+ 1438 qt, qb, FALSE);
|
|
|
+ 1439 QbeGen.StoreVar(lv, qk,
|
|
|
+ 1440 FALSE) END;
|
|
|
+ 1441 QbeGen.Jmp(lTop);
|
|
|
+ 1442 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1443 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
+ 1444 qsel, lEnd: QbeGen.QVal; .)
|
|
|
+ 1445 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
+ 1446 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
+ 1447 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
+ 1448 [ "ELSE" [ StatSeq ] ]
|
|
|
+ 1449 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1450 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 1451 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 1452 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 1453 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 1454 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1455 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
+ 1456 = (. QbeGen.NewLabel(lBody);
|
|
|
+ 1457 QbeGen.NewLabel(lAfter); .)
|
|
|
+ 1458 CaseLabel<tsel, qsel, lBody>
|
|
|
+ 1459 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
+ 1460 ":" (. QbeGen.Jmp(lAfter);
|
|
|
+ 1461 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1462 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
+ 1463 QbeGen.EmitLabel(lAfter); .) .
|
|
|
+ 1464 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1465 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 1466 q2, q3, qc, qd, qe:
|
|
|
+ 1467 QbeGen.QVal;
|
|
|
+ 1468 lNext: QbeGen.QVal; .)
|
|
|
+ 1469 = Expr<t2, q2> (. IF (t2 #
|
|
|
+ 1470 SymTab.InvalidType)
|
|
|
+ 1471 AND (tsel #
|
|
|
+ 1472 SymTab.InvalidType)
|
|
|
+ 1473 AND ((SymTab.ClassOf(t2) =
|
|
|
+ 1474 SymTab.ClSet)
|
|
|
+ 1475 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 1476 SymTab.ClSet)) THEN
|
|
|
+ 1477 SemError(230)
|
|
|
+ 1478 ELSIF (t2 #
|
|
|
+ 1479 SymTab.InvalidType)
|
|
|
+ 1480 AND (tsel #
|
|
|
+ 1481 SymTab.InvalidType)
|
|
|
+ 1482 AND NOT SymTab.EqCheck(t2,
|
|
|
+ 1483 tsel) THEN
|
|
|
+ 1484 SemError(213) END;
|
|
|
+ 1485 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
+ 1486 SemError(230);
|
|
|
+ 1487 QbeGen.CopyOp("0", q2)
|
|
|
+ 1488 END;
|
|
|
+ 1489 QbeGen.NewLabel(lNext);
|
|
|
+ 1490 QbeGen.Cmp(SymTab.OpEq,
|
|
|
+ 1491 qsel, q2, qc, FALSE);
|
|
|
+ 1492 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
+ 1493 QbeGen.EmitLabel(lNext); .)
|
|
|
+ 1494 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
+ 1495 SymTab.InvalidType)
|
|
|
+ 1496 AND (tsel #
|
|
|
+ 1497 SymTab.InvalidType)
|
|
|
+ 1498 AND NOT SymTab.EqCheck(t3,
|
|
|
+ 1499 tsel) THEN
|
|
|
+ 1500 SemError(213) END;
|
|
|
+ 1501 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
+ 1502 SemError(230);
|
|
|
+ 1503 QbeGen.CopyOp("0", q3)
|
|
|
+ 1504 END;
|
|
|
+ 1505 QbeGen.Cmp(SymTab.OpGe,
|
|
|
+ 1506 qsel, q2, qc, FALSE);
|
|
|
+ 1507 QbeGen.Cmp(SymTab.OpLe,
|
|
|
+ 1508 qsel, q3, qd, FALSE);
|
|
|
+ 1509 QbeGen.NewTemp(qe);
|
|
|
+ 1510 QbeGen.Op3("and", qe, qc, qd,
|
|
|
+ 1511 FALSE);
|
|
|
+ 1512 QbeGen.NewLabel(lNext);
|
|
|
+ 1513 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
+ 1514 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
+ 1515 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1516 q, qt: QbeGen.QVal;
|
|
|
+ 1517 res: SymTab.TypeIndex;
|
|
|
+ 1518 hadE, conv: BOOLEAN; .)
|
|
|
+ 1519 = "RETURN" (. hadE := FALSE; .)
|
|
|
+ 1520 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
+ 1521 (. conv := FALSE;
|
|
|
+ 1522 IF NOT SymTab.InProc() THEN
|
|
|
+ 1523 SemError(232)
|
|
|
+ 1524 ELSE res := SymTab.CurRes();
|
|
|
+ 1525 IF NOT hadE THEN
|
|
|
+ 1526 IF res #
|
|
|
+ 1527 SymTab.InvalidType THEN
|
|
|
+ 1528 SemError(232)
|
|
|
+ 1529 ELSE QbeGen.EmitRet(q,
|
|
|
+ 1530 FALSE)
|
|
|
+ 1531 END
|
|
|
+ 1532 ELSIF (res =
|
|
|
+ 1533 SymTab.InvalidType)
|
|
|
+ 1534 OR (t #
|
|
|
+ 1535 SymTab.InvalidType)
|
|
|
+ 1536 AND NOT SymTab.Assignable(t,
|
|
|
+ 1537 res) THEN
|
|
|
+ 1538 SemError(232)
|
|
|
+ 1539 ELSE
|
|
|
+ 1540 conv := (SymTab.ClassOf(
|
|
|
+ 1541 res) = SymTab.ClReal)
|
|
|
+ 1542 AND SymTab.IsIntFamily(t);
|
|
|
+ 1543 IF conv THEN
|
|
|
+ 1544 QbeGen.ConvIR(q, qt);
|
|
|
+ 1545 QbeGen.EmitRet(qt, TRUE)
|
|
|
+ 1546 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
+ 1547 END
|
|
|
+ 1548 END
|
|
|
+ 1549 END; .) .
|
|
|
+ 1550 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1551 q: QbeGen.QVal; .)
|
|
|
+ 1552 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
+ 1553 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 1554 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 1555 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 1556 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 1557 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 1558 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 1559 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 1560 (. VAR n, fn, mal: SymTab.Name;
|
|
|
+ 1561 cls: INTEGER;
|
|
|
+ 1562 ic: SymTab.TypeIndex;
|
|
|
+ 1563 curT, it, eT, bt:
|
|
|
+ 1564 SymTab.TypeIndex;
|
|
|
+ 1565 iq, ql, qlo, qhi, qe:
|
|
|
+ 1566 QbeGen.QVal;
|
|
|
+ 1567 lo, hi: INTEGER;
|
|
|
+ 1568 fo: INTEGER;
|
|
|
+ 1569 isOpen: BOOLEAN;
|
|
|
+ 1570 qb, cv: QbeGen.QVal; .)
|
|
|
+ 1571 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
+ 1572 QbeGen.CopyOp(n, qn);
|
|
|
+ 1573 sfx := FALSE;
|
|
|
+ 1574 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 1575 (* a bare method name inside
|
|
|
+ 1576 a CLASS IMPLEMENTATION
|
|
|
+ 1577 is a sibling call on
|
|
|
+ 1578 THIS *)
|
|
|
+ 1579 ic := SymTab.CurImplClass();
|
|
|
+ 1580 IF (ic #
|
|
|
+ 1581 SymTab.InvalidType)
|
|
|
+ 1582 AND SymTab.MethodExists(ic, n) THEN
|
|
|
+ 1583 sfx := FALSE;
|
|
|
+ 1584 QbeGen.ThisBase(q);
|
|
|
+ 1585 QbeGen.ArmRecv(q);
|
|
|
+ 1586 methCls := ic;
|
|
|
+ 1587 k := SymTab.KindProc;
|
|
|
+ 1588 t := SymTab.InvalidType
|
|
|
+ 1589 ELSE
|
|
|
+ 1590 SemError(201);
|
|
|
+ 1591 t :=
|
|
|
+ 1592 SymTab.InvalidType;
|
|
|
+ 1593 k := -1;
|
|
|
+ 1594 QbeGen.CopyOp("0", q)
|
|
|
+ 1595 END
|
|
|
+ 1596 ELSE
|
|
|
+ 1597 t := SymTab.SymType(n);
|
|
|
+ 1598 k := SymTab.SymKind(n);
|
|
|
+ 1599 IF k = SymTab.KindConst THEN
|
|
|
+ 1600 IF SymTab.Equal(n,
|
|
|
+ 1601 "TRUE") THEN
|
|
|
+ 1602 t := SymTab.BoolType();
|
|
|
+ 1603 QbeGen.CopyOp("1", q)
|
|
|
+ 1604 ELSIF SymTab.Equal(n,
|
|
|
+ 1605 "FALSE") THEN
|
|
|
+ 1606 t := SymTab.BoolType();
|
|
|
1607 QbeGen.CopyOp("0", q)
|
|
|
- 1608 ELSE
|
|
|
- 1609 cls :=
|
|
|
- 1610 SymTab.ClassOf(t);
|
|
|
- 1611 IF (t #
|
|
|
- 1612 SymTab.InvalidType)
|
|
|
- 1613 AND ((cls = SymTab.ClInt)
|
|
|
- 1614 OR (cls
|
|
|
- 1615 = SymTab.ClChar)
|
|
|
- 1616 OR (cls
|
|
|
- 1617 = SymTab.ClEnum)
|
|
|
- 1618 OR (cls
|
|
|
- 1619 = SymTab.ClReal)
|
|
|
- 1620 OR (cls
|
|
|
- 1621 = SymTab.ClNil)) THEN
|
|
|
- 1622 IF cls = SymTab.ClNil THEN
|
|
|
- 1623 QbeGen.CopyOp("0", q)
|
|
|
- 1624 ELSIF ((cls
|
|
|
- 1625 = SymTab.ClInt)
|
|
|
- 1626 OR (cls
|
|
|
- 1627 = SymTab.ClChar)
|
|
|
- 1628 OR (cls
|
|
|
- 1629 = SymTab.ClEnum))
|
|
|
- 1630 AND SymTab.GetSymVal(n, cv)
|
|
|
- 1631 AND QbeGen.IsImm(cv) THEN
|
|
|
- 1632 QbeGen.CopyOp(cv, q)
|
|
|
- 1633 ELSE
|
|
|
- 1634 QbeGen.LoadVar(n,
|
|
|
- 1635 cls = SymTab.ClReal,
|
|
|
- 1636 q)
|
|
|
- 1637 END
|
|
|
- 1638 ELSIF (cls = SymTab.ClArray)
|
|
|
- 1639 OR (cls = SymTab.ClStr)
|
|
|
- 1640 OR (cls = SymTab.ClUStr) THEN
|
|
|
- 1641 (* aggregate constant:
|
|
|
- 1642 its value IS the
|
|
|
- 1643 descriptor address *)
|
|
|
- 1644 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
- 1645 QbeGen.CopyOp(cv, q)
|
|
|
- 1646 ELSE
|
|
|
- 1647 QbeGen.CopyOp("0", q)
|
|
|
- 1648 END
|
|
|
- 1649 ELSE
|
|
|
- 1650 IF t #
|
|
|
- 1651 SymTab.InvalidType THEN
|
|
|
- 1652 SemError(230)
|
|
|
- 1653 END;
|
|
|
- 1654 QbeGen.CopyOp("0", q)
|
|
|
- 1655 END
|
|
|
- 1656 END
|
|
|
- 1657 ELSIF (k = SymTab.KindVar)
|
|
|
- 1658 OR (k = SymTab.KindParam) THEN
|
|
|
- 1659 cls :=
|
|
|
- 1660 SymTab.ClassOf(t);
|
|
|
- 1661 IF (cls = SymTab.ClInt)
|
|
|
- 1662 OR (cls = SymTab.ClBool)
|
|
|
- 1663 OR (cls = SymTab.ClChar)
|
|
|
- 1664 OR (cls = SymTab.ClUChar)
|
|
|
- 1665 OR (cls = SymTab.ClEnum)
|
|
|
- 1666 OR (cls
|
|
|
- 1667 = SymTab.ClReal) THEN
|
|
|
- 1668 QbeGen.LoadVar(n,
|
|
|
- 1669 cls = SymTab.ClReal, q)
|
|
|
- 1670 ELSIF (cls = SymTab.ClPtr)
|
|
|
- 1671 OR (cls = SymTab.ClProc) THEN
|
|
|
- 1672 QbeGen.LoadPtr(n, q)
|
|
|
- 1673 ELSIF cls = SymTab.ClLong THEN
|
|
|
- 1674 QbeGen.LoadLong(n, q)
|
|
|
- 1675 ELSIF (cls
|
|
|
- 1676 = SymTab.ClArray)
|
|
|
- 1677 OR (cls
|
|
|
- 1678 = SymTab.ClSet)
|
|
|
- 1679 OR (cls
|
|
|
- 1680 = SymTab.ClRecord)
|
|
|
- 1681 OR (cls
|
|
|
- 1682 = SymTab.ClUStr)
|
|
|
- 1683 OR (cls
|
|
|
- 1684 = SymTab.ClClass) THEN
|
|
|
- 1685 QbeGen.AddrOf(n, q)
|
|
|
- 1686 ELSE SemError(230);
|
|
|
- 1687 QbeGen.CopyOp("0", q)
|
|
|
- 1688 END
|
|
|
- 1689 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 1690 IF k = SymTab.KindImport THEN
|
|
|
- 1691 SemError(230)
|
|
|
- 1692 ELSIF k =
|
|
|
- 1693 SymTab.KindProc THEN
|
|
|
- 1694 (* bare procedure name:
|
|
|
- 1695 a following ArgList
|
|
|
- 1696 makes it a call;
|
|
|
- 1697 otherwise Fact
|
|
|
- 1698 reports 230 *)
|
|
|
- 1699 ELSE
|
|
|
- 1700 IF k = SymTab.KindField THEN
|
|
|
- 1701 IF QbeGen.TopWith(qb) THEN
|
|
|
- 1702 fo :=
|
|
|
- 1703 SymTab.FieldOffset(
|
|
|
- 1704 SymTab.FieldOwner(n),
|
|
|
- 1705 n);
|
|
|
- 1706 QbeGen.FieldAddr(qb,
|
|
|
- 1707 fo, q);
|
|
|
- 1708 sfx := TRUE
|
|
|
- 1709 ELSE SemError(230);
|
|
|
- 1710 QbeGen.CopyOp("0", q)
|
|
|
- 1711 END
|
|
|
- 1712 END
|
|
|
- 1713 END
|
|
|
- 1714 END
|
|
|
- 1715 END; .)
|
|
|
- 1716 { "[" Expr<it, iq>
|
|
|
- 1717 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1718 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1719 SymTab.ClArray THEN
|
|
|
- 1720 SemError(217);
|
|
|
- 1721 t := SymTab.InvalidType
|
|
|
- 1722 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 1723 AND (SymTab.ClassOf(it) #
|
|
|
- 1724 SymTab.ClChar) THEN
|
|
|
- 1725 SemError(218);
|
|
|
+ 1608 ELSIF SymTab.Equal(n,
|
|
|
+ 1609 "NIL") THEN
|
|
|
+ 1610 QbeGen.CopyOp("0", q)
|
|
|
+ 1611 ELSE
|
|
|
+ 1612 cls :=
|
|
|
+ 1613 SymTab.ClassOf(t);
|
|
|
+ 1614 IF (t #
|
|
|
+ 1615 SymTab.InvalidType)
|
|
|
+ 1616 AND ((cls = SymTab.ClInt)
|
|
|
+ 1617 OR (cls
|
|
|
+ 1618 = SymTab.ClChar)
|
|
|
+ 1619 OR (cls
|
|
|
+ 1620 = SymTab.ClEnum)
|
|
|
+ 1621 OR (cls
|
|
|
+ 1622 = SymTab.ClReal)
|
|
|
+ 1623 OR (cls
|
|
|
+ 1624 = SymTab.ClNil)) THEN
|
|
|
+ 1625 IF cls = SymTab.ClNil THEN
|
|
|
+ 1626 QbeGen.CopyOp("0", q)
|
|
|
+ 1627 ELSIF ((cls
|
|
|
+ 1628 = SymTab.ClInt)
|
|
|
+ 1629 OR (cls
|
|
|
+ 1630 = SymTab.ClChar)
|
|
|
+ 1631 OR (cls
|
|
|
+ 1632 = SymTab.ClEnum))
|
|
|
+ 1633 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 1634 AND QbeGen.IsImm(cv) THEN
|
|
|
+ 1635 QbeGen.CopyOp(cv, q)
|
|
|
+ 1636 ELSE
|
|
|
+ 1637 QbeGen.LoadVar(n,
|
|
|
+ 1638 cls = SymTab.ClReal,
|
|
|
+ 1639 q)
|
|
|
+ 1640 END
|
|
|
+ 1641 ELSIF (cls = SymTab.ClArray)
|
|
|
+ 1642 OR (cls = SymTab.ClRecord)
|
|
|
+ 1643 OR (cls = SymTab.ClClass)
|
|
|
+ 1644 OR (cls = SymTab.ClStr)
|
|
|
+ 1645 OR (cls = SymTab.ClUStr) THEN
|
|
|
+ 1646 (* aggregate constant:
|
|
|
+ 1647 its value IS the
|
|
|
+ 1648 descriptor address *)
|
|
|
+ 1649 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 1650 QbeGen.CopyOp(cv, q)
|
|
|
+ 1651 ELSE
|
|
|
+ 1652 QbeGen.CopyOp("0", q)
|
|
|
+ 1653 END
|
|
|
+ 1654 ELSE
|
|
|
+ 1655 IF t #
|
|
|
+ 1656 SymTab.InvalidType THEN
|
|
|
+ 1657 SemError(230)
|
|
|
+ 1658 END;
|
|
|
+ 1659 QbeGen.CopyOp("0", q)
|
|
|
+ 1660 END
|
|
|
+ 1661 END
|
|
|
+ 1662 ELSIF (k = SymTab.KindVar)
|
|
|
+ 1663 OR (k = SymTab.KindParam) THEN
|
|
|
+ 1664 cls :=
|
|
|
+ 1665 SymTab.ClassOf(t);
|
|
|
+ 1666 IF (cls = SymTab.ClInt)
|
|
|
+ 1667 OR (cls = SymTab.ClBool)
|
|
|
+ 1668 OR (cls = SymTab.ClChar)
|
|
|
+ 1669 OR (cls = SymTab.ClUChar)
|
|
|
+ 1670 OR (cls = SymTab.ClEnum)
|
|
|
+ 1671 OR (cls
|
|
|
+ 1672 = SymTab.ClReal) THEN
|
|
|
+ 1673 QbeGen.LoadVar(n,
|
|
|
+ 1674 cls = SymTab.ClReal, q)
|
|
|
+ 1675 ELSIF (cls = SymTab.ClPtr)
|
|
|
+ 1676 OR (cls = SymTab.ClProc) THEN
|
|
|
+ 1677 QbeGen.LoadPtr(n, q)
|
|
|
+ 1678 ELSIF cls = SymTab.ClLong THEN
|
|
|
+ 1679 QbeGen.LoadLong(n, q)
|
|
|
+ 1680 ELSIF (cls
|
|
|
+ 1681 = SymTab.ClArray)
|
|
|
+ 1682 OR (cls
|
|
|
+ 1683 = SymTab.ClSet)
|
|
|
+ 1684 OR (cls
|
|
|
+ 1685 = SymTab.ClRecord)
|
|
|
+ 1686 OR (cls
|
|
|
+ 1687 = SymTab.ClUStr)
|
|
|
+ 1688 OR (cls
|
|
|
+ 1689 = SymTab.ClClass) THEN
|
|
|
+ 1690 QbeGen.AddrOf(n, q)
|
|
|
+ 1691 ELSE SemError(230);
|
|
|
+ 1692 QbeGen.CopyOp("0", q)
|
|
|
+ 1693 END
|
|
|
+ 1694 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 1695 IF k = SymTab.KindImport THEN
|
|
|
+ 1696 SemError(230)
|
|
|
+ 1697 ELSIF k =
|
|
|
+ 1698 SymTab.KindProc THEN
|
|
|
+ 1699 (* bare procedure name:
|
|
|
+ 1700 a following ArgList
|
|
|
+ 1701 makes it a call;
|
|
|
+ 1702 otherwise Fact
|
|
|
+ 1703 reports 230 *)
|
|
|
+ 1704 ELSE
|
|
|
+ 1705 IF k = SymTab.KindField THEN
|
|
|
+ 1706 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 1707 fo :=
|
|
|
+ 1708 SymTab.FieldOffset(
|
|
|
+ 1709 SymTab.FieldOwner(n),
|
|
|
+ 1710 n);
|
|
|
+ 1711 QbeGen.FieldAddr(qb,
|
|
|
+ 1712 fo, q);
|
|
|
+ 1713 sfx := TRUE
|
|
|
+ 1714 ELSE SemError(230);
|
|
|
+ 1715 QbeGen.CopyOp("0", q)
|
|
|
+ 1716 END
|
|
|
+ 1717 END
|
|
|
+ 1718 END
|
|
|
+ 1719 END
|
|
|
+ 1720 END; .)
|
|
|
+ 1721 { "[" Expr<it, iq>
|
|
|
+ 1722 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1723 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1724 SymTab.ClArray THEN
|
|
|
+ 1725 SemError(217);
|
|
|
1726 t := SymTab.InvalidType
|
|
|
- 1727 ELSE
|
|
|
- 1728 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1729 isOpen :=
|
|
|
- 1730 SymTab.IsOpenArray(t);
|
|
|
- 1731 IF isOpen THEN
|
|
|
- 1732 QbeGen.CopyOp("0", qlo);
|
|
|
- 1733 IF SymTab.IsCharArray(t)
|
|
|
- 1734 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 1735 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 1736 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 1737 END
|
|
|
- 1738 ELSE
|
|
|
- 1739 lo := SymTab.ArrayLo(t);
|
|
|
- 1740 hi := SymTab.ArrayHi(t);
|
|
|
- 1741 IF SymTab.IsCharArray(t)
|
|
|
- 1742 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 1743 hi := hi + 1
|
|
|
- 1744 END;
|
|
|
- 1745 QbeGen.IntStr(lo, qlo);
|
|
|
- 1746 QbeGen.IntStr(hi, qhi)
|
|
|
- 1747 END;
|
|
|
- 1748 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1749 qhi);
|
|
|
- 1750 eT := SymTab.ArrayElem(t);
|
|
|
- 1751 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1752 t, qe);
|
|
|
- 1753 IF SymTab.ClassOf(eT) =
|
|
|
- 1754 SymTab.ClArray THEN
|
|
|
- 1755 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1756 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1757 END;
|
|
|
- 1758 t := eT; sfx := TRUE
|
|
|
- 1759 END; .)
|
|
|
- 1760 { "," Expr<it, iq>
|
|
|
- 1761 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1762 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1763 SymTab.ClArray THEN
|
|
|
- 1764 SemError(217);
|
|
|
- 1765 t := SymTab.InvalidType
|
|
|
- 1766 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 1767 AND (SymTab.ClassOf(it) #
|
|
|
- 1768 SymTab.ClChar) THEN
|
|
|
- 1769 SemError(218);
|
|
|
+ 1727 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 1728 AND (SymTab.ClassOf(it) #
|
|
|
+ 1729 SymTab.ClChar) THEN
|
|
|
+ 1730 SemError(218);
|
|
|
+ 1731 t := SymTab.InvalidType
|
|
|
+ 1732 ELSE
|
|
|
+ 1733 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1734 isOpen :=
|
|
|
+ 1735 SymTab.IsOpenArray(t);
|
|
|
+ 1736 IF isOpen THEN
|
|
|
+ 1737 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1738 IF SymTab.IsCharArray(t)
|
|
|
+ 1739 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1740 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 1741 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 1742 END
|
|
|
+ 1743 ELSE
|
|
|
+ 1744 lo := SymTab.ArrayLo(t);
|
|
|
+ 1745 hi := SymTab.ArrayHi(t);
|
|
|
+ 1746 IF SymTab.IsCharArray(t)
|
|
|
+ 1747 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1748 hi := hi + 1
|
|
|
+ 1749 END;
|
|
|
+ 1750 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1751 QbeGen.IntStr(hi, qhi)
|
|
|
+ 1752 END;
|
|
|
+ 1753 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1754 qhi);
|
|
|
+ 1755 eT := SymTab.ArrayElem(t);
|
|
|
+ 1756 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1757 t, qe);
|
|
|
+ 1758 IF SymTab.ClassOf(eT) =
|
|
|
+ 1759 SymTab.ClArray THEN
|
|
|
+ 1760 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1761 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1762 END;
|
|
|
+ 1763 t := eT; sfx := TRUE
|
|
|
+ 1764 END; .)
|
|
|
+ 1765 { "," Expr<it, iq>
|
|
|
+ 1766 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1767 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1768 SymTab.ClArray THEN
|
|
|
+ 1769 SemError(217);
|
|
|
1770 t := SymTab.InvalidType
|
|
|
- 1771 ELSE
|
|
|
- 1772 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1773 isOpen :=
|
|
|
- 1774 SymTab.IsOpenArray(t);
|
|
|
- 1775 IF isOpen THEN
|
|
|
- 1776 QbeGen.CopyOp("0", qlo);
|
|
|
- 1777 IF SymTab.IsCharArray(t)
|
|
|
- 1778 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 1779 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 1780 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 1781 END
|
|
|
- 1782 ELSE
|
|
|
- 1783 lo := SymTab.ArrayLo(t);
|
|
|
- 1784 hi := SymTab.ArrayHi(t);
|
|
|
- 1785 IF SymTab.IsCharArray(t)
|
|
|
- 1786 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 1787 hi := hi + 1
|
|
|
- 1788 END;
|
|
|
- 1789 QbeGen.IntStr(lo, qlo);
|
|
|
- 1790 QbeGen.IntStr(hi, qhi)
|
|
|
- 1791 END;
|
|
|
- 1792 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1793 qhi);
|
|
|
- 1794 eT := SymTab.ArrayElem(t);
|
|
|
- 1795 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1796 t, qe);
|
|
|
- 1797 IF SymTab.ClassOf(eT) =
|
|
|
- 1798 SymTab.ClArray THEN
|
|
|
- 1799 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1800 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1801 END;
|
|
|
- 1802 t := eT; sfx := TRUE
|
|
|
- 1803 END; .) }
|
|
|
- 1804 "]"
|
|
|
- 1805 | "." GetIdent<fn>
|
|
|
- 1806 (. IF k = SymTab.KindModule THEN
|
|
|
- 1807 (* qualified L.x: materialize
|
|
|
- 1808 the export, then load it *)
|
|
|
- 1809 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 1810 fn, mal) THEN
|
|
|
- 1811 SemError(201);
|
|
|
- 1812 t := SymTab.InvalidType;
|
|
|
- 1813 QbeGen.CopyOp("0", q)
|
|
|
- 1814 ELSE
|
|
|
- 1815 QbeGen.CopyOp(mal, qn);
|
|
|
- 1816 t := SymTab.SymType(mal);
|
|
|
- 1817 k := SymTab.SymKind(mal);
|
|
|
- 1818 sfx := FALSE;
|
|
|
- 1819 IF k = SymTab.KindProc THEN
|
|
|
- 1820 (* call: ArgList supplies
|
|
|
- 1821 the value *)
|
|
|
- 1822 QbeGen.CopyOp("0", q)
|
|
|
- 1823 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
- 1824 mal, t, k, q) THEN
|
|
|
- 1825 SemError(230);
|
|
|
- 1826 QbeGen.CopyOp("0", q)
|
|
|
- 1827 END
|
|
|
- 1828 END
|
|
|
- 1829 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 1830 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 1831 SymTab.ClRecord)
|
|
|
- 1832 AND (SymTab.ClassOf(t) #
|
|
|
- 1833 SymTab.ClClass) THEN
|
|
|
- 1834 SemError(215);
|
|
|
- 1835 t := SymTab.InvalidType
|
|
|
- 1836 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 1837 SymTab.ClClass)
|
|
|
- 1838 AND SymTab.MethodExists(t, fn) THEN
|
|
|
- 1839 (* obj.Method: bind the
|
|
|
- 1840 method and pass obj as
|
|
|
- 1841 the hidden receiver; q
|
|
|
- 1842 already holds the
|
|
|
- 1843 object's address *)
|
|
|
- 1844 QbeGen.ArmRecv(q);
|
|
|
- 1845 QbeGen.CopyOp(fn, n);
|
|
|
- 1846 QbeGen.CopyOp(fn, qn);
|
|
|
- 1847 methCls := t;
|
|
|
- 1848 k := SymTab.KindProc;
|
|
|
- 1849 t := SymTab.InvalidType
|
|
|
- 1850 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 1851 fn) THEN
|
|
|
- 1852 SemError(216);
|
|
|
- 1853 t := SymTab.InvalidType
|
|
|
- 1854 ELSE
|
|
|
- 1855 fo := SymTab.FieldOffset(t,
|
|
|
- 1856 fn);
|
|
|
- 1857 t := SymTab.FieldType(t, fn);
|
|
|
- 1858 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 1859 (* array fields are inline:
|
|
|
- 1860 the field address is the
|
|
|
- 1861 descriptor, like records *)
|
|
|
- 1862 QbeGen.CopyOp(qe, q);
|
|
|
- 1863 sfx := TRUE
|
|
|
- 1864 END; .)
|
|
|
- 1865 | "^"
|
|
|
- 1866 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1867 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1868 SymTab.ClPtr THEN
|
|
|
- 1869 SemError(219);
|
|
|
- 1870 t := SymTab.InvalidType
|
|
|
- 1871 ELSE
|
|
|
- 1872 bt := SymTab.PtrBase(t);
|
|
|
- 1873 IF bt = SymTab.InvalidType THEN
|
|
|
- 1874 ELSE
|
|
|
- 1875 IF sfx THEN
|
|
|
- 1876 QbeGen.ElemLoad(q, t,
|
|
|
- 1877 qb);
|
|
|
- 1878 QbeGen.CopyOp(qb, q)
|
|
|
- 1879 END;
|
|
|
- 1880 t := bt;
|
|
|
- 1881 (* q holds the pointee
|
|
|
- 1882 address: Fact loads
|
|
|
- 1883 scalars/pointers and uses
|
|
|
- 1884 the address for
|
|
|
- 1885 aggregates; the VAR-actual
|
|
|
- 1886 note is q itself. *)
|
|
|
- 1887 sfx := TRUE
|
|
|
- 1888 END
|
|
|
- 1889 END; .) } .
|
|
|
- 1890 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1891 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 1892 op: INTEGER;
|
|
|
- 1893 q2, qt, wl: QbeGen.QVal;
|
|
|
- 1894 isR: BOOLEAN; .)
|
|
|
- 1895 = SimExpr<t, q>
|
|
|
- 1896 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 1897 (. IF op = SymTab.OpIn THEN
|
|
|
- 1898 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 1899 IF (t = SymTab.InvalidType)
|
|
|
- 1900 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1901 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1902 ELSE
|
|
|
- 1903 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 1904 SymTab.SetCount(t2), qt);
|
|
|
- 1905 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1906 END
|
|
|
- 1907 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 1908 QbeGen.CopyOp("0", q)
|
|
|
- 1909 END
|
|
|
- 1910 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 1911 IF (t = SymTab.InvalidType)
|
|
|
- 1912 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1913 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1914 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 1915 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 1916 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 1917 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 1918 SemError(213); t := SymTab.InvalidType;
|
|
|
- 1919 QbeGen.CopyOp("0", q)
|
|
|
- 1920 ELSE
|
|
|
- 1921 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 1922 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1923 END
|
|
|
- 1924 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1925 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1926 QbeGen.CmpSet(op, q, q2,
|
|
|
- 1927 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 1928 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1929 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 1930 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 1931 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1932 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 1933 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 1934 IF SymTab.IsIntFamily(t) THEN
|
|
|
- 1935 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
- 1936 END;
|
|
|
- 1937 IF SymTab.IsIntFamily(t2) THEN
|
|
|
- 1938 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
- 1939 END;
|
|
|
- 1940 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
- 1941 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1942 ELSE
|
|
|
- 1943 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1944 t := SymTab.BoolType();
|
|
|
- 1945 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 1946 QbeGen.CopyOp(qt, q)
|
|
|
- 1947 END
|
|
|
- 1948 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 1949 QbeGen.CopyOp("0", q)
|
|
|
- 1950 END; .) ] .
|
|
|
- 1951 Rel<VAR op: INTEGER>
|
|
|
- 1952 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 1953 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 1954 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 1955 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 1956 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 1957 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 1958 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 1959 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1960 (. VAR t2, res2, lt, rt:
|
|
|
- 1961 SymTab.TypeIndex;
|
|
|
- 1962 op: INTEGER;
|
|
|
- 1963 q2, qt, wq, qf, q2a, q2b:
|
|
|
- 1964 QbeGen.QVal;
|
|
|
- 1965 neg, isR, isL, folded:
|
|
|
- 1966 BOOLEAN;
|
|
|
- 1967 lw, rw, mw: CARDINAL;
|
|
|
- 1968 lTrue, lNext, lDone, qr, qs:
|
|
|
- 1969 QbeGen.QVal; .)
|
|
|
- 1970 = (. neg := FALSE; .)
|
|
|
- 1971 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
- 1972 Term<t, q> (. IF neg THEN
|
|
|
- 1973 IF QbeGen.IsImm(q) THEN
|
|
|
- 1974 QbeGen.NegFold(q, q)
|
|
|
- 1975 ELSE QbeGen.NewTemp(qt);
|
|
|
- 1976 QbeGen.NegQ(q, qt,
|
|
|
- 1977 SymTab.ClassOf(t)
|
|
|
- 1978 = SymTab.ClReal);
|
|
|
- 1979 QbeGen.CopyOp(qt, q)
|
|
|
- 1980 END
|
|
|
- 1981 END; .)
|
|
|
- 1982 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
- 1983 QbeGen.DelayBegin END; .)
|
|
|
- 1984 Term<t2, q2> (. IF op = SymTab.OpOr THEN
|
|
|
- 1985 QbeGen.DelayEnd END; .)
|
|
|
- 1986 (. IF op = SymTab.OpOr THEN
|
|
|
- 1987 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 1988 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 1989 t := SymTab.BoolType()
|
|
|
- 1990 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1991 IF t # SymTab.InvalidType THEN
|
|
|
- 1992 QbeGen.Slot4(qs);
|
|
|
- 1993 QbeGen.NewLabel(lTrue);
|
|
|
- 1994 QbeGen.NewLabel(lNext);
|
|
|
- 1995 QbeGen.NewLabel(lDone);
|
|
|
- 1996 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
- 1997 QbeGen.EmitLabel(lTrue);
|
|
|
- 1998 QbeGen.StoreW(qs, "1");
|
|
|
- 1999 QbeGen.Jmp(lDone);
|
|
|
- 2000 QbeGen.EmitLabel(lNext);
|
|
|
- 2001 QbeGen.DelayFlush;
|
|
|
- 2002 QbeGen.StoreW(qs, q2);
|
|
|
- 2003 QbeGen.Jmp(lDone);
|
|
|
- 2004 QbeGen.EmitLabel(lDone);
|
|
|
- 2005 QbeGen.LoadW(qs, qr);
|
|
|
- 2006 QbeGen.CopyOp(qr, q)
|
|
|
- 2007 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 2008 END
|
|
|
- 2009 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2010 AND (SymTab.UStrCompat(t, t2)
|
|
|
- 2011 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2012 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
- 2013 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
- 2014 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
- 2015 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2016 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
- 2017 (* UString concatenation: a UCHAR operand becomes a
|
|
|
- 2018 1-codepoint UString; the result is a descriptor in the
|
|
|
- 2019 shim's concat buffer. Work on copies so neither
|
|
|
- 2020 operand is clobbered. *)
|
|
|
- 2021 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
- 2022 QbeGen.CopyOp(q, q2a)
|
|
|
- 2023 ELSE
|
|
|
- 2024 QbeGen.UStrFrom(q, q2a)
|
|
|
- 2025 END;
|
|
|
- 2026 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
- 2027 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
+ 1771 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 1772 AND (SymTab.ClassOf(it) #
|
|
|
+ 1773 SymTab.ClChar) THEN
|
|
|
+ 1774 SemError(218);
|
|
|
+ 1775 t := SymTab.InvalidType
|
|
|
+ 1776 ELSE
|
|
|
+ 1777 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1778 isOpen :=
|
|
|
+ 1779 SymTab.IsOpenArray(t);
|
|
|
+ 1780 IF isOpen THEN
|
|
|
+ 1781 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1782 IF SymTab.IsCharArray(t)
|
|
|
+ 1783 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1784 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 1785 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 1786 END
|
|
|
+ 1787 ELSE
|
|
|
+ 1788 lo := SymTab.ArrayLo(t);
|
|
|
+ 1789 hi := SymTab.ArrayHi(t);
|
|
|
+ 1790 IF SymTab.IsCharArray(t)
|
|
|
+ 1791 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1792 hi := hi + 1
|
|
|
+ 1793 END;
|
|
|
+ 1794 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1795 QbeGen.IntStr(hi, qhi)
|
|
|
+ 1796 END;
|
|
|
+ 1797 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1798 qhi);
|
|
|
+ 1799 eT := SymTab.ArrayElem(t);
|
|
|
+ 1800 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1801 t, qe);
|
|
|
+ 1802 IF SymTab.ClassOf(eT) =
|
|
|
+ 1803 SymTab.ClArray THEN
|
|
|
+ 1804 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1805 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1806 END;
|
|
|
+ 1807 t := eT; sfx := TRUE
|
|
|
+ 1808 END; .) }
|
|
|
+ 1809 "]"
|
|
|
+ 1810 | "." GetIdent<fn>
|
|
|
+ 1811 (. IF k = SymTab.KindModule THEN
|
|
|
+ 1812 (* qualified L.x: materialize
|
|
|
+ 1813 the export, then load it *)
|
|
|
+ 1814 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 1815 fn, mal) THEN
|
|
|
+ 1816 SemError(201);
|
|
|
+ 1817 t := SymTab.InvalidType;
|
|
|
+ 1818 QbeGen.CopyOp("0", q)
|
|
|
+ 1819 ELSE
|
|
|
+ 1820 QbeGen.CopyOp(mal, qn);
|
|
|
+ 1821 t := SymTab.SymType(mal);
|
|
|
+ 1822 k := SymTab.SymKind(mal);
|
|
|
+ 1823 sfx := FALSE;
|
|
|
+ 1824 IF k = SymTab.KindProc THEN
|
|
|
+ 1825 (* call: ArgList supplies
|
|
|
+ 1826 the value *)
|
|
|
+ 1827 QbeGen.CopyOp("0", q)
|
|
|
+ 1828 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
+ 1829 mal, t, k, q) THEN
|
|
|
+ 1830 SemError(230);
|
|
|
+ 1831 QbeGen.CopyOp("0", q)
|
|
|
+ 1832 END
|
|
|
+ 1833 END
|
|
|
+ 1834 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 1835 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 1836 SymTab.ClRecord)
|
|
|
+ 1837 AND (SymTab.ClassOf(t) #
|
|
|
+ 1838 SymTab.ClClass) THEN
|
|
|
+ 1839 SemError(215);
|
|
|
+ 1840 t := SymTab.InvalidType
|
|
|
+ 1841 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 1842 SymTab.ClClass)
|
|
|
+ 1843 AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ 1844 (* obj.Method: bind the
|
|
|
+ 1845 method and pass obj as
|
|
|
+ 1846 the hidden receiver; q
|
|
|
+ 1847 already holds the
|
|
|
+ 1848 object's address *)
|
|
|
+ 1849 QbeGen.ArmRecv(q);
|
|
|
+ 1850 QbeGen.CopyOp(fn, n);
|
|
|
+ 1851 QbeGen.CopyOp(fn, qn);
|
|
|
+ 1852 methCls := t;
|
|
|
+ 1853 k := SymTab.KindProc;
|
|
|
+ 1854 t := SymTab.InvalidType
|
|
|
+ 1855 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 1856 fn) THEN
|
|
|
+ 1857 SemError(216);
|
|
|
+ 1858 t := SymTab.InvalidType
|
|
|
+ 1859 ELSE
|
|
|
+ 1860 fo := SymTab.FieldOffset(t,
|
|
|
+ 1861 fn);
|
|
|
+ 1862 t := SymTab.FieldType(t, fn);
|
|
|
+ 1863 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 1864 (* array fields are inline:
|
|
|
+ 1865 the field address is the
|
|
|
+ 1866 descriptor, like records *)
|
|
|
+ 1867 QbeGen.CopyOp(qe, q);
|
|
|
+ 1868 sfx := TRUE
|
|
|
+ 1869 END; .)
|
|
|
+ 1870 | "^"
|
|
|
+ 1871 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1872 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1873 SymTab.ClPtr THEN
|
|
|
+ 1874 SemError(219);
|
|
|
+ 1875 t := SymTab.InvalidType
|
|
|
+ 1876 ELSE
|
|
|
+ 1877 bt := SymTab.PtrBase(t);
|
|
|
+ 1878 IF bt = SymTab.InvalidType THEN
|
|
|
+ 1879 ELSE
|
|
|
+ 1880 IF sfx THEN
|
|
|
+ 1881 QbeGen.ElemLoad(q, t,
|
|
|
+ 1882 qb);
|
|
|
+ 1883 QbeGen.CopyOp(qb, q)
|
|
|
+ 1884 END;
|
|
|
+ 1885 t := bt;
|
|
|
+ 1886 (* q holds the pointee
|
|
|
+ 1887 address: Fact loads
|
|
|
+ 1888 scalars/pointers and uses
|
|
|
+ 1889 the address for
|
|
|
+ 1890 aggregates; the VAR-actual
|
|
|
+ 1891 note is q itself. *)
|
|
|
+ 1892 sfx := TRUE
|
|
|
+ 1893 END
|
|
|
+ 1894 END; .) } .
|
|
|
+ 1895 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1896 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 1897 op: INTEGER;
|
|
|
+ 1898 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 1899 isR: BOOLEAN; .)
|
|
|
+ 1900 = SimExpr<t, q>
|
|
|
+ 1901 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 1902 (. IF op = SymTab.OpIn THEN
|
|
|
+ 1903 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 1904 IF (t = SymTab.InvalidType)
|
|
|
+ 1905 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1906 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1907 ELSE
|
|
|
+ 1908 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 1909 SymTab.SetCount(t2), qt);
|
|
|
+ 1910 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1911 END
|
|
|
+ 1912 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 1913 QbeGen.CopyOp("0", q)
|
|
|
+ 1914 END
|
|
|
+ 1915 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 1916 IF (t = SymTab.InvalidType)
|
|
|
+ 1917 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1918 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1919 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 1920 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 1921 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 1922 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 1923 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1924 QbeGen.CopyOp("0", q)
|
|
|
+ 1925 ELSE
|
|
|
+ 1926 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 1927 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1928 END
|
|
|
+ 1929 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1930 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1931 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 1932 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 1933 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1934 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 1935 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 1936 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1937 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 1938 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 1939 IF SymTab.IsIntFamily(t) THEN
|
|
|
+ 1940 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
+ 1941 END;
|
|
|
+ 1942 IF SymTab.IsIntFamily(t2) THEN
|
|
|
+ 1943 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
+ 1944 END;
|
|
|
+ 1945 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
+ 1946 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1947 ELSE
|
|
|
+ 1948 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1949 t := SymTab.BoolType();
|
|
|
+ 1950 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 1951 QbeGen.CopyOp(qt, q)
|
|
|
+ 1952 END
|
|
|
+ 1953 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1954 QbeGen.CopyOp("0", q)
|
|
|
+ 1955 END; .) ] .
|
|
|
+ 1956 Rel<VAR op: INTEGER>
|
|
|
+ 1957 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 1958 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 1959 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 1960 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 1961 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 1962 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 1963 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 1964 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1965 (. VAR t2, res2, lt, rt:
|
|
|
+ 1966 SymTab.TypeIndex;
|
|
|
+ 1967 op: INTEGER;
|
|
|
+ 1968 q2, qt, wq, qf, q2a, q2b:
|
|
|
+ 1969 QbeGen.QVal;
|
|
|
+ 1970 neg, isR, isL, folded:
|
|
|
+ 1971 BOOLEAN;
|
|
|
+ 1972 lw, rw, mw: CARDINAL;
|
|
|
+ 1973 lTrue, lNext, lDone, qr, qs:
|
|
|
+ 1974 QbeGen.QVal; .)
|
|
|
+ 1975 = (. neg := FALSE; .)
|
|
|
+ 1976 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
+ 1977 Term<t, q> (. IF neg THEN
|
|
|
+ 1978 IF QbeGen.IsImm(q) THEN
|
|
|
+ 1979 QbeGen.NegFold(q, q)
|
|
|
+ 1980 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 1981 QbeGen.NegQ(q, qt,
|
|
|
+ 1982 SymTab.ClassOf(t)
|
|
|
+ 1983 = SymTab.ClReal);
|
|
|
+ 1984 QbeGen.CopyOp(qt, q)
|
|
|
+ 1985 END
|
|
|
+ 1986 END; .)
|
|
|
+ 1987 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
+ 1988 QbeGen.DelayBegin END; .)
|
|
|
+ 1989 Term<t2, q2> (. IF op = SymTab.OpOr THEN
|
|
|
+ 1990 QbeGen.DelayEnd END; .)
|
|
|
+ 1991 (. IF op = SymTab.OpOr THEN
|
|
|
+ 1992 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 1993 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 1994 t := SymTab.BoolType()
|
|
|
+ 1995 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1996 IF t # SymTab.InvalidType THEN
|
|
|
+ 1997 QbeGen.Slot4(qs);
|
|
|
+ 1998 QbeGen.NewLabel(lTrue);
|
|
|
+ 1999 QbeGen.NewLabel(lNext);
|
|
|
+ 2000 QbeGen.NewLabel(lDone);
|
|
|
+ 2001 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
+ 2002 QbeGen.EmitLabel(lTrue);
|
|
|
+ 2003 QbeGen.StoreW(qs, "1");
|
|
|
+ 2004 QbeGen.Jmp(lDone);
|
|
|
+ 2005 QbeGen.EmitLabel(lNext);
|
|
|
+ 2006 QbeGen.DelayFlush;
|
|
|
+ 2007 QbeGen.StoreW(qs, q2);
|
|
|
+ 2008 QbeGen.Jmp(lDone);
|
|
|
+ 2009 QbeGen.EmitLabel(lDone);
|
|
|
+ 2010 QbeGen.LoadW(qs, qr);
|
|
|
+ 2011 QbeGen.CopyOp(qr, q)
|
|
|
+ 2012 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 2013 END
|
|
|
+ 2014 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2015 AND (SymTab.UStrCompat(t, t2)
|
|
|
+ 2016 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2017 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
+ 2018 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
+ 2019 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
+ 2020 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2021 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
+ 2022 (* UString concatenation: a UCHAR operand becomes a
|
|
|
+ 2023 1-codepoint UString; the result is a descriptor in the
|
|
|
+ 2024 shim's concat buffer. Work on copies so neither
|
|
|
+ 2025 operand is clobbered. *)
|
|
|
+ 2026 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
+ 2027 QbeGen.CopyOp(q, q2a)
|
|
|
2028 ELSE
|
|
|
- 2029 QbeGen.UStrFrom(q2, q2b);
|
|
|
- 2030 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
- 2031 END;
|
|
|
- 2032 t := SymTab.NewUStr();
|
|
|
- 2033 QbeGen.CopyOp(qt, q)
|
|
|
- 2034 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2035 AND (SymTab.StrCompat(t, t2)
|
|
|
- 2036 OR (SymTab.IsStrType(t)
|
|
|
- 2037 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 2038 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 2039 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 2040 (* string concatenation; a CHAR operand becomes a
|
|
|
- 2041 1-character string literal *)
|
|
|
- 2042 IF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2043 QbeGen.StrCat(q, q2, qt)
|
|
|
- 2044 ELSIF SymTab.IsStrType(t) THEN
|
|
|
- 2045 QbeGen.DeclCharStr(q2, qs);
|
|
|
- 2046 QbeGen.StrCat(q, qs, qt)
|
|
|
- 2047 ELSE
|
|
|
- 2048 QbeGen.DeclCharStr(q, qs);
|
|
|
- 2049 QbeGen.StrCat(qs, q2, qt)
|
|
|
- 2050 END;
|
|
|
- 2051 t := SymTab.NewStr();
|
|
|
- 2052 QbeGen.CopyOp(qt, q)
|
|
|
- 2053 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2054 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2055 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2056 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2057 mw := lw;
|
|
|
- 2058 IF rw > mw THEN mw := rw END;
|
|
|
- 2059 IF op = SymTab.OpAdd THEN
|
|
|
- 2060 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 2061 ELSE
|
|
|
- 2062 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 2063 END;
|
|
|
- 2064 t := SymTab.NewSet(
|
|
|
- 2065 SymTab.NewSubR(0,
|
|
|
- 2066 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2067 QbeGen.CopyOp(qt, q)
|
|
|
- 2068 ELSE
|
|
|
- 2069 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 2070 lt := t; rt := t2; t := res2
|
|
|
- 2071 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2072 IF t # SymTab.InvalidType THEN
|
|
|
- 2073 isL := SymTab.IsLongFamily(t);
|
|
|
- 2074 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2075 folded := FALSE;
|
|
|
- 2076 IF (NOT isL) AND (NOT isR)
|
|
|
- 2077 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2078 IF op = SymTab.OpAdd THEN
|
|
|
- 2079 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 2080 ELSE
|
|
|
- 2081 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 2082 END
|
|
|
- 2083 END;
|
|
|
- 2084 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2085 ELSE
|
|
|
- 2086 IF isL THEN
|
|
|
- 2087 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 2088 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 2089 END;
|
|
|
- 2090 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 2091 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 2092 END;
|
|
|
- 2093 QbeGen.NewTemp(qt);
|
|
|
- 2094 IF op = SymTab.OpAdd THEN
|
|
|
- 2095 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 2096 ELSE
|
|
|
- 2097 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 2098 END
|
|
|
- 2099 ELSE
|
|
|
- 2100 QbeGen.NewTemp(qt);
|
|
|
- 2101 IF op = SymTab.OpAdd THEN
|
|
|
- 2102 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 2103 ELSE
|
|
|
- 2104 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 2105 END
|
|
|
- 2106 END;
|
|
|
- 2107 QbeGen.CopyOp(qt, q)
|
|
|
- 2108 END
|
|
|
- 2109 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2110 END
|
|
|
- 2111 END; .) } .
|
|
|
- 2112 AddOp<VAR op: INTEGER>
|
|
|
- 2113 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 2114 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 2115 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 2116 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2117 (. VAR t2, res2, lt, rt:
|
|
|
- 2118 SymTab.TypeIndex;
|
|
|
- 2119 op: INTEGER;
|
|
|
- 2120 q2, qt, wq, qf:
|
|
|
- 2121 QbeGen.QVal;
|
|
|
- 2122 isR, isL, folded: BOOLEAN;
|
|
|
- 2123 lw, rw, mw: CARDINAL;
|
|
|
- 2124 lNext, lFalse, lDone, qr, qs:
|
|
|
- 2125 QbeGen.QVal; .)
|
|
|
- 2126 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
- 2127 QbeGen.DelayBegin END; .)
|
|
|
- 2128 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
- 2129 QbeGen.DelayEnd END; .)
|
|
|
- 2130 (. IF op = SymTab.OpAnd THEN
|
|
|
- 2131 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 2132 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2133 t := SymTab.BoolType()
|
|
|
- 2134 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2135 IF t # SymTab.InvalidType THEN
|
|
|
- 2136 QbeGen.Slot4(qs);
|
|
|
- 2137 QbeGen.NewLabel(lNext);
|
|
|
- 2138 QbeGen.NewLabel(lFalse);
|
|
|
- 2139 QbeGen.NewLabel(lDone);
|
|
|
- 2140 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
- 2141 QbeGen.EmitLabel(lNext);
|
|
|
- 2142 QbeGen.DelayFlush;
|
|
|
- 2143 QbeGen.StoreW(qs, q2);
|
|
|
- 2144 QbeGen.Jmp(lDone);
|
|
|
- 2145 QbeGen.EmitLabel(lFalse);
|
|
|
- 2146 QbeGen.StoreW(qs, "0");
|
|
|
- 2147 QbeGen.Jmp(lDone);
|
|
|
- 2148 QbeGen.EmitLabel(lDone);
|
|
|
- 2149 QbeGen.LoadW(qs, qr);
|
|
|
- 2150 QbeGen.CopyOp(qr, q)
|
|
|
- 2151 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 2152 END
|
|
|
- 2153 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2154 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2155 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2156 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2157 mw := lw;
|
|
|
- 2158 IF rw > mw THEN mw := rw END;
|
|
|
- 2159 IF op = SymTab.OpTimes THEN
|
|
|
- 2160 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 2161 ELSE
|
|
|
- 2162 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 2163 END;
|
|
|
- 2164 t := SymTab.NewSet(
|
|
|
- 2165 SymTab.NewSubR(0,
|
|
|
- 2166 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2167 QbeGen.CopyOp(qt, q)
|
|
|
- 2168 ELSE
|
|
|
- 2169 IF SymTab.ArithCheck(t, t2,
|
|
|
- 2170 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 2171 res2) THEN
|
|
|
- 2172 lt := t; rt := t2; t := res2
|
|
|
- 2173 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2174 IF t # SymTab.InvalidType THEN
|
|
|
- 2175 isL := SymTab.IsLongFamily(t);
|
|
|
- 2176 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2177 folded := FALSE;
|
|
|
- 2178 IF (NOT isL) AND (NOT isR)
|
|
|
- 2179 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2180 IF op = SymTab.OpTimes THEN
|
|
|
- 2181 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 2182 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 2183 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 2184 ELSIF op = SymTab.OpMod THEN
|
|
|
- 2185 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 2186 END
|
|
|
- 2187 END;
|
|
|
- 2188 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2189 ELSE
|
|
|
- 2190 IF isL THEN
|
|
|
- 2191 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 2192 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 2193 END;
|
|
|
- 2194 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 2195 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 2196 END;
|
|
|
- 2197 QbeGen.NewTemp(qt);
|
|
|
- 2198 IF op = SymTab.OpTimes THEN
|
|
|
- 2199 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 2200 ELSIF (op = SymTab.OpDiv)
|
|
|
- 2201 OR (op = SymTab.OpSlash) THEN
|
|
|
- 2202 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 2203 ELSE
|
|
|
- 2204 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 2205 END
|
|
|
- 2206 ELSE
|
|
|
- 2207 QbeGen.NewTemp(qt);
|
|
|
- 2208 IF op = SymTab.OpTimes THEN
|
|
|
- 2209 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 2210 ELSIF (op = SymTab.OpDiv)
|
|
|
- 2211 OR (op = SymTab.OpSlash) THEN
|
|
|
- 2212 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 2213 ELSE
|
|
|
- 2214 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 2215 END
|
|
|
- 2216 END;
|
|
|
- 2217 QbeGen.CopyOp(qt, q)
|
|
|
- 2218 END
|
|
|
- 2219 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2220 END
|
|
|
- 2221 END; .) } .
|
|
|
- 2222 MulOp<VAR op: INTEGER>
|
|
|
- 2223 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 2224 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 2225 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 2226 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 2227 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 2228 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2229 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 2230 et, dt, t2, st, ct2:
|
|
|
- 2231 SymTab.TypeIndex;
|
|
|
- 2232 dk: INTEGER;
|
|
|
- 2233 qd, q2, sq, qa, qm0, qr:
|
|
|
- 2234 QbeGen.QVal;
|
|
|
- 2235 qn, vn: SymTab.Name;
|
|
|
- 2236 vt: SymTab.TypeIndex;
|
|
|
- 2237 c1, c2: INTEGER;
|
|
|
- 2238 called, isHigh, sfx, isCh,
|
|
|
- 2239 isU, uok, isStr: BOOLEAN;
|
|
|
- 2240 ucp: INTEGER; .)
|
|
|
- 2241 = integer (. LexString(s);
|
|
|
- 2242 QbeGen.NormInt(s, q);
|
|
|
- 2243 t := SymTab.IntType(); .)
|
|
|
- 2244 | charConst (. LexString(s);
|
|
|
- 2245 QbeGen.NormLit(s, q, isCh);
|
|
|
- 2246 t := SymTab.CharType(); .)
|
|
|
- 2247 | real (. LexString(s);
|
|
|
- 2248 QbeGen.NormReal(s, q);
|
|
|
- 2249 t := SymTab.RealType(); .)
|
|
|
- 2250 | string (. LexString(s);
|
|
|
- 2251 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2252 t := SymTab.CharType();
|
|
|
- 2253 QbeGen.IntStr(
|
|
|
- 2254 QbeGen.CharVal(s), q)
|
|
|
- 2255 ELSE t := SymTab.NewStr();
|
|
|
- 2256 QbeGen.DeclStr(s, q);
|
|
|
- 2257 (* a literal's value IS its
|
|
|
- 2258 static descriptor address *)
|
|
|
- 2259 QbeGen.NoteAddr(q, q)
|
|
|
- 2260 END; .)
|
|
|
- 2261 | ustring (. LexString(s);
|
|
|
- 2262 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 2263 uok);
|
|
|
- 2264 IF NOT uok THEN
|
|
|
- 2265 SemError(234);
|
|
|
- 2266 t := SymTab.InvalidType
|
|
|
- 2267 ELSIF isU THEN
|
|
|
- 2268 t := SymTab.UCharType();
|
|
|
- 2269 QbeGen.IntStr(ucp, q)
|
|
|
- 2270 ELSE
|
|
|
- 2271 t := SymTab.NewUStr();
|
|
|
- 2272 QbeGen.NoteAddr(q, q)
|
|
|
- 2273 END; .)
|
|
|
- 2274 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
- 2275 t := dt;
|
|
|
- 2276 IF sfx THEN
|
|
|
- 2277 IF dt =
|
|
|
- 2278 SymTab.InvalidType THEN
|
|
|
- 2279 QbeGen.CopyOp("0", q)
|
|
|
- 2280 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 2281 SymTab.ClRecord)
|
|
|
- 2282 OR (SymTab.ClassOf(dt) =
|
|
|
- 2283 SymTab.ClSet)
|
|
|
- 2284 OR (SymTab.ClassOf(dt) =
|
|
|
- 2285 SymTab.ClArray)
|
|
|
- 2286 OR (SymTab.ClassOf(dt) =
|
|
|
- 2287 SymTab.ClClass) THEN
|
|
|
- 2288 QbeGen.CopyOp(qd, q)
|
|
|
- 2289 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 2290 q)
|
|
|
- 2291 END
|
|
|
- 2292 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 2293 END;
|
|
|
- 2294 IF (dk = SymTab.KindVar)
|
|
|
- 2295 OR (dk = SymTab.KindParam)
|
|
|
- 2296 OR (dk =
|
|
|
- 2297 SymTab.KindField) THEN
|
|
|
- 2298 IF sfx THEN
|
|
|
- 2299 QbeGen.NoteAddr(q, qd)
|
|
|
- 2300 ELSE
|
|
|
- 2301 QbeGen.AddrOf(qn, qa);
|
|
|
- 2302 QbeGen.NoteAddr(q, qa)
|
|
|
- 2303 END
|
|
|
- 2304 ELSIF sfx
|
|
|
- 2305 AND (dt #
|
|
|
- 2306 SymTab.InvalidType)
|
|
|
- 2307 AND ((SymTab.ClassOf(dt) =
|
|
|
- 2308 SymTab.ClArray)
|
|
|
- 2309 OR (SymTab.ClassOf(dt) =
|
|
|
- 2310 SymTab.ClSet)
|
|
|
- 2311 OR (SymTab.ClassOf(dt) =
|
|
|
- 2312 SymTab.ClRecord)) THEN
|
|
|
- 2313 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2314 END; .)
|
|
|
- 2315 [ TypedBraceLit<dt, q> (. t := dt; .) ]
|
|
|
- 2316 [ ArgList<qn, dt, qd, TRUE, methCls, ct2, q2, called>
|
|
|
- 2317 (. t := ct2;
|
|
|
- 2318 QbeGen.CopyOp(q2, q); .) ]
|
|
|
- 2319 (. IF NOT called
|
|
|
- 2320 AND (dk = SymTab.KindProc) THEN
|
|
|
- 2321 (* bare zero-arg function
|
|
|
- 2322 call (parentheses may be
|
|
|
- 2323 omitted); a proper or
|
|
|
- 2324 parameterised proc here
|
|
|
- 2325 is 230 *)
|
|
|
- 2326 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 2327 AND (SymTab.ProcRes(qn) #
|
|
|
- 2328 SymTab.InvalidType) THEN
|
|
|
- 2329 QbeGen.Mangled(qn,
|
|
|
- 2330 SymTab.ProcUid(qn), qm0);
|
|
|
- 2331 QbeGen.CallBegin(qm0,
|
|
|
- 2332 SymTab.ProcRes(qn),
|
|
|
- 2333 SymTab.ProcDepthOf(qn),
|
|
|
- 2334 SymTab.IsExternal(qn));
|
|
|
- 2335 QbeGen.CallEnd(TRUE, q);
|
|
|
- 2336 t := SymTab.ProcRes(qn)
|
|
|
- 2337 ELSE
|
|
|
- 2338 (* procedure used as a
|
|
|
- 2339 value (assign to a
|
|
|
- 2340 procedure variable):
|
|
|
- 2341 its code address *)
|
|
|
- 2342 t := SymTab.ProcTypeOf(qn);
|
|
|
- 2343 QbeGen.Mangled(qn,
|
|
|
- 2344 SymTab.ProcUid(qn), qm0);
|
|
|
- 2345 QbeGen.ProcAddr(qm0, q)
|
|
|
- 2346 END
|
|
|
- 2347 END; .)
|
|
|
- 2348 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 2349 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 2350 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
- 2351 isU := FALSE; .)
|
|
|
- 2352 | string (. LexString(s);
|
|
|
- 2353 isStr := TRUE;
|
|
|
- 2354 isU := FALSE;
|
|
|
- 2355 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2356 dt := SymTab.CharType();
|
|
|
- 2357 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 2358 qd)
|
|
|
- 2359 ELSE
|
|
|
- 2360 dt := SymTab.NewStr();
|
|
|
- 2361 QbeGen.DeclStr(s, qd);
|
|
|
- 2362 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2363 END;
|
|
|
- 2364 dk := -1;
|
|
|
- 2365 qn[0] := CHR(0); .)
|
|
|
- 2366 | ustring (. LexString(s);
|
|
|
- 2367 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
- 2368 uok);
|
|
|
- 2369 isStr := FALSE;
|
|
|
- 2370 IF NOT uok THEN
|
|
|
- 2371 SemError(234);
|
|
|
- 2372 dt := SymTab.InvalidType
|
|
|
- 2373 ELSIF isU THEN
|
|
|
- 2374 (* one codepoint: a UCHAR;
|
|
|
- 2375 LEN is 1, HIGH is 0 *)
|
|
|
- 2376 dt := SymTab.UCharType();
|
|
|
- 2377 QbeGen.IntStr(ucp, qd)
|
|
|
- 2378 ELSE
|
|
|
- 2379 dt := SymTab.NewUStr();
|
|
|
- 2380 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2381 END;
|
|
|
- 2382 dk := -1;
|
|
|
- 2383 qn[0] := CHR(0); .) )
|
|
|
- 2384 ")"
|
|
|
- 2385 (. IF (dt # SymTab.InvalidType)
|
|
|
- 2386 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
- 2387 (* UString: the count is
|
|
|
- 2388 the descriptor header *)
|
|
|
- 2389 IF isHigh THEN
|
|
|
- 2390 QbeGen.UStrLen(qd, qr);
|
|
|
- 2391 QbeGen.DecQ(qr)
|
|
|
- 2392 ELSE
|
|
|
- 2393 QbeGen.UStrLen(qd, qr)
|
|
|
- 2394 END;
|
|
|
- 2395 t := SymTab.IntType();
|
|
|
- 2396 QbeGen.CopyOp(qr, q)
|
|
|
- 2397 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 2398 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
- 2399 (* single UCHAR codepoint *)
|
|
|
- 2400 IF isHigh THEN
|
|
|
- 2401 QbeGen.CopyOp("0", qr)
|
|
|
- 2402 ELSE
|
|
|
- 2403 QbeGen.CopyOp("1", qr)
|
|
|
- 2404 END;
|
|
|
- 2405 t := SymTab.IntType();
|
|
|
- 2406 QbeGen.CopyOp(qr, q)
|
|
|
- 2407 ELSIF isStr THEN
|
|
|
- 2408 (* fold: content length at
|
|
|
- 2409 compile time *)
|
|
|
- 2410 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2411 c1 := 1
|
|
|
- 2412 ELSE
|
|
|
- 2413 c1 :=
|
|
|
- 2414 SymTab.StrLen(s) - 2
|
|
|
- 2415 END;
|
|
|
- 2416 IF isHigh THEN
|
|
|
- 2417 DEC(c1)
|
|
|
- 2418 END;
|
|
|
- 2419 QbeGen.IntStr(c1, qr);
|
|
|
- 2420 t := SymTab.IntType();
|
|
|
- 2421 QbeGen.CopyOp(qr, q)
|
|
|
- 2422 ELSIF dt = SymTab.InvalidType THEN
|
|
|
- 2423 t := SymTab.InvalidType;
|
|
|
- 2424 QbeGen.CopyOp("0", q)
|
|
|
- 2425 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 2426 SymTab.ClArray THEN
|
|
|
- 2427 SemError(217);
|
|
|
+ 2029 QbeGen.UStrFrom(q, q2a)
|
|
|
+ 2030 END;
|
|
|
+ 2031 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
+ 2032 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
+ 2033 ELSE
|
|
|
+ 2034 QbeGen.UStrFrom(q2, q2b);
|
|
|
+ 2035 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
+ 2036 END;
|
|
|
+ 2037 t := SymTab.NewUStr();
|
|
|
+ 2038 QbeGen.CopyOp(qt, q)
|
|
|
+ 2039 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2040 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 2041 OR (SymTab.IsStrType(t)
|
|
|
+ 2042 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 2043 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 2044 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 2045 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 2046 1-character string literal *)
|
|
|
+ 2047 IF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2048 QbeGen.StrCat(q, q2, qt)
|
|
|
+ 2049 ELSIF SymTab.IsStrType(t) THEN
|
|
|
+ 2050 QbeGen.DeclCharStr(q2, qs);
|
|
|
+ 2051 QbeGen.StrCat(q, qs, qt)
|
|
|
+ 2052 ELSE
|
|
|
+ 2053 QbeGen.DeclCharStr(q, qs);
|
|
|
+ 2054 QbeGen.StrCat(qs, q2, qt)
|
|
|
+ 2055 END;
|
|
|
+ 2056 t := SymTab.NewStr();
|
|
|
+ 2057 QbeGen.CopyOp(qt, q)
|
|
|
+ 2058 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2059 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2060 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2061 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2062 mw := lw;
|
|
|
+ 2063 IF rw > mw THEN mw := rw END;
|
|
|
+ 2064 IF op = SymTab.OpAdd THEN
|
|
|
+ 2065 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 2066 ELSE
|
|
|
+ 2067 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 2068 END;
|
|
|
+ 2069 t := SymTab.NewSet(
|
|
|
+ 2070 SymTab.NewSubR(0,
|
|
|
+ 2071 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2072 QbeGen.CopyOp(qt, q)
|
|
|
+ 2073 ELSE
|
|
|
+ 2074 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 2075 lt := t; rt := t2; t := res2
|
|
|
+ 2076 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2077 IF t # SymTab.InvalidType THEN
|
|
|
+ 2078 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2079 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2080 folded := FALSE;
|
|
|
+ 2081 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2082 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2083 IF op = SymTab.OpAdd THEN
|
|
|
+ 2084 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 2085 ELSE
|
|
|
+ 2086 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 2087 END
|
|
|
+ 2088 END;
|
|
|
+ 2089 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2090 ELSE
|
|
|
+ 2091 IF isL THEN
|
|
|
+ 2092 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 2093 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 2094 END;
|
|
|
+ 2095 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 2096 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 2097 END;
|
|
|
+ 2098 QbeGen.NewTemp(qt);
|
|
|
+ 2099 IF op = SymTab.OpAdd THEN
|
|
|
+ 2100 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 2101 ELSE
|
|
|
+ 2102 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 2103 END
|
|
|
+ 2104 ELSE
|
|
|
+ 2105 QbeGen.NewTemp(qt);
|
|
|
+ 2106 IF op = SymTab.OpAdd THEN
|
|
|
+ 2107 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 2108 ELSE
|
|
|
+ 2109 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 2110 END
|
|
|
+ 2111 END;
|
|
|
+ 2112 QbeGen.CopyOp(qt, q)
|
|
|
+ 2113 END
|
|
|
+ 2114 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2115 END
|
|
|
+ 2116 END; .) } .
|
|
|
+ 2117 AddOp<VAR op: INTEGER>
|
|
|
+ 2118 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 2119 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 2120 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 2121 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2122 (. VAR t2, res2, lt, rt:
|
|
|
+ 2123 SymTab.TypeIndex;
|
|
|
+ 2124 op: INTEGER;
|
|
|
+ 2125 q2, qt, wq, qf:
|
|
|
+ 2126 QbeGen.QVal;
|
|
|
+ 2127 isR, isL, folded: BOOLEAN;
|
|
|
+ 2128 lw, rw, mw: CARDINAL;
|
|
|
+ 2129 lNext, lFalse, lDone, qr, qs:
|
|
|
+ 2130 QbeGen.QVal; .)
|
|
|
+ 2131 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 2132 QbeGen.DelayBegin END; .)
|
|
|
+ 2133 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 2134 QbeGen.DelayEnd END; .)
|
|
|
+ 2135 (. IF op = SymTab.OpAnd THEN
|
|
|
+ 2136 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 2137 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2138 t := SymTab.BoolType()
|
|
|
+ 2139 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2140 IF t # SymTab.InvalidType THEN
|
|
|
+ 2141 QbeGen.Slot4(qs);
|
|
|
+ 2142 QbeGen.NewLabel(lNext);
|
|
|
+ 2143 QbeGen.NewLabel(lFalse);
|
|
|
+ 2144 QbeGen.NewLabel(lDone);
|
|
|
+ 2145 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
+ 2146 QbeGen.EmitLabel(lNext);
|
|
|
+ 2147 QbeGen.DelayFlush;
|
|
|
+ 2148 QbeGen.StoreW(qs, q2);
|
|
|
+ 2149 QbeGen.Jmp(lDone);
|
|
|
+ 2150 QbeGen.EmitLabel(lFalse);
|
|
|
+ 2151 QbeGen.StoreW(qs, "0");
|
|
|
+ 2152 QbeGen.Jmp(lDone);
|
|
|
+ 2153 QbeGen.EmitLabel(lDone);
|
|
|
+ 2154 QbeGen.LoadW(qs, qr);
|
|
|
+ 2155 QbeGen.CopyOp(qr, q)
|
|
|
+ 2156 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 2157 END
|
|
|
+ 2158 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2159 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2160 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2161 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2162 mw := lw;
|
|
|
+ 2163 IF rw > mw THEN mw := rw END;
|
|
|
+ 2164 IF op = SymTab.OpTimes THEN
|
|
|
+ 2165 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 2166 ELSE
|
|
|
+ 2167 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 2168 END;
|
|
|
+ 2169 t := SymTab.NewSet(
|
|
|
+ 2170 SymTab.NewSubR(0,
|
|
|
+ 2171 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2172 QbeGen.CopyOp(qt, q)
|
|
|
+ 2173 ELSE
|
|
|
+ 2174 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 2175 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 2176 res2) THEN
|
|
|
+ 2177 lt := t; rt := t2; t := res2
|
|
|
+ 2178 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2179 IF t # SymTab.InvalidType THEN
|
|
|
+ 2180 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2181 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2182 folded := FALSE;
|
|
|
+ 2183 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2184 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2185 IF op = SymTab.OpTimes THEN
|
|
|
+ 2186 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 2187 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 2188 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 2189 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 2190 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 2191 END
|
|
|
+ 2192 END;
|
|
|
+ 2193 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2194 ELSE
|
|
|
+ 2195 IF isL THEN
|
|
|
+ 2196 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 2197 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 2198 END;
|
|
|
+ 2199 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 2200 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 2201 END;
|
|
|
+ 2202 QbeGen.NewTemp(qt);
|
|
|
+ 2203 IF op = SymTab.OpTimes THEN
|
|
|
+ 2204 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 2205 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 2206 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 2207 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 2208 ELSE
|
|
|
+ 2209 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 2210 END
|
|
|
+ 2211 ELSE
|
|
|
+ 2212 QbeGen.NewTemp(qt);
|
|
|
+ 2213 IF op = SymTab.OpTimes THEN
|
|
|
+ 2214 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 2215 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 2216 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 2217 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 2218 ELSE
|
|
|
+ 2219 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 2220 END
|
|
|
+ 2221 END;
|
|
|
+ 2222 QbeGen.CopyOp(qt, q)
|
|
|
+ 2223 END
|
|
|
+ 2224 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2225 END
|
|
|
+ 2226 END; .) } .
|
|
|
+ 2227 MulOp<VAR op: INTEGER>
|
|
|
+ 2228 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 2229 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 2230 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 2231 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 2232 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 2233 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2234 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 2235 et, dt, t2, st, ct2:
|
|
|
+ 2236 SymTab.TypeIndex;
|
|
|
+ 2237 dk: INTEGER;
|
|
|
+ 2238 qd, q2, sq, qa, qm0, qr:
|
|
|
+ 2239 QbeGen.QVal;
|
|
|
+ 2240 qn, vn: SymTab.Name;
|
|
|
+ 2241 vt: SymTab.TypeIndex;
|
|
|
+ 2242 c1, c2: INTEGER;
|
|
|
+ 2243 called, isHigh, sfx, isCh,
|
|
|
+ 2244 isU, uok, isStr: BOOLEAN;
|
|
|
+ 2245 ucp: INTEGER; .)
|
|
|
+ 2246 = integer (. LexString(s);
|
|
|
+ 2247 QbeGen.NormInt(s, q);
|
|
|
+ 2248 t := SymTab.IntType(); .)
|
|
|
+ 2249 | charConst (. LexString(s);
|
|
|
+ 2250 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 2251 t := SymTab.CharType(); .)
|
|
|
+ 2252 | real (. LexString(s);
|
|
|
+ 2253 QbeGen.NormReal(s, q);
|
|
|
+ 2254 t := SymTab.RealType(); .)
|
|
|
+ 2255 | string (. LexString(s);
|
|
|
+ 2256 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2257 t := SymTab.CharType();
|
|
|
+ 2258 QbeGen.IntStr(
|
|
|
+ 2259 QbeGen.CharVal(s), q)
|
|
|
+ 2260 ELSE t := SymTab.NewStr();
|
|
|
+ 2261 QbeGen.DeclStr(s, q);
|
|
|
+ 2262 (* a literal's value IS its
|
|
|
+ 2263 static descriptor address *)
|
|
|
+ 2264 QbeGen.NoteAddr(q, q)
|
|
|
+ 2265 END; .)
|
|
|
+ 2266 | ustring (. LexString(s);
|
|
|
+ 2267 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 2268 uok);
|
|
|
+ 2269 IF NOT uok THEN
|
|
|
+ 2270 SemError(234);
|
|
|
+ 2271 t := SymTab.InvalidType
|
|
|
+ 2272 ELSIF isU THEN
|
|
|
+ 2273 t := SymTab.UCharType();
|
|
|
+ 2274 QbeGen.IntStr(ucp, q)
|
|
|
+ 2275 ELSE
|
|
|
+ 2276 t := SymTab.NewUStr();
|
|
|
+ 2277 QbeGen.NoteAddr(q, q)
|
|
|
+ 2278 END; .)
|
|
|
+ 2279 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
+ 2280 t := dt;
|
|
|
+ 2281 IF sfx THEN
|
|
|
+ 2282 IF dt =
|
|
|
+ 2283 SymTab.InvalidType THEN
|
|
|
+ 2284 QbeGen.CopyOp("0", q)
|
|
|
+ 2285 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 2286 SymTab.ClRecord)
|
|
|
+ 2287 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2288 SymTab.ClSet)
|
|
|
+ 2289 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2290 SymTab.ClArray)
|
|
|
+ 2291 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2292 SymTab.ClClass) THEN
|
|
|
+ 2293 QbeGen.CopyOp(qd, q)
|
|
|
+ 2294 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 2295 q)
|
|
|
+ 2296 END
|
|
|
+ 2297 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 2298 END;
|
|
|
+ 2299 IF (dk = SymTab.KindVar)
|
|
|
+ 2300 OR (dk = SymTab.KindParam)
|
|
|
+ 2301 OR (dk =
|
|
|
+ 2302 SymTab.KindField) THEN
|
|
|
+ 2303 IF sfx THEN
|
|
|
+ 2304 QbeGen.NoteAddr(q, qd)
|
|
|
+ 2305 ELSE
|
|
|
+ 2306 QbeGen.AddrOf(qn, qa);
|
|
|
+ 2307 QbeGen.NoteAddr(q, qa)
|
|
|
+ 2308 END
|
|
|
+ 2309 ELSIF sfx
|
|
|
+ 2310 AND (dt #
|
|
|
+ 2311 SymTab.InvalidType)
|
|
|
+ 2312 AND ((SymTab.ClassOf(dt) =
|
|
|
+ 2313 SymTab.ClArray)
|
|
|
+ 2314 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2315 SymTab.ClSet)
|
|
|
+ 2316 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2317 SymTab.ClRecord)) THEN
|
|
|
+ 2318 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2319 END; .)
|
|
|
+ 2320 [ TypedBraceLit<dt, q> (. t := dt; .) ]
|
|
|
+ 2321 [ ArgList<qn, dt, qd, TRUE, methCls, ct2, q2, called>
|
|
|
+ 2322 (. t := ct2;
|
|
|
+ 2323 QbeGen.CopyOp(q2, q); .) ]
|
|
|
+ 2324 (. IF NOT called
|
|
|
+ 2325 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 2326 (* bare zero-arg function
|
|
|
+ 2327 call (parentheses may be
|
|
|
+ 2328 omitted); a proper or
|
|
|
+ 2329 parameterised proc here
|
|
|
+ 2330 is 230 *)
|
|
|
+ 2331 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 2332 AND (SymTab.ProcRes(qn) #
|
|
|
+ 2333 SymTab.InvalidType) THEN
|
|
|
+ 2334 QbeGen.Mangled(qn,
|
|
|
+ 2335 SymTab.ProcUid(qn), qm0);
|
|
|
+ 2336 QbeGen.CallBegin(qm0,
|
|
|
+ 2337 SymTab.ProcRes(qn),
|
|
|
+ 2338 SymTab.ProcDepthOf(qn),
|
|
|
+ 2339 SymTab.IsExternal(qn));
|
|
|
+ 2340 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 2341 t := SymTab.ProcRes(qn)
|
|
|
+ 2342 ELSE
|
|
|
+ 2343 (* procedure used as a
|
|
|
+ 2344 value (assign to a
|
|
|
+ 2345 procedure variable):
|
|
|
+ 2346 its code address *)
|
|
|
+ 2347 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 2348 QbeGen.Mangled(qn,
|
|
|
+ 2349 SymTab.ProcUid(qn), qm0);
|
|
|
+ 2350 QbeGen.ProcAddr(qm0, q)
|
|
|
+ 2351 END
|
|
|
+ 2352 END; .)
|
|
|
+ 2353 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 2354 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 2355 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
+ 2356 isU := FALSE; .)
|
|
|
+ 2357 | string (. LexString(s);
|
|
|
+ 2358 isStr := TRUE;
|
|
|
+ 2359 isU := FALSE;
|
|
|
+ 2360 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2361 dt := SymTab.CharType();
|
|
|
+ 2362 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 2363 qd)
|
|
|
+ 2364 ELSE
|
|
|
+ 2365 dt := SymTab.NewStr();
|
|
|
+ 2366 QbeGen.DeclStr(s, qd);
|
|
|
+ 2367 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2368 END;
|
|
|
+ 2369 dk := -1;
|
|
|
+ 2370 qn[0] := CHR(0); .)
|
|
|
+ 2371 | ustring (. LexString(s);
|
|
|
+ 2372 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
+ 2373 uok);
|
|
|
+ 2374 isStr := FALSE;
|
|
|
+ 2375 IF NOT uok THEN
|
|
|
+ 2376 SemError(234);
|
|
|
+ 2377 dt := SymTab.InvalidType
|
|
|
+ 2378 ELSIF isU THEN
|
|
|
+ 2379 (* one codepoint: a UCHAR;
|
|
|
+ 2380 LEN is 1, HIGH is 0 *)
|
|
|
+ 2381 dt := SymTab.UCharType();
|
|
|
+ 2382 QbeGen.IntStr(ucp, qd)
|
|
|
+ 2383 ELSE
|
|
|
+ 2384 dt := SymTab.NewUStr();
|
|
|
+ 2385 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2386 END;
|
|
|
+ 2387 dk := -1;
|
|
|
+ 2388 qn[0] := CHR(0); .) )
|
|
|
+ 2389 ")"
|
|
|
+ 2390 (. IF (dt # SymTab.InvalidType)
|
|
|
+ 2391 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
+ 2392 (* UString: the count is
|
|
|
+ 2393 the descriptor header *)
|
|
|
+ 2394 IF isHigh THEN
|
|
|
+ 2395 QbeGen.UStrLen(qd, qr);
|
|
|
+ 2396 QbeGen.DecQ(qr)
|
|
|
+ 2397 ELSE
|
|
|
+ 2398 QbeGen.UStrLen(qd, qr)
|
|
|
+ 2399 END;
|
|
|
+ 2400 t := SymTab.IntType();
|
|
|
+ 2401 QbeGen.CopyOp(qr, q)
|
|
|
+ 2402 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 2403 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
+ 2404 (* single UCHAR codepoint *)
|
|
|
+ 2405 IF isHigh THEN
|
|
|
+ 2406 QbeGen.CopyOp("0", qr)
|
|
|
+ 2407 ELSE
|
|
|
+ 2408 QbeGen.CopyOp("1", qr)
|
|
|
+ 2409 END;
|
|
|
+ 2410 t := SymTab.IntType();
|
|
|
+ 2411 QbeGen.CopyOp(qr, q)
|
|
|
+ 2412 ELSIF isStr THEN
|
|
|
+ 2413 (* fold: content length at
|
|
|
+ 2414 compile time *)
|
|
|
+ 2415 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2416 c1 := 1
|
|
|
+ 2417 ELSE
|
|
|
+ 2418 c1 :=
|
|
|
+ 2419 SymTab.StrLen(s) - 2
|
|
|
+ 2420 END;
|
|
|
+ 2421 IF isHigh THEN
|
|
|
+ 2422 DEC(c1)
|
|
|
+ 2423 END;
|
|
|
+ 2424 QbeGen.IntStr(c1, qr);
|
|
|
+ 2425 t := SymTab.IntType();
|
|
|
+ 2426 QbeGen.CopyOp(qr, q)
|
|
|
+ 2427 ELSIF dt = SymTab.InvalidType THEN
|
|
|
2428 t := SymTab.InvalidType;
|
|
|
2429 QbeGen.CopyOp("0", q)
|
|
|
- 2430 ELSE
|
|
|
- 2431 IF isHigh THEN
|
|
|
- 2432 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2433 QbeGen.OpenHi(qd, qr)
|
|
|
- 2434 ELSE
|
|
|
- 2435 QbeGen.IntStr(
|
|
|
- 2436 SymTab.ArrayHi(dt), qr)
|
|
|
- 2437 END
|
|
|
- 2438 ELSE
|
|
|
- 2439 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2440 QbeGen.LoadCount(qd, qr)
|
|
|
- 2441 ELSE
|
|
|
- 2442 QbeGen.IntStr(VAL(
|
|
|
- 2443 INTEGER,
|
|
|
- 2444 SymTab.ArrayLen(dt)),
|
|
|
- 2445 qr)
|
|
|
- 2446 END
|
|
|
- 2447 END;
|
|
|
- 2448 t := SymTab.IntType();
|
|
|
- 2449 QbeGen.CopyOp(qr, q)
|
|
|
- 2450 END; .)
|
|
|
- 2451 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2452 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2453 t := SymTab.InvalidType;
|
|
|
- 2454 QbeGen.CopyOp("0", q)
|
|
|
- 2455 ELSE
|
|
|
- 2456 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 2457 SymTab.ObjectSize(dt)), q);
|
|
|
- 2458 t := SymTab.IntType()
|
|
|
- 2459 END; .)
|
|
|
- 2460 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2461 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2462 t := SymTab.InvalidType;
|
|
|
- 2463 QbeGen.CopyOp("0", q)
|
|
|
- 2464 ELSE
|
|
|
- 2465 IF sfx THEN
|
|
|
- 2466 QbeGen.CopyOp(qd, q)
|
|
|
- 2467 ELSIF (dk = SymTab.KindVar)
|
|
|
- 2468 OR (dk = SymTab.KindParam) THEN
|
|
|
- 2469 QbeGen.AddrOf(qn, q)
|
|
|
- 2470 ELSE SemError(230);
|
|
|
- 2471 QbeGen.CopyOp("0", q)
|
|
|
- 2472 END;
|
|
|
- 2473 t := SymTab.AddrType()
|
|
|
- 2474 END; .)
|
|
|
- 2475 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 2476 (. IF (et # SymTab.InvalidType)
|
|
|
- 2477 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2478 SemError(211) END;
|
|
|
- 2479 t := SymTab.CharType(); .)
|
|
|
- 2480 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 2481 (. IF et # SymTab.InvalidType THEN
|
|
|
- 2482 IF (SymTab.ClassOf(et) #
|
|
|
- 2483 SymTab.ClChar)
|
|
|
- 2484 AND (SymTab.ClassOf(et) #
|
|
|
- 2485 SymTab.ClBool)
|
|
|
- 2486 AND (SymTab.ClassOf(et) #
|
|
|
- 2487 SymTab.ClEnum)
|
|
|
- 2488 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2489 SemError(211) END
|
|
|
- 2490 END;
|
|
|
- 2491 t := SymTab.IntType(); .)
|
|
|
- 2492 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 2493 (. QbeGen.CapQ(q, qa);
|
|
|
- 2494 QbeGen.CopyOp(qa, q);
|
|
|
- 2495 t := SymTab.CharType(); .)
|
|
|
- 2496 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 2497 (. (* UCHR: the UCHAR constructor.
|
|
|
- 2498 CHAR -> UCHAR (identity);
|
|
|
- 2499 INTEGER familly -> UCHAR
|
|
|
- 2500 (codepoint value). *)
|
|
|
- 2501 IF (et # SymTab.InvalidType)
|
|
|
- 2502 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 2503 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2504 SemError(211) END;
|
|
|
- 2505 t := SymTab.UCharType(); .)
|
|
|
- 2506 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 2507 (. IF (et # SymTab.InvalidType)
|
|
|
- 2508 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 2430 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 2431 SymTab.ClArray THEN
|
|
|
+ 2432 SemError(217);
|
|
|
+ 2433 t := SymTab.InvalidType;
|
|
|
+ 2434 QbeGen.CopyOp("0", q)
|
|
|
+ 2435 ELSE
|
|
|
+ 2436 IF isHigh THEN
|
|
|
+ 2437 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2438 QbeGen.OpenHi(qd, qr)
|
|
|
+ 2439 ELSE
|
|
|
+ 2440 QbeGen.IntStr(
|
|
|
+ 2441 SymTab.ArrayHi(dt), qr)
|
|
|
+ 2442 END
|
|
|
+ 2443 ELSE
|
|
|
+ 2444 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2445 QbeGen.LoadCount(qd, qr)
|
|
|
+ 2446 ELSE
|
|
|
+ 2447 QbeGen.IntStr(VAL(
|
|
|
+ 2448 INTEGER,
|
|
|
+ 2449 SymTab.ArrayLen(dt)),
|
|
|
+ 2450 qr)
|
|
|
+ 2451 END
|
|
|
+ 2452 END;
|
|
|
+ 2453 t := SymTab.IntType();
|
|
|
+ 2454 QbeGen.CopyOp(qr, q)
|
|
|
+ 2455 END; .)
|
|
|
+ 2456 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2457 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2458 t := SymTab.InvalidType;
|
|
|
+ 2459 QbeGen.CopyOp("0", q)
|
|
|
+ 2460 ELSE
|
|
|
+ 2461 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 2462 SymTab.ObjectSize(dt)), q);
|
|
|
+ 2463 t := SymTab.IntType()
|
|
|
+ 2464 END; .)
|
|
|
+ 2465 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2466 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2467 t := SymTab.InvalidType;
|
|
|
+ 2468 QbeGen.CopyOp("0", q)
|
|
|
+ 2469 ELSE
|
|
|
+ 2470 IF sfx THEN
|
|
|
+ 2471 QbeGen.CopyOp(qd, q)
|
|
|
+ 2472 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 2473 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 2474 QbeGen.AddrOf(qn, q)
|
|
|
+ 2475 ELSE SemError(230);
|
|
|
+ 2476 QbeGen.CopyOp("0", q)
|
|
|
+ 2477 END;
|
|
|
+ 2478 t := SymTab.AddrType()
|
|
|
+ 2479 END; .)
|
|
|
+ 2480 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 2481 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2482 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2483 SemError(211) END;
|
|
|
+ 2484 t := SymTab.CharType(); .)
|
|
|
+ 2485 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 2486 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 2487 IF (SymTab.ClassOf(et) #
|
|
|
+ 2488 SymTab.ClChar)
|
|
|
+ 2489 AND (SymTab.ClassOf(et) #
|
|
|
+ 2490 SymTab.ClBool)
|
|
|
+ 2491 AND (SymTab.ClassOf(et) #
|
|
|
+ 2492 SymTab.ClEnum)
|
|
|
+ 2493 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2494 SemError(211) END
|
|
|
+ 2495 END;
|
|
|
+ 2496 t := SymTab.IntType(); .)
|
|
|
+ 2497 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 2498 (. QbeGen.CapQ(q, qa);
|
|
|
+ 2499 QbeGen.CopyOp(qa, q);
|
|
|
+ 2500 t := SymTab.CharType(); .)
|
|
|
+ 2501 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 2502 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 2503 CHAR -> UCHAR (identity);
|
|
|
+ 2504 INTEGER familly -> UCHAR
|
|
|
+ 2505 (codepoint value). *)
|
|
|
+ 2506 IF (et # SymTab.InvalidType)
|
|
|
+ 2507 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 2508 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
2509 SemError(211) END;
|
|
|
- 2510 QbeGen.WidenLong(q, qa);
|
|
|
- 2511 QbeGen.CheckRange(qa, "0", "255");
|
|
|
- 2512 t := SymTab.CharType(); .)
|
|
|
- 2513 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 2514 (. (* UORD(u): the codepoint as a
|
|
|
- 2515 32-bit ordinal (INTEGER),
|
|
|
- 2516 cf. ORD for CHAR. *)
|
|
|
- 2517 IF (et # SymTab.InvalidType)
|
|
|
- 2518 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 2519 SemError(211) END;
|
|
|
- 2520 t := SymTab.IntType(); .)
|
|
|
- 2521 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 2522 (. IF (et # SymTab.InvalidType)
|
|
|
- 2523 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 2524 AND (SymTab.ClassOf(et) #
|
|
|
- 2525 SymTab.ClReal) THEN
|
|
|
- 2526 SemError(211)
|
|
|
- 2527 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 2528 SymTab.ClassOf(et) =
|
|
|
- 2529 SymTab.ClReal);
|
|
|
- 2530 QbeGen.CopyOp(qa, q)
|
|
|
- 2531 END;
|
|
|
- 2532 t := et; .)
|
|
|
- 2533 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
- 2534 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 2535 SemError(201);
|
|
|
- 2536 t := SymTab.InvalidType
|
|
|
- 2537 ELSE vt := SymTab.SymType(vn);
|
|
|
- 2538 IF vt = SymTab.InvalidType THEN
|
|
|
- 2539 t := SymTab.InvalidType
|
|
|
- 2540 ELSIF et =
|
|
|
- 2541 SymTab.InvalidType THEN
|
|
|
- 2542 t := vt
|
|
|
- 2543 ELSE
|
|
|
- 2544 c1 := SymTab.ClassOf(et);
|
|
|
- 2545 c2 := SymTab.ClassOf(vt);
|
|
|
- 2546 IF (c1 = SymTab.ClInt)
|
|
|
- 2547 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 2548 QbeGen.WidenLong(q, qa);
|
|
|
- 2549 QbeGen.CopyOp(qa, q);
|
|
|
- 2550 t := vt
|
|
|
- 2551 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 2552 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 2553 QbeGen.NarrowLong(q, qa);
|
|
|
+ 2510 t := SymTab.UCharType(); .)
|
|
|
+ 2511 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 2512 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2513 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 2514 SemError(211) END;
|
|
|
+ 2515 QbeGen.WidenLong(q, qa);
|
|
|
+ 2516 QbeGen.CheckRange(qa, "0", "255");
|
|
|
+ 2517 t := SymTab.CharType(); .)
|
|
|
+ 2518 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 2519 (. (* UORD(u): the codepoint as a
|
|
|
+ 2520 32-bit ordinal (INTEGER),
|
|
|
+ 2521 cf. ORD for CHAR. *)
|
|
|
+ 2522 IF (et # SymTab.InvalidType)
|
|
|
+ 2523 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 2524 SemError(211) END;
|
|
|
+ 2525 t := SymTab.IntType(); .)
|
|
|
+ 2526 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 2527 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2528 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 2529 AND (SymTab.ClassOf(et) #
|
|
|
+ 2530 SymTab.ClReal) THEN
|
|
|
+ 2531 SemError(211)
|
|
|
+ 2532 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 2533 SymTab.ClassOf(et) =
|
|
|
+ 2534 SymTab.ClReal);
|
|
|
+ 2535 QbeGen.CopyOp(qa, q)
|
|
|
+ 2536 END;
|
|
|
+ 2537 t := et; .)
|
|
|
+ 2538 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
+ 2539 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 2540 SemError(201);
|
|
|
+ 2541 t := SymTab.InvalidType
|
|
|
+ 2542 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 2543 IF vt = SymTab.InvalidType THEN
|
|
|
+ 2544 t := SymTab.InvalidType
|
|
|
+ 2545 ELSIF et =
|
|
|
+ 2546 SymTab.InvalidType THEN
|
|
|
+ 2547 t := vt
|
|
|
+ 2548 ELSE
|
|
|
+ 2549 c1 := SymTab.ClassOf(et);
|
|
|
+ 2550 c2 := SymTab.ClassOf(vt);
|
|
|
+ 2551 IF (c1 = SymTab.ClInt)
|
|
|
+ 2552 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 2553 QbeGen.WidenLong(q, qa);
|
|
|
2554 QbeGen.CopyOp(qa, q);
|
|
|
2555 t := vt
|
|
|
- 2556 ELSIF (c1 = SymTab.ClInt)
|
|
|
- 2557 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 2558 QbeGen.ConvIR(q, qa);
|
|
|
+ 2556 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 2557 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 2558 QbeGen.NarrowLong(q, qa);
|
|
|
2559 QbeGen.CopyOp(qa, q);
|
|
|
2560 t := vt
|
|
|
- 2561 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 2561 ELSIF (c1 = SymTab.ClInt)
|
|
|
2562 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 2563 QbeGen.ConvLR(q, qa);
|
|
|
+ 2563 QbeGen.ConvIR(q, qa);
|
|
|
2564 QbeGen.CopyOp(qa, q);
|
|
|
2565 t := vt
|
|
|
- 2566 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 2567 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 2568 QbeGen.ConvRI(q, qa);
|
|
|
+ 2566 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 2567 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 2568 QbeGen.ConvLR(q, qa);
|
|
|
2569 QbeGen.CopyOp(qa, q);
|
|
|
2570 t := vt
|
|
|
2571 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 2572 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 2573 QbeGen.ConvRL(q, qa);
|
|
|
+ 2572 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 2573 QbeGen.ConvRI(q, qa);
|
|
|
2574 QbeGen.CopyOp(qa, q);
|
|
|
2575 t := vt
|
|
|
- 2576 ELSIF ((c1 = SymTab.ClInt)
|
|
|
- 2577 OR (c1 =
|
|
|
- 2578 SymTab.ClChar)
|
|
|
- 2579 OR (c1 =
|
|
|
- 2580 SymTab.ClBool)
|
|
|
- 2581 OR (c1 =
|
|
|
- 2582 SymTab.ClEnum))
|
|
|
- 2583 AND ((c2 = SymTab.ClInt)
|
|
|
- 2584 OR (c2 =
|
|
|
- 2585 SymTab.ClChar)
|
|
|
- 2586 OR (c2 =
|
|
|
- 2587 SymTab.ClBool)
|
|
|
- 2588 OR (c2 =
|
|
|
- 2589 SymTab.ClEnum)) THEN
|
|
|
- 2590 t := vt
|
|
|
- 2591 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 2592 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 2593 t := vt
|
|
|
- 2594 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 2595 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 2596 t := vt
|
|
|
- 2597 ELSE SemError(230);
|
|
|
- 2598 t := SymTab.InvalidType
|
|
|
- 2599 END
|
|
|
- 2600 END
|
|
|
- 2601 END; .)
|
|
|
- 2602 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
- 2603 | SetLit<st, sq> (. t := st;
|
|
|
- 2604 QbeGen.CopyOp(sq, q); .)
|
|
|
- 2605 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
- 2606 t := SymTab.BoolType()
|
|
|
- 2607 ELSE SemError(212);
|
|
|
- 2608 t := SymTab.InvalidType END;
|
|
|
- 2609 IF t # SymTab.InvalidType THEN
|
|
|
- 2610 QbeGen.NotQ(q2, q)
|
|
|
- 2611 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2612 END; .) .
|
|
|
- 2613 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 2614 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 2615 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 2616 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2617 = "{" (. t := SymTab.NewSet(
|
|
|
- 2618 SymTab.NewSubR(0, 255));
|
|
|
- 2619 QbeGen.NewSetTemp(8, q);
|
|
|
- 2620 QbeGen.SetZero(q, 8); .)
|
|
|
- 2621 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
- 2622 "}" .
|
|
|
- 2623 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
- 2624 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
- 2625 declared type sets the width (set) or element type (array). *)
|
|
|
- 2626 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2627 (. VAR nw: CARDINAL; .)
|
|
|
- 2628 = "{" (. IF vt = SymTab.InvalidType THEN
|
|
|
- 2629 braceCls := -1
|
|
|
- 2630 ELSE braceCls :=
|
|
|
- 2631 SymTab.ClassOf(vt)
|
|
|
- 2632 END;
|
|
|
- 2633 IF braceCls = SymTab.ClSet THEN
|
|
|
- 2634 IF vt = SymTab.InvalidType THEN
|
|
|
- 2635 nw := 8
|
|
|
- 2636 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 2637 IF nw = 0 THEN nw := 8 END
|
|
|
- 2638 END;
|
|
|
- 2639 QbeGen.NewSetTemp(nw, q);
|
|
|
- 2640 QbeGen.SetZero(q, nw)
|
|
|
- 2641 ELSIF braceCls = SymTab.ClArray THEN
|
|
|
- 2642 QbeGen.CtorBegin(vt)
|
|
|
- 2643 ELSE
|
|
|
- 2644 IF vt # SymTab.InvalidType THEN
|
|
|
- 2645 SemError(230) END;
|
|
|
- 2646 braceCls := -1
|
|
|
- 2647 END; .)
|
|
|
- 2648 [ BraceElem<vt, q> { "," BraceElem<vt, q> } ]
|
|
|
- 2649 "}" (. IF braceCls = SymTab.ClArray THEN
|
|
|
- 2650 QbeGen.CtorEnd(q)
|
|
|
- 2651 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
- 2652 QbeGen.CopyOp("0", q)
|
|
|
- 2653 END; .) .
|
|
|
- 2654 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal>
|
|
|
- 2655 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 2656 qe, q2: QbeGen.QVal;
|
|
|
- 2657 v, v2, reps, k: INTEGER;
|
|
|
- 2658 elem: SymTab.TypeIndex;
|
|
|
- 2659 lo: INTEGER;
|
|
|
- 2660 span: CARDINAL;
|
|
|
- 2661 cl, cl2: INTEGER;
|
|
|
- 2662 hasR, hasB: BOOLEAN; .)
|
|
|
- 2663 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
- 2664 Expr<et, qe>
|
|
|
- 2665 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
- 2666 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
- 2667 (. IF braceCls = SymTab.ClSet THEN
|
|
|
- 2668 IF hasB THEN SemError(230) END;
|
|
|
- 2669 lo := SymTab.SetBaseLo(vt);
|
|
|
- 2670 span := SymTab.SetCount(vt);
|
|
|
- 2671 IF (et = SymTab.InvalidType)
|
|
|
- 2672 OR (hasR AND (et2 =
|
|
|
- 2673 SymTab.InvalidType)) THEN
|
|
|
- 2674 ELSE cl :=
|
|
|
- 2675 SymTab.ClassOf(et);
|
|
|
- 2676 IF hasR THEN
|
|
|
- 2677 cl2 :=
|
|
|
- 2678 SymTab.ClassOf(et2)
|
|
|
- 2679 ELSE cl2 := SymTab.ClInt
|
|
|
- 2680 END;
|
|
|
- 2681 IF ((cl # SymTab.ClInt)
|
|
|
- 2682 AND (cl # SymTab.ClChar)
|
|
|
- 2683 AND (cl # SymTab.ClBool))
|
|
|
- 2684 OR (hasR AND
|
|
|
- 2685 ((cl2
|
|
|
- 2686 # SymTab.ClInt)
|
|
|
- 2687 AND (cl2
|
|
|
- 2688 # SymTab.ClChar)
|
|
|
- 2689 AND (cl2
|
|
|
- 2690 # SymTab.ClBool))) THEN
|
|
|
- 2691 SemError(222)
|
|
|
- 2692 ELSIF hasR
|
|
|
- 2693 AND SymTab.ConstInt(qe, v)
|
|
|
- 2694 AND SymTab.ConstInt(q2,
|
|
|
- 2695 v2)
|
|
|
- 2696 AND ((v < lo)
|
|
|
- 2697 OR (v2 < lo)
|
|
|
- 2698 OR (v >= lo +
|
|
|
- 2699 VAL(INTEGER, span))
|
|
|
- 2700 OR (v2 >= lo +
|
|
|
- 2701 VAL(INTEGER, span))
|
|
|
- 2702 OR (v > v2)) THEN
|
|
|
- 2703 SemError(222)
|
|
|
- 2704 ELSIF hasR THEN
|
|
|
- 2705 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 2706 lo, span)
|
|
|
- 2707 ELSIF SymTab.ConstInt(qe,
|
|
|
- 2708 v)
|
|
|
- 2709 AND ((v < lo)
|
|
|
- 2710 OR (v >= lo +
|
|
|
- 2711 VAL(INTEGER,
|
|
|
- 2712 span))) THEN
|
|
|
- 2713 SemError(222)
|
|
|
- 2714 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 2715 lo, span)
|
|
|
- 2716 END
|
|
|
- 2717 END
|
|
|
- 2718 ELSIF braceCls = SymTab.ClArray THEN
|
|
|
- 2719 IF hasR THEN SemError(230) END;
|
|
|
- 2720 reps := 1;
|
|
|
- 2721 IF hasB THEN
|
|
|
- 2722 IF SymTab.ConstInt(q2, v2)
|
|
|
- 2723 AND (v2 >= 1) THEN
|
|
|
- 2724 reps := v2
|
|
|
- 2725 ELSE SemError(230)
|
|
|
- 2726 END
|
|
|
- 2727 END;
|
|
|
- 2728 elem := SymTab.ArrayElem(vt);
|
|
|
- 2729 IF (SymTab.ClassOf(elem) =
|
|
|
- 2730 SymTab.ClArray)
|
|
|
- 2731 AND (SymTab.ClassOf(et) =
|
|
|
- 2732 SymTab.ClStr) THEN
|
|
|
- 2733 QbeGen.CtorElemStr(qe, elem)
|
|
|
- 2734 ELSE
|
|
|
- 2735 k := 0;
|
|
|
- 2736 WHILE k < reps DO
|
|
|
- 2737 QbeGen.CtorElem(qe, elem);
|
|
|
- 2738 INC(k)
|
|
|
- 2739 END
|
|
|
- 2740 END
|
|
|
- 2741 END; .) .
|
|
|
- 2742 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 2743 qe, q2: QbeGen.QVal;
|
|
|
- 2744 v, v2: INTEGER;
|
|
|
- 2745 lo: INTEGER;
|
|
|
- 2746 span: CARDINAL;
|
|
|
- 2747 cl, cl2: INTEGER;
|
|
|
- 2748 hasR: BOOLEAN; .)
|
|
|
- 2749 = (. hasR := FALSE; .)
|
|
|
- 2750 Expr<et, qe>
|
|
|
- 2751 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
- 2752 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 2753 span := SymTab.SetCount(st);
|
|
|
- 2754 IF (et = SymTab.InvalidType)
|
|
|
- 2755 OR (hasR AND (et2 =
|
|
|
- 2756 SymTab.InvalidType)) THEN
|
|
|
- 2757 ELSE cl :=
|
|
|
- 2758 SymTab.ClassOf(et);
|
|
|
- 2759 IF hasR THEN
|
|
|
- 2760 cl2 :=
|
|
|
- 2761 SymTab.ClassOf(et2)
|
|
|
- 2762 ELSE cl2 := SymTab.ClInt
|
|
|
- 2763 END;
|
|
|
- 2764 IF ((cl # SymTab.ClInt)
|
|
|
- 2765 AND (cl # SymTab.ClChar)
|
|
|
- 2766 AND (cl # SymTab.ClBool))
|
|
|
- 2767 OR (hasR AND
|
|
|
- 2768 ((cl2
|
|
|
- 2769 # SymTab.ClInt)
|
|
|
- 2770 AND (cl2
|
|
|
- 2771 # SymTab.ClChar)
|
|
|
- 2772 AND (cl2
|
|
|
- 2773 # SymTab.ClBool))) THEN
|
|
|
- 2774 SemError(222)
|
|
|
- 2775 ELSIF hasR
|
|
|
- 2776 AND SymTab.ConstInt(qe, v)
|
|
|
- 2777 AND SymTab.ConstInt(q2,
|
|
|
- 2778 v2)
|
|
|
- 2779 AND ((v < lo)
|
|
|
- 2780 OR (v2 < lo)
|
|
|
- 2781 OR (v >= lo +
|
|
|
- 2782 VAL(INTEGER, span))
|
|
|
- 2783 OR (v2 >= lo +
|
|
|
- 2784 VAL(INTEGER, span))
|
|
|
- 2785 OR (v > v2)) THEN
|
|
|
- 2786 SemError(222)
|
|
|
- 2787 ELSIF hasR THEN
|
|
|
- 2788 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 2789 lo, span)
|
|
|
- 2790 ELSIF SymTab.ConstInt(qe,
|
|
|
- 2791 v)
|
|
|
- 2792 AND ((v < lo)
|
|
|
- 2793 OR (v >= lo +
|
|
|
- 2794 VAL(INTEGER,
|
|
|
- 2795 span))) THEN
|
|
|
- 2796 SemError(222)
|
|
|
- 2797 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 2798 lo, span)
|
|
|
- 2799 END
|
|
|
- 2800 END; .) .
|
|
|
- 2801 GetIdent<VAR n: SymTab.Name>
|
|
|
- 2802 = ident (. LexName(n); .) .
|
|
|
- 2803
|
|
|
- 2804 END M2.
|
|
|
+ 2576 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 2577 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 2578 QbeGen.ConvRL(q, qa);
|
|
|
+ 2579 QbeGen.CopyOp(qa, q);
|
|
|
+ 2580 t := vt
|
|
|
+ 2581 ELSIF ((c1 = SymTab.ClInt)
|
|
|
+ 2582 OR (c1 =
|
|
|
+ 2583 SymTab.ClChar)
|
|
|
+ 2584 OR (c1 =
|
|
|
+ 2585 SymTab.ClBool)
|
|
|
+ 2586 OR (c1 =
|
|
|
+ 2587 SymTab.ClEnum))
|
|
|
+ 2588 AND ((c2 = SymTab.ClInt)
|
|
|
+ 2589 OR (c2 =
|
|
|
+ 2590 SymTab.ClChar)
|
|
|
+ 2591 OR (c2 =
|
|
|
+ 2592 SymTab.ClBool)
|
|
|
+ 2593 OR (c2 =
|
|
|
+ 2594 SymTab.ClEnum)) THEN
|
|
|
+ 2595 t := vt
|
|
|
+ 2596 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 2597 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 2598 t := vt
|
|
|
+ 2599 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 2600 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 2601 t := vt
|
|
|
+ 2602 ELSE SemError(230);
|
|
|
+ 2603 t := SymTab.InvalidType
|
|
|
+ 2604 END
|
|
|
+ 2605 END
|
|
|
+ 2606 END; .)
|
|
|
+ 2607 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
+ 2608 | SetLit<st, sq> (. t := st;
|
|
|
+ 2609 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 2610 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 2611 t := SymTab.BoolType()
|
|
|
+ 2612 ELSE SemError(212);
|
|
|
+ 2613 t := SymTab.InvalidType END;
|
|
|
+ 2614 IF t # SymTab.InvalidType THEN
|
|
|
+ 2615 QbeGen.NotQ(q2, q)
|
|
|
+ 2616 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2617 END; .) .
|
|
|
+ 2618 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 2619 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 2620 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 2621 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2622 = "{" (. t := SymTab.NewSet(
|
|
|
+ 2623 SymTab.NewSubR(0, 255));
|
|
|
+ 2624 QbeGen.NewSetTemp(8, q);
|
|
|
+ 2625 QbeGen.SetZero(q, 8); .)
|
|
|
+ 2626 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
+ 2627 "}" .
|
|
|
+ 2628 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
+ 2629 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
+ 2630 declared type sets the width (set) or element type (array). *)
|
|
|
+ 2631 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2632 (. VAR nw: CARDINAL; .)
|
|
|
+ 2633 = "{" (. IF vt = SymTab.InvalidType THEN
|
|
|
+ 2634 braceCls := -1
|
|
|
+ 2635 ELSE braceCls :=
|
|
|
+ 2636 SymTab.ClassOf(vt)
|
|
|
+ 2637 END;
|
|
|
+ 2638 IF braceCls = SymTab.ClSet THEN
|
|
|
+ 2639 IF vt = SymTab.InvalidType THEN
|
|
|
+ 2640 nw := 8
|
|
|
+ 2641 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 2642 IF nw = 0 THEN nw := 8 END
|
|
|
+ 2643 END;
|
|
|
+ 2644 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 2645 QbeGen.SetZero(q, nw)
|
|
|
+ 2646 ELSIF (braceCls =
|
|
|
+ 2647 SymTab.ClArray)
|
|
|
+ 2648 OR (braceCls =
|
|
|
+ 2649 SymTab.ClRecord)
|
|
|
+ 2650 OR (braceCls =
|
|
|
+ 2651 SymTab.ClClass) THEN
|
|
|
+ 2652 QbeGen.CtorBegin(vt)
|
|
|
+ 2653 ELSE
|
|
|
+ 2654 IF vt # SymTab.InvalidType THEN
|
|
|
+ 2655 SemError(230) END;
|
|
|
+ 2656 braceCls := -1
|
|
|
+ 2657 END; .)
|
|
|
+ 2658 [ BraceElem<vt, q> { "," BraceElem<vt, q> } ]
|
|
|
+ 2659 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
+ 2660 OR (braceCls =
|
|
|
+ 2661 SymTab.ClRecord)
|
|
|
+ 2662 OR (braceCls =
|
|
|
+ 2663 SymTab.ClClass) THEN
|
|
|
+ 2664 QbeGen.CtorEnd(q)
|
|
|
+ 2665 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
+ 2666 QbeGen.CopyOp("0", q)
|
|
|
+ 2667 END; .) .
|
|
|
+ 2668 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal>
|
|
|
+ 2669 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 2670 qe, q2: QbeGen.QVal;
|
|
|
+ 2671 v, v2, reps, k: INTEGER;
|
|
|
+ 2672 elem: SymTab.TypeIndex;
|
|
|
+ 2673 lo: INTEGER;
|
|
|
+ 2674 span: CARDINAL;
|
|
|
+ 2675 cl, cl2: INTEGER;
|
|
|
+ 2676 hasR, hasB: BOOLEAN; .)
|
|
|
+ 2677 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
+ 2678 Expr<et, qe>
|
|
|
+ 2679 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
+ 2680 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
+ 2681 (. IF braceCls = SymTab.ClSet THEN
|
|
|
+ 2682 IF hasB THEN SemError(230) END;
|
|
|
+ 2683 lo := SymTab.SetBaseLo(vt);
|
|
|
+ 2684 span := SymTab.SetCount(vt);
|
|
|
+ 2685 IF (et = SymTab.InvalidType)
|
|
|
+ 2686 OR (hasR AND (et2 =
|
|
|
+ 2687 SymTab.InvalidType)) THEN
|
|
|
+ 2688 ELSE cl :=
|
|
|
+ 2689 SymTab.ClassOf(et);
|
|
|
+ 2690 IF hasR THEN
|
|
|
+ 2691 cl2 :=
|
|
|
+ 2692 SymTab.ClassOf(et2)
|
|
|
+ 2693 ELSE cl2 := SymTab.ClInt
|
|
|
+ 2694 END;
|
|
|
+ 2695 IF ((cl # SymTab.ClInt)
|
|
|
+ 2696 AND (cl # SymTab.ClChar)
|
|
|
+ 2697 AND (cl # SymTab.ClBool))
|
|
|
+ 2698 OR (hasR AND
|
|
|
+ 2699 ((cl2
|
|
|
+ 2700 # SymTab.ClInt)
|
|
|
+ 2701 AND (cl2
|
|
|
+ 2702 # SymTab.ClChar)
|
|
|
+ 2703 AND (cl2
|
|
|
+ 2704 # SymTab.ClBool))) THEN
|
|
|
+ 2705 SemError(222)
|
|
|
+ 2706 ELSIF hasR
|
|
|
+ 2707 AND SymTab.ConstInt(qe, v)
|
|
|
+ 2708 AND SymTab.ConstInt(q2,
|
|
|
+ 2709 v2)
|
|
|
+ 2710 AND ((v < lo)
|
|
|
+ 2711 OR (v2 < lo)
|
|
|
+ 2712 OR (v >= lo +
|
|
|
+ 2713 VAL(INTEGER, span))
|
|
|
+ 2714 OR (v2 >= lo +
|
|
|
+ 2715 VAL(INTEGER, span))
|
|
|
+ 2716 OR (v > v2)) THEN
|
|
|
+ 2717 SemError(222)
|
|
|
+ 2718 ELSIF hasR THEN
|
|
|
+ 2719 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 2720 lo, span)
|
|
|
+ 2721 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 2722 v)
|
|
|
+ 2723 AND ((v < lo)
|
|
|
+ 2724 OR (v >= lo +
|
|
|
+ 2725 VAL(INTEGER,
|
|
|
+ 2726 span))) THEN
|
|
|
+ 2727 SemError(222)
|
|
|
+ 2728 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 2729 lo, span)
|
|
|
+ 2730 END
|
|
|
+ 2731 END
|
|
|
+ 2732 ELSIF (braceCls = SymTab.ClArray)
|
|
|
+ 2733 OR (braceCls =
|
|
|
+ 2734 SymTab.ClRecord)
|
|
|
+ 2735 OR (braceCls =
|
|
|
+ 2736 SymTab.ClClass) THEN
|
|
|
+ 2737 IF hasR THEN SemError(230) END;
|
|
|
+ 2738 reps := 1;
|
|
|
+ 2739 IF hasB THEN
|
|
|
+ 2740 IF SymTab.ConstInt(q2, v2)
|
|
|
+ 2741 AND (v2 >= 1) THEN
|
|
|
+ 2742 reps := v2
|
|
|
+ 2743 ELSE SemError(230)
|
|
|
+ 2744 END
|
|
|
+ 2745 END;
|
|
|
+ 2746 k := 0;
|
|
|
+ 2747 WHILE k < reps DO
|
|
|
+ 2748 QbeGen.CtorElem(qe);
|
|
|
+ 2749 INC(k)
|
|
|
+ 2750 END
|
|
|
+ 2751 END; .) .
|
|
|
+ 2752 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 2753 qe, q2: QbeGen.QVal;
|
|
|
+ 2754 v, v2: INTEGER;
|
|
|
+ 2755 lo: INTEGER;
|
|
|
+ 2756 span: CARDINAL;
|
|
|
+ 2757 cl, cl2: INTEGER;
|
|
|
+ 2758 hasR: BOOLEAN; .)
|
|
|
+ 2759 = (. hasR := FALSE; .)
|
|
|
+ 2760 Expr<et, qe>
|
|
|
+ 2761 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
+ 2762 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 2763 span := SymTab.SetCount(st);
|
|
|
+ 2764 IF (et = SymTab.InvalidType)
|
|
|
+ 2765 OR (hasR AND (et2 =
|
|
|
+ 2766 SymTab.InvalidType)) THEN
|
|
|
+ 2767 ELSE cl :=
|
|
|
+ 2768 SymTab.ClassOf(et);
|
|
|
+ 2769 IF hasR THEN
|
|
|
+ 2770 cl2 :=
|
|
|
+ 2771 SymTab.ClassOf(et2)
|
|
|
+ 2772 ELSE cl2 := SymTab.ClInt
|
|
|
+ 2773 END;
|
|
|
+ 2774 IF ((cl # SymTab.ClInt)
|
|
|
+ 2775 AND (cl # SymTab.ClChar)
|
|
|
+ 2776 AND (cl # SymTab.ClBool))
|
|
|
+ 2777 OR (hasR AND
|
|
|
+ 2778 ((cl2
|
|
|
+ 2779 # SymTab.ClInt)
|
|
|
+ 2780 AND (cl2
|
|
|
+ 2781 # SymTab.ClChar)
|
|
|
+ 2782 AND (cl2
|
|
|
+ 2783 # SymTab.ClBool))) THEN
|
|
|
+ 2784 SemError(222)
|
|
|
+ 2785 ELSIF hasR
|
|
|
+ 2786 AND SymTab.ConstInt(qe, v)
|
|
|
+ 2787 AND SymTab.ConstInt(q2,
|
|
|
+ 2788 v2)
|
|
|
+ 2789 AND ((v < lo)
|
|
|
+ 2790 OR (v2 < lo)
|
|
|
+ 2791 OR (v >= lo +
|
|
|
+ 2792 VAL(INTEGER, span))
|
|
|
+ 2793 OR (v2 >= lo +
|
|
|
+ 2794 VAL(INTEGER, span))
|
|
|
+ 2795 OR (v > v2)) THEN
|
|
|
+ 2796 SemError(222)
|
|
|
+ 2797 ELSIF hasR THEN
|
|
|
+ 2798 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 2799 lo, span)
|
|
|
+ 2800 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 2801 v)
|
|
|
+ 2802 AND ((v < lo)
|
|
|
+ 2803 OR (v >= lo +
|
|
|
+ 2804 VAL(INTEGER,
|
|
|
+ 2805 span))) THEN
|
|
|
+ 2806 SemError(222)
|
|
|
+ 2807 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 2808 lo, span)
|
|
|
+ 2809 END
|
|
|
+ 2810 END; .) .
|
|
|
+ 2811 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 2812 = ident (. LexName(n); .) .
|
|
|
+ 2813
|
|
|
+ 2814 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|