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