|
|
@@ -2718,1524 +2718,1543 @@ Listing:
|
|
|
2697 astLab: AST.Node;
|
|
|
2698 lNext: QbeGen.QVal; .)
|
|
|
2699 = Expr<t2, q2> (. astLab := astCur;
|
|
|
- 2700 IF (t2 #
|
|
|
- 2701 SymTab.InvalidType)
|
|
|
- 2702 AND (tsel #
|
|
|
- 2703 SymTab.InvalidType)
|
|
|
- 2704 AND NOT SymTab.EqCheck(t2,
|
|
|
- 2705 tsel) THEN
|
|
|
- 2706 SemError(213) END;
|
|
|
- 2707 (* set labels are not immediates:
|
|
|
- 2708 the CASE chain uses CmpSet *)
|
|
|
- 2709 IF (SymTab.ClassOf(t2) # SymTab.ClSet)
|
|
|
- 2710 AND NOT QbeGen.IsImm(q2) THEN
|
|
|
- 2711 SemError(230)
|
|
|
- 2712 END; .)
|
|
|
- 2713 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
- 2714 AST.NkSubrange, 0, astLab, astCur);
|
|
|
- 2715 IF (t3 #
|
|
|
- 2716 SymTab.InvalidType)
|
|
|
- 2717 AND (tsel #
|
|
|
- 2718 SymTab.InvalidType)
|
|
|
- 2719 AND NOT SymTab.EqCheck(t3,
|
|
|
- 2720 tsel) THEN
|
|
|
- 2721 SemError(213) END;
|
|
|
- 2722 IF (SymTab.ClassOf(t3) # SymTab.ClSet)
|
|
|
- 2723 AND NOT QbeGen.IsImm(q3) THEN
|
|
|
- 2724 SemError(230)
|
|
|
- 2725 END; .) ]
|
|
|
- 2726 (. AST.SetChild(arm,
|
|
|
- 2727 AST.NChild(arm), astLab); .) .
|
|
|
- 2728 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2729 q, qt: QbeGen.QVal;
|
|
|
- 2730 res: SymTab.TypeIndex;
|
|
|
- 2731 hadE, conv: BOOLEAN;
|
|
|
- 2732 astVal, astNode: AST.Node; .)
|
|
|
- 2733 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
- 2734 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
- 2735 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
- 2736 IF hadE THEN
|
|
|
- 2737 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2738 END;
|
|
|
- 2739 astStmt := astNode;
|
|
|
- 2740 conv := FALSE;
|
|
|
- 2741 IF NOT SymTab.InProc() THEN
|
|
|
- 2742 SemError(232)
|
|
|
- 2743 ELSE res := SymTab.CurRes();
|
|
|
- 2744 IF NOT hadE THEN
|
|
|
- 2745 IF res #
|
|
|
- 2746 SymTab.InvalidType THEN
|
|
|
- 2747 SemError(232)
|
|
|
- 2748 END
|
|
|
- 2749 ELSIF (res =
|
|
|
- 2750 SymTab.InvalidType)
|
|
|
- 2751 OR (t #
|
|
|
- 2752 SymTab.InvalidType)
|
|
|
- 2753 AND NOT SymTab.Assignable(t,
|
|
|
- 2754 res) THEN
|
|
|
- 2755 SemError(232)
|
|
|
- 2756 END
|
|
|
- 2757 END; .) .
|
|
|
- 2758 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2759 q: QbeGen.QVal;
|
|
|
- 2760 astVal, astNode: AST.Node; .)
|
|
|
- 2761 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
- 2762 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
- 2763 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
- 2764 IF astVal # AST.NoNode THEN
|
|
|
- 2765 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2766 END;
|
|
|
- 2767 astStmt := astNode;
|
|
|
- 2768 .) .
|
|
|
- 2769 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 2770 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 2771 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 2772 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 2773 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 2774 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 2775 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 2776 (. VAR n: SymTab.Name; .)
|
|
|
- 2777 = GetIdent<n> DesignTail<n, t, k, q, qn, sfx> .
|
|
|
- 2778 (* The part of Design after the identifier: resolve it and walk the
|
|
|
- 2779 selectors. Split out so a statement can decide between a label
|
|
|
- 2780 (`ident :`) and a designator (`ident := ...`) with one token. *)
|
|
|
- 2781 DesignTail<VAR n: SymTab.Name; VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 2782 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 2783 (. VAR fn, mal: SymTab.Name;
|
|
|
- 2784 cls: INTEGER;
|
|
|
- 2785 ic: SymTab.TypeIndex;
|
|
|
- 2786 curT, it, eT, bt:
|
|
|
- 2787 SymTab.TypeIndex;
|
|
|
- 2788 iq, ql, qlo, qhi, qe:
|
|
|
- 2789 QbeGen.QVal;
|
|
|
- 2790 lo, hi: INTEGER;
|
|
|
- 2791 fo: INTEGER;
|
|
|
- 2792 isOpen: BOOLEAN;
|
|
|
- 2793 qb, cv: QbeGen.QVal;
|
|
|
- 2794 r: BOOLEAN;
|
|
|
- 2795 astDes, astSel: AST.Node; .)
|
|
|
- 2796 = (. methCls := SymTab.InvalidType;
|
|
|
- 2797 QbeGen.CopyOp(n, qn);
|
|
|
- 2798 sfx := FALSE;
|
|
|
- 2799 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 2800 (* a bare method name inside
|
|
|
- 2801 a CLASS IMPLEMENTATION
|
|
|
- 2802 is a sibling call on
|
|
|
- 2803 THIS *)
|
|
|
- 2804 ic := SymTab.CurImplClass();
|
|
|
- 2805 IF (ic #
|
|
|
- 2806 SymTab.InvalidType)
|
|
|
- 2807 AND SymTab.MethodExists(ic, n) THEN
|
|
|
- 2808 sfx := FALSE;
|
|
|
- 2809 QbeGen.CopyOp("@", q);
|
|
|
- 2810 methCls := ic;
|
|
|
- 2811 k := SymTab.KindProc;
|
|
|
- 2812 t := SymTab.InvalidType
|
|
|
- 2813 ELSIF SymTab.InProc() THEN
|
|
|
- 2814 (* not declared anywhere
|
|
|
- 2815 in scope: with bodies
|
|
|
- 2816 parsed at unit end this
|
|
|
- 2817 is a genuine 201 (a
|
|
|
- 2818 nested-local forward is
|
|
|
- 2819 no longer tolerated). *)
|
|
|
- 2820 SemError(201);
|
|
|
- 2821 t := SymTab.InvalidType;
|
|
|
- 2822 k := -1;
|
|
|
- 2823 QbeGen.CopyOp("0", q)
|
|
|
- 2824 ELSE
|
|
|
- 2825 SemError(201);
|
|
|
- 2826 t :=
|
|
|
- 2827 SymTab.InvalidType;
|
|
|
- 2828 k := -1;
|
|
|
- 2829 QbeGen.CopyOp("0", q)
|
|
|
- 2830 END
|
|
|
- 2831 ELSE
|
|
|
- 2832 t := SymTab.SymType(n);
|
|
|
- 2833 k := SymTab.SymKind(n);
|
|
|
- 2834 IF k = SymTab.KindConst THEN
|
|
|
- 2835 IF SymTab.Equal(n,
|
|
|
- 2836 "TRUE") THEN
|
|
|
- 2837 t := SymTab.BoolType();
|
|
|
- 2838 QbeGen.CopyOp("1", q)
|
|
|
- 2839 ELSIF SymTab.Equal(n,
|
|
|
- 2840 "FALSE") THEN
|
|
|
- 2841 t := SymTab.BoolType();
|
|
|
- 2842 QbeGen.CopyOp("0", q)
|
|
|
- 2843 ELSIF SymTab.Equal(n,
|
|
|
- 2844 "NIL") THEN
|
|
|
- 2845 QbeGen.CopyOp("0", q)
|
|
|
- 2846 ELSE
|
|
|
- 2847 cls :=
|
|
|
- 2848 SymTab.ClassOf(t);
|
|
|
- 2849 IF (t #
|
|
|
- 2850 SymTab.InvalidType)
|
|
|
- 2851 AND ((cls = SymTab.ClInt)
|
|
|
- 2852 OR (cls
|
|
|
- 2853 = SymTab.ClChar)
|
|
|
- 2854 OR (cls
|
|
|
- 2855 = SymTab.ClEnum)
|
|
|
- 2856 OR (cls
|
|
|
- 2857 = SymTab.ClReal)
|
|
|
- 2858 OR (cls
|
|
|
- 2859 = SymTab.ClLong)
|
|
|
- 2860 OR (cls
|
|
|
- 2861 = SymTab.ClNil)
|
|
|
- 2862 OR (cls = SymTab.ClBool)) THEN
|
|
|
- 2863 IF cls = SymTab.ClNil THEN
|
|
|
- 2864 QbeGen.CopyOp("0", q)
|
|
|
- 2865 ELSIF ((cls
|
|
|
- 2866 = SymTab.ClInt)
|
|
|
- 2867 OR (cls
|
|
|
- 2868 = SymTab.ClChar)
|
|
|
- 2869 OR (cls
|
|
|
- 2870 = SymTab.ClEnum)
|
|
|
- 2871 OR (cls
|
|
|
- 2872 = SymTab.ClLong)
|
|
|
- 2873 OR (cls = SymTab.ClBool))
|
|
|
- 2874 AND SymTab.GetSymVal(n, cv)
|
|
|
- 2875 AND QbeGen.IsImm(cv) THEN
|
|
|
- 2876 QbeGen.CopyOp(cv, q)
|
|
|
- 2877 ELSE
|
|
|
- 2878 QbeGen.LoadVar(n,
|
|
|
- 2879 cls = SymTab.ClReal,
|
|
|
- 2880 q)
|
|
|
- 2881 END
|
|
|
- 2882 ELSIF (cls = SymTab.ClArray)
|
|
|
- 2883 OR (cls = SymTab.ClRecord)
|
|
|
- 2884 OR (cls = SymTab.ClClass)
|
|
|
- 2885 OR (cls = SymTab.ClStr)
|
|
|
- 2886 OR (cls = SymTab.ClUStr)
|
|
|
- 2887 OR (cls = SymTab.ClSet) THEN
|
|
|
- 2888 (* aggregate constant:
|
|
|
- 2889 its value IS the
|
|
|
- 2890 descriptor address *)
|
|
|
- 2891 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
- 2892 QbeGen.CopyOp(cv, q)
|
|
|
- 2893 ELSE
|
|
|
- 2894 QbeGen.CopyOp("0", q)
|
|
|
+ 2700 IF SymTab.IsEmptyStr(t2)
|
|
|
+ 2701 AND (SymTab.ClassOf(tsel) =
|
|
|
+ 2702 SymTab.ClChar) THEN
|
|
|
+ 2703 (* ISO: '' as a CASE label
|
|
|
+ 2704 is the terminator *)
|
|
|
+ 2705 QbeGen.CopyOp("0", q2);
|
|
|
+ 2706 t2 := SymTab.CharType()
|
|
|
+ 2707 END;
|
|
|
+ 2708 IF (t2 #
|
|
|
+ 2709 SymTab.InvalidType)
|
|
|
+ 2710 AND (tsel #
|
|
|
+ 2711 SymTab.InvalidType)
|
|
|
+ 2712 AND NOT SymTab.EqCheck(t2,
|
|
|
+ 2713 tsel) THEN
|
|
|
+ 2714 SemError(213) END;
|
|
|
+ 2715 (* set labels are not immediates:
|
|
|
+ 2716 the CASE chain uses CmpSet *)
|
|
|
+ 2717 IF (SymTab.ClassOf(t2) # SymTab.ClSet)
|
|
|
+ 2718 AND NOT QbeGen.IsImm(q2) THEN
|
|
|
+ 2719 SemError(230)
|
|
|
+ 2720 END; .)
|
|
|
+ 2721 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
+ 2722 AST.NkSubrange, 0, astLab, astCur);
|
|
|
+ 2723 IF SymTab.IsEmptyStr(t3)
|
|
|
+ 2724 AND (SymTab.ClassOf(tsel) =
|
|
|
+ 2725 SymTab.ClChar) THEN
|
|
|
+ 2726 QbeGen.CopyOp("0", q3);
|
|
|
+ 2727 t3 := SymTab.CharType()
|
|
|
+ 2728 END;
|
|
|
+ 2729 IF (t3 #
|
|
|
+ 2730 SymTab.InvalidType)
|
|
|
+ 2731 AND (tsel #
|
|
|
+ 2732 SymTab.InvalidType)
|
|
|
+ 2733 AND NOT SymTab.EqCheck(t3,
|
|
|
+ 2734 tsel) THEN
|
|
|
+ 2735 SemError(213) END;
|
|
|
+ 2736 IF (SymTab.ClassOf(t3) # SymTab.ClSet)
|
|
|
+ 2737 AND NOT QbeGen.IsImm(q3) THEN
|
|
|
+ 2738 SemError(230)
|
|
|
+ 2739 END; .) ]
|
|
|
+ 2740 (. AST.SetChild(arm,
|
|
|
+ 2741 AST.NChild(arm), astLab); .) .
|
|
|
+ 2742 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2743 q, qt: QbeGen.QVal;
|
|
|
+ 2744 res: SymTab.TypeIndex;
|
|
|
+ 2745 hadE, conv: BOOLEAN;
|
|
|
+ 2746 astVal, astNode: AST.Node; .)
|
|
|
+ 2747 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
+ 2748 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
+ 2749 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
+ 2750 IF hadE THEN
|
|
|
+ 2751 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2752 END;
|
|
|
+ 2753 astStmt := astNode;
|
|
|
+ 2754 conv := FALSE;
|
|
|
+ 2755 IF NOT SymTab.InProc() THEN
|
|
|
+ 2756 SemError(232)
|
|
|
+ 2757 ELSE res := SymTab.CurRes();
|
|
|
+ 2758 IF NOT hadE THEN
|
|
|
+ 2759 IF res #
|
|
|
+ 2760 SymTab.InvalidType THEN
|
|
|
+ 2761 SemError(232)
|
|
|
+ 2762 END
|
|
|
+ 2763 ELSIF (res =
|
|
|
+ 2764 SymTab.InvalidType)
|
|
|
+ 2765 OR (t #
|
|
|
+ 2766 SymTab.InvalidType)
|
|
|
+ 2767 AND NOT SymTab.Assignable(t,
|
|
|
+ 2768 res) THEN
|
|
|
+ 2769 SemError(232)
|
|
|
+ 2770 END
|
|
|
+ 2771 END; .) .
|
|
|
+ 2772 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2773 q: QbeGen.QVal;
|
|
|
+ 2774 astVal, astNode: AST.Node; .)
|
|
|
+ 2775 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
+ 2776 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
+ 2777 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
+ 2778 IF astVal # AST.NoNode THEN
|
|
|
+ 2779 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2780 END;
|
|
|
+ 2781 astStmt := astNode;
|
|
|
+ 2782 .) .
|
|
|
+ 2783 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 2784 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 2785 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 2786 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 2787 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 2788 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 2789 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 2790 (. VAR n: SymTab.Name; .)
|
|
|
+ 2791 = GetIdent<n> DesignTail<n, t, k, q, qn, sfx> .
|
|
|
+ 2792 (* The part of Design after the identifier: resolve it and walk the
|
|
|
+ 2793 selectors. Split out so a statement can decide between a label
|
|
|
+ 2794 (`ident :`) and a designator (`ident := ...`) with one token. *)
|
|
|
+ 2795 DesignTail<VAR n: SymTab.Name; VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 2796 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 2797 (. VAR fn, mal: SymTab.Name;
|
|
|
+ 2798 cls: INTEGER;
|
|
|
+ 2799 ic: SymTab.TypeIndex;
|
|
|
+ 2800 curT, it, eT, bt:
|
|
|
+ 2801 SymTab.TypeIndex;
|
|
|
+ 2802 iq, ql, qlo, qhi, qe:
|
|
|
+ 2803 QbeGen.QVal;
|
|
|
+ 2804 lo, hi: INTEGER;
|
|
|
+ 2805 fo: INTEGER;
|
|
|
+ 2806 isOpen: BOOLEAN;
|
|
|
+ 2807 qb, cv: QbeGen.QVal;
|
|
|
+ 2808 r: BOOLEAN;
|
|
|
+ 2809 astDes, astSel: AST.Node; .)
|
|
|
+ 2810 = (. methCls := SymTab.InvalidType;
|
|
|
+ 2811 QbeGen.CopyOp(n, qn);
|
|
|
+ 2812 sfx := FALSE;
|
|
|
+ 2813 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 2814 (* a bare method name inside
|
|
|
+ 2815 a CLASS IMPLEMENTATION
|
|
|
+ 2816 is a sibling call on
|
|
|
+ 2817 THIS *)
|
|
|
+ 2818 ic := SymTab.CurImplClass();
|
|
|
+ 2819 IF (ic #
|
|
|
+ 2820 SymTab.InvalidType)
|
|
|
+ 2821 AND SymTab.MethodExists(ic, n) THEN
|
|
|
+ 2822 sfx := FALSE;
|
|
|
+ 2823 QbeGen.CopyOp("@", q);
|
|
|
+ 2824 methCls := ic;
|
|
|
+ 2825 k := SymTab.KindProc;
|
|
|
+ 2826 t := SymTab.InvalidType
|
|
|
+ 2827 ELSIF SymTab.InProc() THEN
|
|
|
+ 2828 (* not declared anywhere
|
|
|
+ 2829 in scope: with bodies
|
|
|
+ 2830 parsed at unit end this
|
|
|
+ 2831 is a genuine 201 (a
|
|
|
+ 2832 nested-local forward is
|
|
|
+ 2833 no longer tolerated). *)
|
|
|
+ 2834 SemError(201);
|
|
|
+ 2835 t := SymTab.InvalidType;
|
|
|
+ 2836 k := -1;
|
|
|
+ 2837 QbeGen.CopyOp("0", q)
|
|
|
+ 2838 ELSE
|
|
|
+ 2839 SemError(201);
|
|
|
+ 2840 t :=
|
|
|
+ 2841 SymTab.InvalidType;
|
|
|
+ 2842 k := -1;
|
|
|
+ 2843 QbeGen.CopyOp("0", q)
|
|
|
+ 2844 END
|
|
|
+ 2845 ELSE
|
|
|
+ 2846 t := SymTab.SymType(n);
|
|
|
+ 2847 k := SymTab.SymKind(n);
|
|
|
+ 2848 IF k = SymTab.KindConst THEN
|
|
|
+ 2849 IF SymTab.Equal(n,
|
|
|
+ 2850 "TRUE") THEN
|
|
|
+ 2851 t := SymTab.BoolType();
|
|
|
+ 2852 QbeGen.CopyOp("1", q)
|
|
|
+ 2853 ELSIF SymTab.Equal(n,
|
|
|
+ 2854 "FALSE") THEN
|
|
|
+ 2855 t := SymTab.BoolType();
|
|
|
+ 2856 QbeGen.CopyOp("0", q)
|
|
|
+ 2857 ELSIF SymTab.Equal(n,
|
|
|
+ 2858 "NIL") THEN
|
|
|
+ 2859 QbeGen.CopyOp("0", q)
|
|
|
+ 2860 ELSE
|
|
|
+ 2861 cls :=
|
|
|
+ 2862 SymTab.ClassOf(t);
|
|
|
+ 2863 IF (t #
|
|
|
+ 2864 SymTab.InvalidType)
|
|
|
+ 2865 AND ((cls = SymTab.ClInt)
|
|
|
+ 2866 OR (cls
|
|
|
+ 2867 = SymTab.ClChar)
|
|
|
+ 2868 OR (cls
|
|
|
+ 2869 = SymTab.ClEnum)
|
|
|
+ 2870 OR (cls
|
|
|
+ 2871 = SymTab.ClReal)
|
|
|
+ 2872 OR (cls
|
|
|
+ 2873 = SymTab.ClLong)
|
|
|
+ 2874 OR (cls
|
|
|
+ 2875 = SymTab.ClNil)
|
|
|
+ 2876 OR (cls = SymTab.ClBool)) THEN
|
|
|
+ 2877 IF cls = SymTab.ClNil THEN
|
|
|
+ 2878 QbeGen.CopyOp("0", q)
|
|
|
+ 2879 ELSIF ((cls
|
|
|
+ 2880 = SymTab.ClInt)
|
|
|
+ 2881 OR (cls
|
|
|
+ 2882 = SymTab.ClChar)
|
|
|
+ 2883 OR (cls
|
|
|
+ 2884 = SymTab.ClEnum)
|
|
|
+ 2885 OR (cls
|
|
|
+ 2886 = SymTab.ClLong)
|
|
|
+ 2887 OR (cls = SymTab.ClBool))
|
|
|
+ 2888 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 2889 AND QbeGen.IsImm(cv) THEN
|
|
|
+ 2890 QbeGen.CopyOp(cv, q)
|
|
|
+ 2891 ELSE
|
|
|
+ 2892 QbeGen.LoadVar(n,
|
|
|
+ 2893 cls = SymTab.ClReal,
|
|
|
+ 2894 q)
|
|
|
2895 END
|
|
|
- 2896 ELSE
|
|
|
- 2897 IF t #
|
|
|
- 2898 SymTab.InvalidType THEN
|
|
|
- 2899 SemError(230)
|
|
|
- 2900 END;
|
|
|
- 2901 QbeGen.CopyOp("0", q)
|
|
|
- 2902 END
|
|
|
- 2903 END
|
|
|
- 2904 ELSIF (k = SymTab.KindVar)
|
|
|
- 2905 OR (k = SymTab.KindParam) THEN
|
|
|
- 2906 cls := SymTab.ClassOf(t);
|
|
|
- 2907 IF (cls # SymTab.ClInt)
|
|
|
- 2908 AND (cls # SymTab.ClBool)
|
|
|
- 2909 AND (cls # SymTab.ClChar)
|
|
|
- 2910 AND (cls # SymTab.ClUChar)
|
|
|
- 2911 AND (cls # SymTab.ClEnum)
|
|
|
- 2912 AND (cls # SymTab.ClReal)
|
|
|
- 2913 AND (cls # SymTab.ClPtr)
|
|
|
- 2914 AND (cls # SymTab.ClProc)
|
|
|
- 2915 AND (cls # SymTab.ClLong)
|
|
|
- 2916 AND (cls # SymTab.ClArray)
|
|
|
- 2917 AND (cls # SymTab.ClSet)
|
|
|
- 2918 AND (cls # SymTab.ClRecord)
|
|
|
- 2919 AND (cls # SymTab.ClUStr)
|
|
|
- 2920 AND (cls # SymTab.ClClass) THEN
|
|
|
- 2921 SemError(230);
|
|
|
- 2922 QbeGen.CopyOp("0", q)
|
|
|
- 2923 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 2924 END
|
|
|
- 2925 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 2926 IF k = SymTab.KindImport THEN
|
|
|
- 2927 SemError(230)
|
|
|
- 2928 ELSIF k =
|
|
|
- 2929 SymTab.KindProc THEN
|
|
|
- 2930 (* bare procedure name:
|
|
|
- 2931 a following ArgList
|
|
|
- 2932 makes it a call;
|
|
|
- 2933 otherwise Fact
|
|
|
- 2934 reports 230 *)
|
|
|
- 2935 ELSE
|
|
|
- 2936 IF k = SymTab.KindField THEN
|
|
|
- 2937 IF QbeGen.TopWith(qb) THEN
|
|
|
- 2938 sfx := TRUE
|
|
|
- 2939 ELSE SemError(230);
|
|
|
- 2940 QbeGen.CopyOp("0", q)
|
|
|
- 2941 END
|
|
|
- 2942 END
|
|
|
- 2943 END
|
|
|
- 2944 END
|
|
|
- 2945 END; .)
|
|
|
- 2946 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
- 2947 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
- 2948 { "[" Expr<it, iq>
|
|
|
- 2949 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2950 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2951 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2952 SymTab.ClArray THEN
|
|
|
- 2953 SemError(217);
|
|
|
- 2954 t := SymTab.InvalidType
|
|
|
- 2955 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2956 AND (SymTab.ClassOf(it) #
|
|
|
- 2957 SymTab.ClChar)
|
|
|
- 2958 AND (SymTab.ClassOf(it) #
|
|
|
- 2959 SymTab.ClEnum)
|
|
|
- 2960 AND (SymTab.ClassOf(it) #
|
|
|
- 2961 SymTab.ClBool) THEN
|
|
|
- 2962 SemError(218);
|
|
|
- 2963 t := SymTab.InvalidType
|
|
|
- 2964 ELSE
|
|
|
- 2965 eT := SymTab.ArrayElem(t);
|
|
|
- 2966 t := eT; sfx := TRUE
|
|
|
- 2967 END; .)
|
|
|
- 2968 { "," Expr<it, iq>
|
|
|
- 2969 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2970 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2971 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2972 SymTab.ClArray THEN
|
|
|
- 2973 SemError(217);
|
|
|
- 2974 t := SymTab.InvalidType
|
|
|
- 2975 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2976 AND (SymTab.ClassOf(it) #
|
|
|
- 2977 SymTab.ClChar)
|
|
|
- 2978 AND (SymTab.ClassOf(it) #
|
|
|
- 2979 SymTab.ClEnum)
|
|
|
- 2980 AND (SymTab.ClassOf(it) #
|
|
|
- 2981 SymTab.ClBool) THEN
|
|
|
- 2982 SemError(218);
|
|
|
- 2983 t := SymTab.InvalidType
|
|
|
- 2984 ELSE
|
|
|
- 2985 eT := SymTab.ArrayElem(t);
|
|
|
- 2986 t := eT; sfx := TRUE
|
|
|
- 2987 END; .) }
|
|
|
- 2988 "]"
|
|
|
- 2989 | "." GetIdent<fn>
|
|
|
- 2990 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2991 AST.SetOp(astSel, AST.SelField);
|
|
|
- 2992 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
- 2993 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
- 2994 (* qualified L.x: materialize
|
|
|
- 2995 the export, then load it *)
|
|
|
- 2996 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 2997 fn, mal) THEN
|
|
|
- 2998 SemError(201);
|
|
|
- 2999 t := SymTab.InvalidType;
|
|
|
- 3000 QbeGen.CopyOp("0", q)
|
|
|
- 3001 ELSE
|
|
|
- 3002 QbeGen.CopyOp(mal, qn);
|
|
|
- 3003 t := SymTab.SymType(mal);
|
|
|
- 3004 k := SymTab.SymKind(mal);
|
|
|
- 3005 sfx := FALSE;
|
|
|
- 3006 IF k = SymTab.KindProc THEN
|
|
|
- 3007 (* call: ArgList supplies
|
|
|
- 3008 the value *)
|
|
|
- 3009 QbeGen.CopyOp("0", q)
|
|
|
- 3010 ELSIF k = SymTab.KindConst THEN
|
|
|
- 3011 IF SymTab.GetSymVal(mal,
|
|
|
- 3012 cv)
|
|
|
- 3013 THEN QbeGen.CopyOp(cv, q)
|
|
|
- 3014 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3015 END
|
|
|
- 3016 END
|
|
|
- 3017 END
|
|
|
- 3018 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 3019 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 3020 SymTab.ClRecord)
|
|
|
- 3021 AND (SymTab.ClassOf(t) #
|
|
|
- 3022 SymTab.ClClass) THEN
|
|
|
- 3023 SemError(215);
|
|
|
- 3024 t := SymTab.InvalidType
|
|
|
- 3025 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 3026 SymTab.ClClass)
|
|
|
- 3027 AND SymTab.MethodExists(t, fn) THEN
|
|
|
- 3028 (* obj.Method: bind the
|
|
|
- 3029 method and pass obj as
|
|
|
- 3030 the hidden receiver; q
|
|
|
- 3031 already holds the
|
|
|
- 3032 object's address *)
|
|
|
- 3033 QbeGen.CopyOp(fn, n);
|
|
|
- 3034 QbeGen.CopyOp(fn, qn);
|
|
|
- 3035 methCls := t;
|
|
|
- 3036 k := SymTab.KindProc;
|
|
|
- 3037 t := SymTab.InvalidType
|
|
|
- 3038 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 3039 fn) THEN
|
|
|
- 3040 SemError(216);
|
|
|
- 3041 t := SymTab.InvalidType
|
|
|
- 3042 ELSE
|
|
|
- 3043 t := SymTab.FieldType(t, fn);
|
|
|
- 3044 sfx := TRUE
|
|
|
- 3045 END; .)
|
|
|
- 3046 | "^"
|
|
|
- 3047 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 3048 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 3049 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 3050 ELSIF SymTab.ClassOf(t) #
|
|
|
- 3051 SymTab.ClPtr THEN
|
|
|
- 3052 SemError(219);
|
|
|
- 3053 t := SymTab.InvalidType
|
|
|
- 3054 ELSE
|
|
|
- 3055 bt := SymTab.PtrBase(t);
|
|
|
- 3056 IF bt = SymTab.InvalidType THEN
|
|
|
- 3057 ELSE
|
|
|
- 3058 t := bt;
|
|
|
- 3059 sfx := TRUE
|
|
|
- 3060 END
|
|
|
- 3061 END; .) } (. astCur := astDes; .) .
|
|
|
- 3062 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
- 3063 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
- 3064 (a value, or a descriptor address for aggregates); each component
|
|
|
- 3065 descends one level exactly like the Design components. *)
|
|
|
- 3066 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 3067 VAR sfx: BOOLEAN; VAR node: AST.Node;
|
|
|
- 3068 VAR mname: SymTab.Name; VAR methCls: SymTab.TypeIndex;
|
|
|
- 3069 VAR isM: BOOLEAN> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
- 3070 iq, ql, qlo, qhi, qe, qb:
|
|
|
- 3071 QbeGen.QVal;
|
|
|
- 3072 lo, hi, fo: INTEGER;
|
|
|
- 3073 isOpen: BOOLEAN;
|
|
|
- 3074 fname: SymTab.Name;
|
|
|
- 3075 astWrap, astSel: AST.Node; .)
|
|
|
- 3076 = "[" Expr<it, iq>
|
|
|
- 3077 (. isM := FALSE;
|
|
|
- 3078 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 3079 astWrap := AST.MakeNode(
|
|
|
- 3080 AST.NkDesignator);
|
|
|
- 3081 AST.SetChild(astWrap, 0, node);
|
|
|
- 3082 node := astWrap
|
|
|
- 3083 END;
|
|
|
- 3084 AST.SetChild(node, AST.NChild(node),
|
|
|
- 3085 AST.MakeUn(AST.NkSelector,
|
|
|
- 3086 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 3087 ELSIF SymTab.ClassOf(t) #
|
|
|
- 3088 SymTab.ClArray THEN
|
|
|
- 3089 SemError(217);
|
|
|
- 3090 t := SymTab.InvalidType
|
|
|
- 3091 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 3092 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
- 3093 AND (SymTab.ClassOf(it) # SymTab.ClEnum)
|
|
|
- 3094 AND (SymTab.ClassOf(it) # SymTab.ClBool) THEN
|
|
|
- 3095 SemError(218);
|
|
|
- 3096 t := SymTab.InvalidType
|
|
|
- 3097 ELSE
|
|
|
- 3098 eT := SymTab.ArrayElem(t);
|
|
|
- 3099 t := eT; sfx := TRUE
|
|
|
- 3100 END; .)
|
|
|
- 3101 "]"
|
|
|
- 3102 | "." GetIdent<fname>
|
|
|
- 3103 (. isM := FALSE;
|
|
|
- 3104 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 3105 astWrap := AST.MakeNode(
|
|
|
- 3106 AST.NkDesignator);
|
|
|
- 3107 AST.SetChild(astWrap, 0, node);
|
|
|
- 3108 node := astWrap
|
|
|
- 3109 END;
|
|
|
- 3110 AST.SetChild(node, AST.NChild(node),
|
|
|
- 3111 AST.MakeUn(AST.NkSelector,
|
|
|
- 3112 AST.SelField,
|
|
|
- 3113 AST.MakeLeaf(AST.NkIdent,
|
|
|
- 3114 fname))); IF t = SymTab.InvalidType THEN
|
|
|
- 3115 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 3116 SymTab.ClRecord)
|
|
|
- 3117 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 3118 SemError(215);
|
|
|
- 3119 t := SymTab.InvalidType
|
|
|
- 3120 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 3121 SymTab.ClClass)
|
|
|
- 3122 AND SymTab.MethodExists(t, fname) THEN
|
|
|
- 3123 (* a method on the call result:
|
|
|
- 3124 a following ArgList makes
|
|
|
- 3125 the call *)
|
|
|
- 3126 mname := fname;
|
|
|
- 3127 methCls := t; isM := TRUE;
|
|
|
- 3128 t := SymTab.InvalidType
|
|
|
- 3129 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 3130 fname) THEN
|
|
|
- 3131 SemError(216);
|
|
|
- 3132 t := SymTab.InvalidType
|
|
|
- 3133 ELSE
|
|
|
- 3134 t := SymTab.FieldType(t, fname);
|
|
|
- 3135 sfx := TRUE
|
|
|
- 3136 END; .)
|
|
|
- 3137 | "^" (. isM := FALSE;
|
|
|
- 3138 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 3139 astWrap := AST.MakeNode(
|
|
|
- 3140 AST.NkDesignator);
|
|
|
- 3141 AST.SetChild(astWrap, 0, node);
|
|
|
- 3142 node := astWrap
|
|
|
- 3143 END;
|
|
|
- 3144 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 3145 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 3146 AST.SetChild(node,
|
|
|
- 3147 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 3148 ELSIF SymTab.ClassOf(t) #
|
|
|
- 3149 SymTab.ClPtr THEN
|
|
|
- 3150 SemError(219);
|
|
|
- 3151 t := SymTab.InvalidType
|
|
|
- 3152 ELSE
|
|
|
- 3153 bt := SymTab.PtrBase(t);
|
|
|
- 3154 IF bt # SymTab.InvalidType THEN
|
|
|
- 3155 t := bt; sfx := TRUE
|
|
|
- 3156 END
|
|
|
- 3157 END; .) .
|
|
|
- 3158 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3159 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 3160 op: INTEGER;
|
|
|
- 3161 q2, qt, wl: QbeGen.QVal;
|
|
|
- 3162 astA, astB: AST.Node;
|
|
|
- 3163 astOp: INTEGER;
|
|
|
- 3164 astMade: BOOLEAN;
|
|
|
- 3165 isR: BOOLEAN; .)
|
|
|
- 3166 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
- 3167 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 3168 (. astB := astCur; astMade := TRUE;
|
|
|
- 3169 astOp := AST.OpEq;
|
|
|
- 3170 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
- 3171 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
- 3172 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
- 3173 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
- 3174 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
- 3175 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
- 3176 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
- 3177 END;
|
|
|
- 3178 IF op = SymTab.OpIn THEN
|
|
|
- 3179 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 3180 IF (t = SymTab.InvalidType)
|
|
|
- 3181 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 3182 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 3183 ELSE
|
|
|
- 3184 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 3185 END
|
|
|
- 3186 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 3187 QbeGen.CopyOp("0", q)
|
|
|
- 3188 END
|
|
|
- 3189 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 3190 IF (t = SymTab.InvalidType)
|
|
|
- 3191 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 3192 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 3193 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 3194 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 3195 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 3196 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 3197 SemError(213); t := SymTab.InvalidType;
|
|
|
- 3198 QbeGen.CopyOp("0", q)
|
|
|
- 3199 ELSE
|
|
|
- 3200 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 3201 END
|
|
|
- 3202 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 3203 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 3204 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 3205 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 3206 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 3207 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 3208 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 3209 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 3210 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 3211 ELSE
|
|
|
- 3212 t := SymTab.BoolType();
|
|
|
- 3213 QbeGen.CopyOp("@", q)
|
|
|
- 3214 END
|
|
|
- 3215 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 3216 QbeGen.CopyOp("0", q)
|
|
|
- 3217 END;
|
|
|
- 3218 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
- 3219 (. IF NOT astMade THEN astCur := astA END; .)
|
|
|
- 3220 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 3221 Rel<VAR op: INTEGER>
|
|
|
- 3222 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 3223 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 3224 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 3225 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 3226 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 3227 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 3228 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 3229 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3230 (. VAR t2, res2, lt, rt:
|
|
|
- 3231 SymTab.TypeIndex;
|
|
|
- 3232 op: INTEGER;
|
|
|
- 3233 q2, qt, wq, qf, q2a, q2b:
|
|
|
- 3234 QbeGen.QVal;
|
|
|
- 3235 neg, isR, isL, folded:
|
|
|
- 3236 BOOLEAN;
|
|
|
- 3237 fok: BOOLEAN;
|
|
|
- 3238 lw, rw, mw: CARDINAL;
|
|
|
- 3239 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 3240 astA, astB: AST.Node;
|
|
|
- 3241 astSign, astOp: INTEGER; .)
|
|
|
- 3242 = (. neg := FALSE; astSign := 0; .)
|
|
|
- 3243 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
- 3244 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
- 3245 Term<t, q> (. astA := astCur;
|
|
|
- 3246 IF neg AND QbeGen.IsImm(q) THEN
|
|
|
- 3247 QbeGen.NegFold(q, q)
|
|
|
- 3248 END;
|
|
|
- 3249 IF astSign < 0 THEN
|
|
|
- 3250 astCur := AST.MakeUn(
|
|
|
- 3251 AST.NkUnary, AST.OpSub, astA);
|
|
|
- 3252 astA := astCur
|
|
|
- 3253 END; .)
|
|
|
- 3254 { AddOp<op>
|
|
|
- 3255 Term<t2, q2> (. astB := astCur; .)
|
|
|
- 3256 (. astOp := AST.OpAdd;
|
|
|
- 3257 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
- 3258 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
- 3259 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 3260 astCur := astA;
|
|
|
- 3261 IF op = SymTab.OpOr THEN
|
|
|
- 3262 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 3263 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 3264 t := SymTab.BoolType()
|
|
|
- 3265 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 3266 IF t # SymTab.InvalidType THEN
|
|
|
- 3267 QbeGen.CopyOp("@", q)
|
|
|
- 3268 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3269 END
|
|
|
- 3270 ELSIF (op = SymTab.OpAdd)
|
|
|
- 3271 AND (SymTab.UStrCompat(t, t2)
|
|
|
- 3272 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 3273 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
- 3274 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
- 3275 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
- 3276 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 3277 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
- 3278 (* UString concatenation: a UCHAR operand becomes a
|
|
|
- 3279 1-codepoint UString; the result is a descriptor in the
|
|
|
- 3280 shim's concat buffer. Work on copies so neither
|
|
|
- 3281 operand is clobbered. *)
|
|
|
- 3282 t := SymTab.NewUStr();
|
|
|
- 3283 QbeGen.CopyOp("@", q)
|
|
|
+ 2896 ELSIF (cls = SymTab.ClArray)
|
|
|
+ 2897 OR (cls = SymTab.ClRecord)
|
|
|
+ 2898 OR (cls = SymTab.ClClass)
|
|
|
+ 2899 OR (cls = SymTab.ClStr)
|
|
|
+ 2900 OR (cls = SymTab.ClUStr)
|
|
|
+ 2901 OR (cls = SymTab.ClSet) THEN
|
|
|
+ 2902 (* aggregate constant:
|
|
|
+ 2903 its value IS the
|
|
|
+ 2904 descriptor address *)
|
|
|
+ 2905 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 2906 QbeGen.CopyOp(cv, q)
|
|
|
+ 2907 ELSE
|
|
|
+ 2908 QbeGen.CopyOp("0", q)
|
|
|
+ 2909 END
|
|
|
+ 2910 ELSE
|
|
|
+ 2911 IF t #
|
|
|
+ 2912 SymTab.InvalidType THEN
|
|
|
+ 2913 SemError(230)
|
|
|
+ 2914 END;
|
|
|
+ 2915 QbeGen.CopyOp("0", q)
|
|
|
+ 2916 END
|
|
|
+ 2917 END
|
|
|
+ 2918 ELSIF (k = SymTab.KindVar)
|
|
|
+ 2919 OR (k = SymTab.KindParam) THEN
|
|
|
+ 2920 cls := SymTab.ClassOf(t);
|
|
|
+ 2921 IF (cls # SymTab.ClInt)
|
|
|
+ 2922 AND (cls # SymTab.ClBool)
|
|
|
+ 2923 AND (cls # SymTab.ClChar)
|
|
|
+ 2924 AND (cls # SymTab.ClUChar)
|
|
|
+ 2925 AND (cls # SymTab.ClEnum)
|
|
|
+ 2926 AND (cls # SymTab.ClReal)
|
|
|
+ 2927 AND (cls # SymTab.ClPtr)
|
|
|
+ 2928 AND (cls # SymTab.ClProc)
|
|
|
+ 2929 AND (cls # SymTab.ClLong)
|
|
|
+ 2930 AND (cls # SymTab.ClArray)
|
|
|
+ 2931 AND (cls # SymTab.ClSet)
|
|
|
+ 2932 AND (cls # SymTab.ClRecord)
|
|
|
+ 2933 AND (cls # SymTab.ClUStr)
|
|
|
+ 2934 AND (cls # SymTab.ClClass) THEN
|
|
|
+ 2935 SemError(230);
|
|
|
+ 2936 QbeGen.CopyOp("0", q)
|
|
|
+ 2937 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 2938 END
|
|
|
+ 2939 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 2940 IF k = SymTab.KindImport THEN
|
|
|
+ 2941 SemError(230)
|
|
|
+ 2942 ELSIF k =
|
|
|
+ 2943 SymTab.KindProc THEN
|
|
|
+ 2944 (* bare procedure name:
|
|
|
+ 2945 a following ArgList
|
|
|
+ 2946 makes it a call;
|
|
|
+ 2947 otherwise Fact
|
|
|
+ 2948 reports 230 *)
|
|
|
+ 2949 ELSE
|
|
|
+ 2950 IF k = SymTab.KindField THEN
|
|
|
+ 2951 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 2952 sfx := TRUE
|
|
|
+ 2953 ELSE SemError(230);
|
|
|
+ 2954 QbeGen.CopyOp("0", q)
|
|
|
+ 2955 END
|
|
|
+ 2956 END
|
|
|
+ 2957 END
|
|
|
+ 2958 END
|
|
|
+ 2959 END; .)
|
|
|
+ 2960 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
+ 2961 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
+ 2962 { "[" Expr<it, iq>
|
|
|
+ 2963 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2964 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2965 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2966 SymTab.ClArray THEN
|
|
|
+ 2967 SemError(217);
|
|
|
+ 2968 t := SymTab.InvalidType
|
|
|
+ 2969 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2970 AND (SymTab.ClassOf(it) #
|
|
|
+ 2971 SymTab.ClChar)
|
|
|
+ 2972 AND (SymTab.ClassOf(it) #
|
|
|
+ 2973 SymTab.ClEnum)
|
|
|
+ 2974 AND (SymTab.ClassOf(it) #
|
|
|
+ 2975 SymTab.ClBool) THEN
|
|
|
+ 2976 SemError(218);
|
|
|
+ 2977 t := SymTab.InvalidType
|
|
|
+ 2978 ELSE
|
|
|
+ 2979 eT := SymTab.ArrayElem(t);
|
|
|
+ 2980 t := eT; sfx := TRUE
|
|
|
+ 2981 END; .)
|
|
|
+ 2982 { "," Expr<it, iq>
|
|
|
+ 2983 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2984 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2985 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2986 SymTab.ClArray THEN
|
|
|
+ 2987 SemError(217);
|
|
|
+ 2988 t := SymTab.InvalidType
|
|
|
+ 2989 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2990 AND (SymTab.ClassOf(it) #
|
|
|
+ 2991 SymTab.ClChar)
|
|
|
+ 2992 AND (SymTab.ClassOf(it) #
|
|
|
+ 2993 SymTab.ClEnum)
|
|
|
+ 2994 AND (SymTab.ClassOf(it) #
|
|
|
+ 2995 SymTab.ClBool) THEN
|
|
|
+ 2996 SemError(218);
|
|
|
+ 2997 t := SymTab.InvalidType
|
|
|
+ 2998 ELSE
|
|
|
+ 2999 eT := SymTab.ArrayElem(t);
|
|
|
+ 3000 t := eT; sfx := TRUE
|
|
|
+ 3001 END; .) }
|
|
|
+ 3002 "]"
|
|
|
+ 3003 | "." GetIdent<fn>
|
|
|
+ 3004 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 3005 AST.SetOp(astSel, AST.SelField);
|
|
|
+ 3006 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
+ 3007 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
+ 3008 (* qualified L.x: materialize
|
|
|
+ 3009 the export, then load it *)
|
|
|
+ 3010 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 3011 fn, mal) THEN
|
|
|
+ 3012 SemError(201);
|
|
|
+ 3013 t := SymTab.InvalidType;
|
|
|
+ 3014 QbeGen.CopyOp("0", q)
|
|
|
+ 3015 ELSE
|
|
|
+ 3016 QbeGen.CopyOp(mal, qn);
|
|
|
+ 3017 t := SymTab.SymType(mal);
|
|
|
+ 3018 k := SymTab.SymKind(mal);
|
|
|
+ 3019 sfx := FALSE;
|
|
|
+ 3020 IF k = SymTab.KindProc THEN
|
|
|
+ 3021 (* call: ArgList supplies
|
|
|
+ 3022 the value *)
|
|
|
+ 3023 QbeGen.CopyOp("0", q)
|
|
|
+ 3024 ELSIF k = SymTab.KindConst THEN
|
|
|
+ 3025 IF SymTab.GetSymVal(mal,
|
|
|
+ 3026 cv)
|
|
|
+ 3027 THEN QbeGen.CopyOp(cv, q)
|
|
|
+ 3028 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3029 END
|
|
|
+ 3030 END
|
|
|
+ 3031 END
|
|
|
+ 3032 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 3033 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 3034 SymTab.ClRecord)
|
|
|
+ 3035 AND (SymTab.ClassOf(t) #
|
|
|
+ 3036 SymTab.ClClass) THEN
|
|
|
+ 3037 SemError(215);
|
|
|
+ 3038 t := SymTab.InvalidType
|
|
|
+ 3039 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 3040 SymTab.ClClass)
|
|
|
+ 3041 AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ 3042 (* obj.Method: bind the
|
|
|
+ 3043 method and pass obj as
|
|
|
+ 3044 the hidden receiver; q
|
|
|
+ 3045 already holds the
|
|
|
+ 3046 object's address *)
|
|
|
+ 3047 QbeGen.CopyOp(fn, n);
|
|
|
+ 3048 QbeGen.CopyOp(fn, qn);
|
|
|
+ 3049 methCls := t;
|
|
|
+ 3050 k := SymTab.KindProc;
|
|
|
+ 3051 t := SymTab.InvalidType
|
|
|
+ 3052 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 3053 fn) THEN
|
|
|
+ 3054 SemError(216);
|
|
|
+ 3055 t := SymTab.InvalidType
|
|
|
+ 3056 ELSE
|
|
|
+ 3057 t := SymTab.FieldType(t, fn);
|
|
|
+ 3058 sfx := TRUE
|
|
|
+ 3059 END; .)
|
|
|
+ 3060 | "^"
|
|
|
+ 3061 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 3062 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 3063 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 3064 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 3065 SymTab.ClPtr THEN
|
|
|
+ 3066 SemError(219);
|
|
|
+ 3067 t := SymTab.InvalidType
|
|
|
+ 3068 ELSE
|
|
|
+ 3069 bt := SymTab.PtrBase(t);
|
|
|
+ 3070 IF bt = SymTab.InvalidType THEN
|
|
|
+ 3071 ELSE
|
|
|
+ 3072 t := bt;
|
|
|
+ 3073 sfx := TRUE
|
|
|
+ 3074 END
|
|
|
+ 3075 END; .) } (. astCur := astDes; .) .
|
|
|
+ 3076 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
+ 3077 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
+ 3078 (a value, or a descriptor address for aggregates); each component
|
|
|
+ 3079 descends one level exactly like the Design components. *)
|
|
|
+ 3080 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 3081 VAR sfx: BOOLEAN; VAR node: AST.Node;
|
|
|
+ 3082 VAR mname: SymTab.Name; VAR methCls: SymTab.TypeIndex;
|
|
|
+ 3083 VAR isM: BOOLEAN> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
+ 3084 iq, ql, qlo, qhi, qe, qb:
|
|
|
+ 3085 QbeGen.QVal;
|
|
|
+ 3086 lo, hi, fo: INTEGER;
|
|
|
+ 3087 isOpen: BOOLEAN;
|
|
|
+ 3088 fname: SymTab.Name;
|
|
|
+ 3089 astWrap, astSel: AST.Node; .)
|
|
|
+ 3090 = "[" Expr<it, iq>
|
|
|
+ 3091 (. isM := FALSE;
|
|
|
+ 3092 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 3093 astWrap := AST.MakeNode(
|
|
|
+ 3094 AST.NkDesignator);
|
|
|
+ 3095 AST.SetChild(astWrap, 0, node);
|
|
|
+ 3096 node := astWrap
|
|
|
+ 3097 END;
|
|
|
+ 3098 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 3099 AST.MakeUn(AST.NkSelector,
|
|
|
+ 3100 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 3101 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 3102 SymTab.ClArray THEN
|
|
|
+ 3103 SemError(217);
|
|
|
+ 3104 t := SymTab.InvalidType
|
|
|
+ 3105 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 3106 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
+ 3107 AND (SymTab.ClassOf(it) # SymTab.ClEnum)
|
|
|
+ 3108 AND (SymTab.ClassOf(it) # SymTab.ClBool) THEN
|
|
|
+ 3109 SemError(218);
|
|
|
+ 3110 t := SymTab.InvalidType
|
|
|
+ 3111 ELSE
|
|
|
+ 3112 eT := SymTab.ArrayElem(t);
|
|
|
+ 3113 t := eT; sfx := TRUE
|
|
|
+ 3114 END; .)
|
|
|
+ 3115 "]"
|
|
|
+ 3116 | "." GetIdent<fname>
|
|
|
+ 3117 (. isM := FALSE;
|
|
|
+ 3118 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 3119 astWrap := AST.MakeNode(
|
|
|
+ 3120 AST.NkDesignator);
|
|
|
+ 3121 AST.SetChild(astWrap, 0, node);
|
|
|
+ 3122 node := astWrap
|
|
|
+ 3123 END;
|
|
|
+ 3124 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 3125 AST.MakeUn(AST.NkSelector,
|
|
|
+ 3126 AST.SelField,
|
|
|
+ 3127 AST.MakeLeaf(AST.NkIdent,
|
|
|
+ 3128 fname))); IF t = SymTab.InvalidType THEN
|
|
|
+ 3129 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 3130 SymTab.ClRecord)
|
|
|
+ 3131 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 3132 SemError(215);
|
|
|
+ 3133 t := SymTab.InvalidType
|
|
|
+ 3134 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 3135 SymTab.ClClass)
|
|
|
+ 3136 AND SymTab.MethodExists(t, fname) THEN
|
|
|
+ 3137 (* a method on the call result:
|
|
|
+ 3138 a following ArgList makes
|
|
|
+ 3139 the call *)
|
|
|
+ 3140 mname := fname;
|
|
|
+ 3141 methCls := t; isM := TRUE;
|
|
|
+ 3142 t := SymTab.InvalidType
|
|
|
+ 3143 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 3144 fname) THEN
|
|
|
+ 3145 SemError(216);
|
|
|
+ 3146 t := SymTab.InvalidType
|
|
|
+ 3147 ELSE
|
|
|
+ 3148 t := SymTab.FieldType(t, fname);
|
|
|
+ 3149 sfx := TRUE
|
|
|
+ 3150 END; .)
|
|
|
+ 3151 | "^" (. isM := FALSE;
|
|
|
+ 3152 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 3153 astWrap := AST.MakeNode(
|
|
|
+ 3154 AST.NkDesignator);
|
|
|
+ 3155 AST.SetChild(astWrap, 0, node);
|
|
|
+ 3156 node := astWrap
|
|
|
+ 3157 END;
|
|
|
+ 3158 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 3159 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 3160 AST.SetChild(node,
|
|
|
+ 3161 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 3162 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 3163 SymTab.ClPtr THEN
|
|
|
+ 3164 SemError(219);
|
|
|
+ 3165 t := SymTab.InvalidType
|
|
|
+ 3166 ELSE
|
|
|
+ 3167 bt := SymTab.PtrBase(t);
|
|
|
+ 3168 IF bt # SymTab.InvalidType THEN
|
|
|
+ 3169 t := bt; sfx := TRUE
|
|
|
+ 3170 END
|
|
|
+ 3171 END; .) .
|
|
|
+ 3172 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3173 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 3174 op: INTEGER;
|
|
|
+ 3175 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 3176 astA, astB: AST.Node;
|
|
|
+ 3177 astOp: INTEGER;
|
|
|
+ 3178 astMade: BOOLEAN;
|
|
|
+ 3179 isR: BOOLEAN; .)
|
|
|
+ 3180 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
+ 3181 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 3182 (. astB := astCur; astMade := TRUE;
|
|
|
+ 3183 astOp := AST.OpEq;
|
|
|
+ 3184 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
+ 3185 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
+ 3186 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
+ 3187 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
+ 3188 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
+ 3189 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
+ 3190 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
+ 3191 END;
|
|
|
+ 3192 IF op = SymTab.OpIn THEN
|
|
|
+ 3193 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 3194 IF (t = SymTab.InvalidType)
|
|
|
+ 3195 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 3196 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 3197 ELSE
|
|
|
+ 3198 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 3199 END
|
|
|
+ 3200 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 3201 QbeGen.CopyOp("0", q)
|
|
|
+ 3202 END
|
|
|
+ 3203 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 3204 IF (t = SymTab.InvalidType)
|
|
|
+ 3205 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 3206 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 3207 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 3208 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 3209 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 3210 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 3211 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 3212 QbeGen.CopyOp("0", q)
|
|
|
+ 3213 ELSE
|
|
|
+ 3214 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 3215 END
|
|
|
+ 3216 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 3217 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 3218 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 3219 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 3220 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 3221 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 3222 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 3223 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 3224 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 3225 ELSE
|
|
|
+ 3226 t := SymTab.BoolType();
|
|
|
+ 3227 QbeGen.CopyOp("@", q)
|
|
|
+ 3228 END
|
|
|
+ 3229 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 3230 QbeGen.CopyOp("0", q)
|
|
|
+ 3231 END;
|
|
|
+ 3232 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
+ 3233 (. IF NOT astMade THEN astCur := astA END; .)
|
|
|
+ 3234 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 3235 Rel<VAR op: INTEGER>
|
|
|
+ 3236 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 3237 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 3238 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 3239 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 3240 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 3241 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 3242 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 3243 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3244 (. VAR t2, res2, lt, rt:
|
|
|
+ 3245 SymTab.TypeIndex;
|
|
|
+ 3246 op: INTEGER;
|
|
|
+ 3247 q2, qt, wq, qf, q2a, q2b:
|
|
|
+ 3248 QbeGen.QVal;
|
|
|
+ 3249 neg, isR, isL, folded:
|
|
|
+ 3250 BOOLEAN;
|
|
|
+ 3251 fok: BOOLEAN;
|
|
|
+ 3252 lw, rw, mw: CARDINAL;
|
|
|
+ 3253 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 3254 astA, astB: AST.Node;
|
|
|
+ 3255 astSign, astOp: INTEGER; .)
|
|
|
+ 3256 = (. neg := FALSE; astSign := 0; .)
|
|
|
+ 3257 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
+ 3258 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
+ 3259 Term<t, q> (. astA := astCur;
|
|
|
+ 3260 IF neg AND QbeGen.IsImm(q) THEN
|
|
|
+ 3261 QbeGen.NegFold(q, q)
|
|
|
+ 3262 END;
|
|
|
+ 3263 IF astSign < 0 THEN
|
|
|
+ 3264 astCur := AST.MakeUn(
|
|
|
+ 3265 AST.NkUnary, AST.OpSub, astA);
|
|
|
+ 3266 astA := astCur
|
|
|
+ 3267 END; .)
|
|
|
+ 3268 { AddOp<op>
|
|
|
+ 3269 Term<t2, q2> (. astB := astCur; .)
|
|
|
+ 3270 (. astOp := AST.OpAdd;
|
|
|
+ 3271 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
+ 3272 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
+ 3273 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 3274 astCur := astA;
|
|
|
+ 3275 IF op = SymTab.OpOr THEN
|
|
|
+ 3276 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 3277 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 3278 t := SymTab.BoolType()
|
|
|
+ 3279 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 3280 IF t # SymTab.InvalidType THEN
|
|
|
+ 3281 QbeGen.CopyOp("@", q)
|
|
|
+ 3282 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3283 END
|
|
|
3284 ELSIF (op = SymTab.OpAdd)
|
|
|
- 3285 AND (SymTab.StrCompat(t, t2)
|
|
|
- 3286 OR (SymTab.IsStrType(t)
|
|
|
- 3287 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 3288 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 3289 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 3290 (* string concatenation; a CHAR operand becomes a
|
|
|
- 3291 1-character string literal. When both operands are
|
|
|
- 3292 constants, fold to a single string literal so a
|
|
|
- 3293 constructor element stays compile-time. *)
|
|
|
- 3294 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
- 3295 qt, fok);
|
|
|
- 3296 IF fok THEN QbeGen.CopyOp(qt, q)
|
|
|
- 3297 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 3298 END;
|
|
|
- 3299 t := SymTab.NewStr()
|
|
|
- 3300 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 3301 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 3302 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 3303 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 3304 mw := lw;
|
|
|
- 3305 IF rw > mw THEN mw := rw END;
|
|
|
- 3306 t := SymTab.NewSet(
|
|
|
- 3307 SymTab.NewSubR(0,
|
|
|
- 3308 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 3309 QbeGen.CopyOp("@", q)
|
|
|
- 3310 ELSE
|
|
|
- 3311 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 3312 lt := t; rt := t2; t := res2
|
|
|
- 3313 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 3314 IF t # SymTab.InvalidType THEN
|
|
|
- 3315 isL := SymTab.IsLongFamily(t);
|
|
|
- 3316 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 3317 folded := FALSE;
|
|
|
- 3318 IF (NOT isL) AND (NOT isR)
|
|
|
- 3319 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 3320 IF op = SymTab.OpAdd THEN
|
|
|
- 3321 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 3322 ELSE
|
|
|
- 3323 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 3324 END
|
|
|
- 3325 END;
|
|
|
- 3326 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 3327 ELSE
|
|
|
- 3328 QbeGen.CopyOp("@", q)
|
|
|
- 3329 END
|
|
|
- 3330 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3331 END
|
|
|
- 3332 END; .) }
|
|
|
- 3333 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 3334 AddOp<VAR op: INTEGER>
|
|
|
- 3335 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 3336 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 3337 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 3338 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3339 (. VAR t2, res2, lt, rt:
|
|
|
- 3340 SymTab.TypeIndex;
|
|
|
- 3341 op: INTEGER;
|
|
|
- 3342 q2, qt, wq, qf:
|
|
|
- 3343 QbeGen.QVal;
|
|
|
- 3344 isR, isL, folded: BOOLEAN;
|
|
|
- 3345 lw, rw, mw: CARDINAL;
|
|
|
- 3346 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 3347 astA, astB: AST.Node;
|
|
|
- 3348 astOp: INTEGER; .)
|
|
|
- 3349 = Fact<t, q> (. astA := astCur; .) { MulOp<op>
|
|
|
- 3350 Fact<t2, q2> (. astB := astCur; .)
|
|
|
- 3351 (. astOp := AST.OpMul;
|
|
|
- 3352 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
- 3353 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
- 3354 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
- 3355 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
- 3356 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 3357 astCur := astA;
|
|
|
- 3358 IF op = SymTab.OpAnd THEN
|
|
|
- 3359 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 3360 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 3361 t := SymTab.BoolType()
|
|
|
- 3362 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 3363 IF t # SymTab.InvalidType THEN QbeGen.CopyOp("@", q)
|
|
|
- 3364 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3365 END
|
|
|
- 3366 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 3367 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 3368 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 3369 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 3370 mw := lw;
|
|
|
- 3371 IF rw > mw THEN mw := rw END;
|
|
|
- 3372 t := SymTab.NewSet(
|
|
|
- 3373 SymTab.NewSubR(0,
|
|
|
- 3374 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 3375 QbeGen.CopyOp("@", q)
|
|
|
- 3376 ELSE
|
|
|
- 3377 IF SymTab.ArithCheck(t, t2,
|
|
|
- 3378 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 3379 res2) THEN
|
|
|
- 3380 lt := t; rt := t2; t := res2
|
|
|
- 3381 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 3382 IF t # SymTab.InvalidType THEN
|
|
|
- 3383 isL := SymTab.IsLongFamily(t);
|
|
|
- 3384 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 3385 folded := FALSE;
|
|
|
- 3386 IF (NOT isL) AND (NOT isR)
|
|
|
- 3387 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 3388 IF op = SymTab.OpTimes THEN
|
|
|
- 3389 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 3390 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 3391 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 3392 ELSIF op = SymTab.OpMod THEN
|
|
|
- 3393 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 3394 END
|
|
|
- 3395 END;
|
|
|
- 3396 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 3397 ELSE
|
|
|
- 3398 QbeGen.CopyOp("@", q)
|
|
|
- 3399 END
|
|
|
- 3400 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3401 END
|
|
|
- 3402 END; .) }
|
|
|
- 3403 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 3404 MulOp<VAR op: INTEGER>
|
|
|
- 3405 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 3406 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 3407 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 3408 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 3409 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 3410 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3411 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 3412 et, dt, t2, st, ct2, et2:
|
|
|
- 3413 SymTab.TypeIndex;
|
|
|
- 3414 dk: INTEGER;
|
|
|
- 3415 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
- 3416 QbeGen.QVal;
|
|
|
- 3417 qn, vn: SymTab.Name;
|
|
|
- 3418 vt: SymTab.TypeIndex;
|
|
|
- 3419 c1, c2: INTEGER;
|
|
|
- 3420 lo, hi: INTEGER;
|
|
|
- 3421 isMax: BOOLEAN;
|
|
|
- 3422 called, isHigh, sfx, isCh,
|
|
|
- 3423 isU, uok, isStr: BOOLEAN;
|
|
|
- 3424 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
- 3425 astD: AST.Node;
|
|
|
- 3426 astCall: BOOLEAN;
|
|
|
- 3427 astNode, astNot: AST.Node;
|
|
|
- 3428 j: CARDINAL;
|
|
|
- 3429 astArg2: AST.Node;
|
|
|
- 3430 astBrace: AST.Node;
|
|
|
- 3431 astRes: AST.Node; mname: SymTab.Name; isM: BOOLEAN;
|
|
|
- 3432 isConvF: BOOLEAN;
|
|
|
- 3433 fi, fj: CARDINAL; .)
|
|
|
- 3434 = (. astIsLit := FALSE; .)
|
|
|
- 3435 ( "__LINE__" (. QbeGen.IntStr(M2S.line, q);
|
|
|
- 3436 astIsLit := TRUE;
|
|
|
- 3437 astCur := AST.MakeLeaf(
|
|
|
- 3438 AST.NkIntLit, q);
|
|
|
- 3439 t := SymTab.IntType(); .)
|
|
|
- 3440 | "__FILE__" (. (* fold to the quoted file name *)
|
|
|
- 3441 s[0] := '"'; fi := 1; fj := 0;
|
|
|
- 3442 WHILE (M2S.fileName[fj] # CHR(0))
|
|
|
- 3443 AND (fi < HIGH(s)) DO
|
|
|
- 3444 s[fi] := M2S.fileName[fj];
|
|
|
- 3445 INC(fi); INC(fj)
|
|
|
- 3446 END;
|
|
|
- 3447 s[fi] := '"';
|
|
|
- 3448 s[fi + 1] := CHR(0);
|
|
|
- 3449 astIsLit := TRUE;
|
|
|
- 3450 astCur := AST.MakeLeaf(
|
|
|
- 3451 AST.NkStrLit, s);
|
|
|
- 3452 t := SymTab.NewStr();
|
|
|
- 3453 QbeGen.DeclStr(s, q); .)
|
|
|
- 3454 | integer (. LexString(s);
|
|
|
- 3455 QbeGen.NormInt(s, q); astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s);
|
|
|
- 3456 t := SymTab.IntType(); .)
|
|
|
- 3457 | charConst (. LexString(s);
|
|
|
- 3458 QbeGen.NormLit(s, q, isCh);
|
|
|
- 3459 astIsLit := TRUE;
|
|
|
- 3460 astCur := AST.MakeLeaf(
|
|
|
- 3461 AST.NkCharLit, s);
|
|
|
- 3462 t := SymTab.CharType(); .)
|
|
|
- 3463 | real (. LexString(s);
|
|
|
- 3464 QbeGen.NormReal(s, q);
|
|
|
- 3465 astIsLit := TRUE;
|
|
|
- 3466 astCur := AST.MakeLeaf(
|
|
|
- 3467 AST.NkRealLit, s);
|
|
|
- 3468 t := SymTab.RealType(); .)
|
|
|
- 3469 | string (. LexString(s);
|
|
|
- 3470 astIsLit := TRUE;
|
|
|
- 3471 astCur := AST.MakeLeaf(
|
|
|
- 3472 AST.NkStrLit, s);
|
|
|
- 3473 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3474 t := SymTab.CharType();
|
|
|
- 3475 QbeGen.IntStr(
|
|
|
- 3476 QbeGen.CharVal(s), q)
|
|
|
- 3477 ELSE t := SymTab.NewStr();
|
|
|
- 3478 QbeGen.DeclStr(s, q);
|
|
|
- 3479 (* a literal's value IS its
|
|
|
- 3480 static descriptor address *)
|
|
|
- 3481 END; .)
|
|
|
- 3482 | ustring (. LexString(s);
|
|
|
- 3483 astIsLit := TRUE;
|
|
|
- 3484 astCur := AST.MakeLeaf(
|
|
|
- 3485 AST.NkStrLit, s);
|
|
|
- 3486 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 3487 uok);
|
|
|
- 3488 IF NOT uok THEN
|
|
|
- 3489 SemError(234);
|
|
|
- 3490 t := SymTab.InvalidType
|
|
|
- 3491 ELSIF isU THEN
|
|
|
- 3492 t := SymTab.UCharType();
|
|
|
- 3493 QbeGen.IntStr(ucp, q)
|
|
|
- 3494 ELSE
|
|
|
- 3495 t := SymTab.NewUStr();
|
|
|
- 3496 END; .)
|
|
|
- 3497 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
- 3498 astNArgs := 0; called := FALSE;
|
|
|
- 3499 t := dt;
|
|
|
- 3500 IF dk = SymTab.KindConst THEN
|
|
|
- 3501 QbeGen.CopyOp(qd, q)
|
|
|
- 3502 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 3503 END; .)
|
|
|
- 3504 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
- 3505 astBrace := astCur; .) ]
|
|
|
- 3506 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 3507 (. astCall := TRUE;
|
|
|
- 3508 IF (SymTab.SymKind(qn) = SymTab.KindType)
|
|
|
- 3509 OR (SymTab.SymKind(qn) = SymTab.KindPredef) THEN
|
|
|
- 3510 (* T(x): emit as the VAL builtin so Lower's
|
|
|
- 3511 conversion rules apply unchanged *)
|
|
|
- 3512 astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3513 AST.SetChild(astNode, 0,
|
|
|
- 3514 AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3515 AST.SetChild(astNode, 1,
|
|
|
- 3516 AST.MakeLeaf(AST.NkIdent, qn));
|
|
|
- 3517 IF astNArgs = 1 THEN
|
|
|
- 3518 AST.SetChild(astNode, 2, astArgs[0])
|
|
|
- 3519 END;
|
|
|
- 3520 isConvF := TRUE
|
|
|
- 3521 ELSE astNode := AstCallNode(astD)
|
|
|
- 3522 END;
|
|
|
- 3523 astRes := astNode;
|
|
|
- 3524 t := ct2;
|
|
|
- 3525 QbeGen.CopyOp(q2, q);
|
|
|
- 3526 IF isConvF AND QbeGen.IsImm(convQ)
|
|
|
- 3527 AND OrdClass(convT) AND OrdClass(ct2) THEN
|
|
|
- 3528 QbeGen.CopyOp(convQ, q)
|
|
|
- 3529 END;
|
|
|
- 3530 sfx := FALSE; .)
|
|
|
- 3531 { ResultComp<t, q, sfx, astRes, mname, methCls, isM>
|
|
|
- 3532 [ (. astNArgs := 0; .)
|
|
|
- 3533 ArgList<mname, t, q, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 3534 (. astNode := AstCallNode(astRes);
|
|
|
- 3535 astRes := astNode;
|
|
|
- 3536 t := ct2;
|
|
|
- 3537 QbeGen.CopyOp(q2, q);
|
|
|
- 3538 sfx := FALSE; .) ] }
|
|
|
- 3539 (. IF sfx THEN
|
|
|
- 3540 IF t = SymTab.InvalidType THEN
|
|
|
- 3541 QbeGen.CopyOp("0", q)
|
|
|
- 3542 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 3543 SymTab.ClRecord)
|
|
|
- 3544 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
- 3545 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
- 3546 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 3547 QbeGen.CopyOp("@", q)
|
|
|
- 3548 END
|
|
|
- 3549 END; .) ]
|
|
|
- 3550 (. IF called THEN
|
|
|
- 3551 astCur := astRes
|
|
|
- 3552 ELSIF astCall THEN
|
|
|
- 3553 astCur := astBrace
|
|
|
- 3554 ELSE astCur := astD
|
|
|
- 3555 END;
|
|
|
- 3556 astIsLit := TRUE;
|
|
|
- 3557 IF NOT called
|
|
|
- 3558 AND (dk = SymTab.KindProc) THEN
|
|
|
- 3559 (* bare zero-arg function
|
|
|
- 3560 call (parentheses may be
|
|
|
- 3561 omitted); a proper or
|
|
|
- 3562 parameterised proc here
|
|
|
- 3563 is 230 *)
|
|
|
- 3564 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 3565 AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
|
|
|
- 3566 t := SymTab.ProcRes(qn);
|
|
|
- 3567 QbeGen.CopyOp("@", q);
|
|
|
- 3568 astCur := AST.MakeNode(AST.NkCall);
|
|
|
- 3569 AST.SetChild(astCur, 0, astD)
|
|
|
- 3570 ELSE
|
|
|
- 3571 t := SymTab.ProcTypeOf(qn);
|
|
|
- 3572 QbeGen.CopyOp("@", q)
|
|
|
- 3573 END
|
|
|
- 3574 END; .)
|
|
|
- 3575 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 3576 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 3577 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
- 3578 isU := FALSE; .)
|
|
|
- 3579 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3580 isStr := TRUE;
|
|
|
- 3581 isU := FALSE;
|
|
|
- 3582 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3583 dt := SymTab.CharType();
|
|
|
- 3584 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 3585 qd)
|
|
|
- 3586 ELSE
|
|
|
- 3587 dt := SymTab.NewStr();
|
|
|
- 3588 QbeGen.DeclStr(s, qd);
|
|
|
- 3589 END;
|
|
|
- 3590 dk := -1;
|
|
|
- 3591 qn[0] := CHR(0); .)
|
|
|
- 3592 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3593 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
- 3594 uok);
|
|
|
- 3595 isStr := FALSE;
|
|
|
- 3596 IF NOT uok THEN
|
|
|
- 3597 SemError(234);
|
|
|
- 3598 dt := SymTab.InvalidType
|
|
|
- 3599 ELSIF isU THEN
|
|
|
- 3600 (* one codepoint: a UCHAR;
|
|
|
- 3601 LEN is 1, HIGH is 0 *)
|
|
|
- 3602 dt := SymTab.UCharType();
|
|
|
- 3603 QbeGen.IntStr(ucp, qd)
|
|
|
- 3604 ELSE
|
|
|
- 3605 dt := SymTab.NewUStr();
|
|
|
- 3606 END;
|
|
|
- 3607 dk := -1;
|
|
|
- 3608 qn[0] := CHR(0); .) )
|
|
|
- 3609 ")"
|
|
|
- 3610 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3611 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
- 3612 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
- 3613 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3614 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
- 3615 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3616 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3617 IF (dt # SymTab.InvalidType)
|
|
|
- 3618 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
- 3619 (* UString: the count is
|
|
|
- 3620 the descriptor header *)
|
|
|
- 3621 t := SymTab.IntType();
|
|
|
- 3622 QbeGen.CopyOp("@", q)
|
|
|
- 3623 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 3624 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
- 3625 (* single UCHAR codepoint *)
|
|
|
- 3626 IF isHigh THEN
|
|
|
- 3627 QbeGen.CopyOp("0", qr)
|
|
|
- 3628 ELSE
|
|
|
- 3629 QbeGen.CopyOp("1", qr)
|
|
|
- 3630 END;
|
|
|
- 3631 t := SymTab.IntType();
|
|
|
- 3632 QbeGen.CopyOp(qr, q)
|
|
|
- 3633 ELSIF isStr THEN
|
|
|
- 3634 (* fold: content length at
|
|
|
- 3635 compile time *)
|
|
|
- 3636 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3637 c1 := 1
|
|
|
- 3638 ELSE
|
|
|
- 3639 c1 :=
|
|
|
- 3640 SymTab.StrLen(s) - 2
|
|
|
- 3641 END;
|
|
|
- 3642 IF isHigh THEN
|
|
|
- 3643 DEC(c1)
|
|
|
- 3644 END;
|
|
|
- 3645 QbeGen.IntStr(c1, qr);
|
|
|
- 3646 t := SymTab.IntType();
|
|
|
- 3647 QbeGen.CopyOp(qr, q)
|
|
|
- 3648 ELSIF dt = SymTab.InvalidType THEN
|
|
|
- 3649 t := SymTab.InvalidType;
|
|
|
- 3650 QbeGen.CopyOp("0", q)
|
|
|
- 3651 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 3652 SymTab.ClArray THEN
|
|
|
- 3653 SemError(217);
|
|
|
- 3654 t := SymTab.InvalidType;
|
|
|
- 3655 QbeGen.CopyOp("0", q)
|
|
|
- 3656 ELSE
|
|
|
- 3657 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3658 t := SymTab.IntType();
|
|
|
- 3659 QbeGen.CopyOp("@", q)
|
|
|
- 3660 ELSE
|
|
|
- 3661 IF isHigh THEN
|
|
|
- 3662 QbeGen.IntStr(
|
|
|
- 3663 SymTab.ArrayHi(dt), qr)
|
|
|
- 3664 ELSE
|
|
|
- 3665 QbeGen.IntStr(VAL(
|
|
|
- 3666 INTEGER,
|
|
|
- 3667 SymTab.ArrayLen(dt)),
|
|
|
- 3668 qr)
|
|
|
- 3669 END;
|
|
|
- 3670 t := SymTab.IntType();
|
|
|
- 3671 QbeGen.CopyOp(qr, q)
|
|
|
- 3672 END
|
|
|
- 3673 END; .)
|
|
|
- 3674 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3675 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3676 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
- 3677 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3678 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3679 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3680 t := SymTab.InvalidType;
|
|
|
- 3681 QbeGen.CopyOp("0", q)
|
|
|
- 3682 ELSE
|
|
|
- 3683 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 3684 SymTab.ObjectSize(dt)), q);
|
|
|
- 3685 t := SymTab.IntType()
|
|
|
- 3686 END; .)
|
|
|
- 3687 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
- 3688 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
- 3689 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
- 3690 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3691 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3692 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
- 3693 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3694 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
- 3695 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3696 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3697 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3698 (* set shift/rotate: isMax
|
|
|
- 3699 doubles as "rotate" *)
|
|
|
- 3700 IF (et # SymTab.InvalidType)
|
|
|
- 3701 AND (SymTab.ClassOf(et) =
|
|
|
- 3702 SymTab.ClSet) THEN
|
|
|
- 3703 t := et;
|
|
|
- 3704 QbeGen.CopyOp("@", q)
|
|
|
- 3705 ELSE SemError(230);
|
|
|
- 3706 t := SymTab.InvalidType;
|
|
|
- 3707 QbeGen.CopyOp("0", q)
|
|
|
- 3708 END; .)
|
|
|
- 3709 | ( "MIN" (. isMax := FALSE; .)
|
|
|
- 3710 | "MAX" (. isMax := TRUE; .) )
|
|
|
- 3711 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3712 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3713 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3714 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
- 3715 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3716 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
- 3717 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3718 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3719 IF (dt # SymTab.InvalidType)
|
|
|
- 3720 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
- 3721 (* REAL/LONGREAL: the
|
|
|
- 3722 implementation bounds *)
|
|
|
- 3723 IF isMax THEN
|
|
|
- 3724 QbeGen.NormReal(
|
|
|
- 3725 "3.402823e38", q)
|
|
|
- 3726 ELSE QbeGen.NormReal(
|
|
|
- 3727 "-3.402823e38", q)
|
|
|
- 3728 END;
|
|
|
- 3729 t := SymTab.RealType()
|
|
|
- 3730 ELSIF (dt #
|
|
|
- 3731 SymTab.InvalidType)
|
|
|
- 3732 AND (SymTab.ClassOf(dt) =
|
|
|
- 3733 SymTab.ClLong) THEN
|
|
|
- 3734 IF isMax THEN
|
|
|
- 3735 QbeGen.CopyOp(
|
|
|
- 3736 "9223372036854775807", q)
|
|
|
- 3737 ELSE QbeGen.CopyOp(
|
|
|
- 3738 "-9223372036854775808", q)
|
|
|
- 3739 END;
|
|
|
- 3740 t := SymTab.LongType()
|
|
|
- 3741 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
- 3742 hi) THEN
|
|
|
- 3743 IF isMax THEN
|
|
|
- 3744 QbeGen.IntStr(hi, q)
|
|
|
- 3745 ELSE QbeGen.IntStr(lo, q)
|
|
|
- 3746 END;
|
|
|
- 3747 (* a set's bounds are those
|
|
|
- 3748 of its base type *)
|
|
|
- 3749 IF SymTab.ClassOf(dt) =
|
|
|
- 3750 SymTab.ClSet THEN
|
|
|
- 3751 t := SymTab.SetBase(dt)
|
|
|
- 3752 ELSE t := SymTab.IntType()
|
|
|
- 3753 END
|
|
|
- 3754 ELSE SemError(230);
|
|
|
- 3755 t := SymTab.InvalidType;
|
|
|
- 3756 QbeGen.CopyOp("0", q)
|
|
|
- 3757 END; .)
|
|
|
- 3758 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3759 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3760 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
- 3761 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3762 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3763 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3764 t := SymTab.InvalidType;
|
|
|
- 3765 QbeGen.CopyOp("0", q)
|
|
|
- 3766 ELSE
|
|
|
- 3767 IF sfx
|
|
|
- 3768 OR (dk = SymTab.KindVar)
|
|
|
- 3769 OR (dk = SymTab.KindParam) THEN
|
|
|
- 3770 QbeGen.CopyOp("@", q)
|
|
|
- 3771 ELSE SemError(230);
|
|
|
- 3772 QbeGen.CopyOp("0", q)
|
|
|
- 3773 END;
|
|
|
- 3774 t := SymTab.AddrType()
|
|
|
- 3775 END; .)
|
|
|
- 3776 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 3777 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3778 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
- 3779 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3780 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3781 (. IF (et # SymTab.InvalidType)
|
|
|
- 3782 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3783 SemError(211) END;
|
|
|
- 3784 t := SymTab.CharType(); .)
|
|
|
- 3785 | "ORD" "(" Expr<et, q> ")"
|
|
|
- 3786 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3787 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
- 3788 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3789 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3790 (. IF et # SymTab.InvalidType THEN
|
|
|
- 3791 IF (SymTab.ClassOf(et) #
|
|
|
- 3792 SymTab.ClChar)
|
|
|
- 3793 AND (SymTab.ClassOf(et) #
|
|
|
- 3794 SymTab.ClBool)
|
|
|
- 3795 AND (SymTab.ClassOf(et) #
|
|
|
- 3796 SymTab.ClEnum)
|
|
|
- 3797 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3798 SemError(211) END
|
|
|
- 3799 END;
|
|
|
- 3800 t := SymTab.IntType(); .)
|
|
|
- 3801 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 3802 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3803 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
- 3804 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3805 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3806 (. IF QbeGen.IsImm(q)
|
|
|
- 3807 AND SymTab.ConstInt(q, lo) THEN
|
|
|
- 3808 IF (lo >= VAL(INTEGER, ORD("a"))) AND (lo <= VAL(INTEGER, ORD("z"))) THEN lo := lo - 32 END;
|
|
|
- 3809 QbeGen.IntStr(lo, q)
|
|
|
- 3810 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 3811 END;
|
|
|
- 3812 t := SymTab.CharType(); .)
|
|
|
- 3813 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 3814 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3815 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
- 3816 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3817 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3818 (. (* UCHR: the UCHAR constructor.
|
|
|
- 3819 CHAR -> UCHAR (identity);
|
|
|
- 3820 INTEGER familly -> UCHAR
|
|
|
- 3821 (codepoint value). *)
|
|
|
- 3822 IF (et # SymTab.InvalidType)
|
|
|
- 3823 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 3824 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3825 SemError(211) END;
|
|
|
- 3826 t := SymTab.UCharType(); .)
|
|
|
- 3827 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 3828 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3829 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
- 3830 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3831 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3832 (. IF (et # SymTab.InvalidType)
|
|
|
- 3833 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3834 SemError(211) END;
|
|
|
- 3835 t := SymTab.CharType(); .)
|
|
|
- 3836 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 3837 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3838 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
- 3839 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3840 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3841 (. (* UORD(u): the codepoint as a
|
|
|
- 3842 32-bit ordinal (INTEGER),
|
|
|
- 3843 cf. ORD for CHAR. *)
|
|
|
- 3844 IF (et # SymTab.InvalidType)
|
|
|
- 3845 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3846 SemError(211) END;
|
|
|
- 3847 t := SymTab.IntType(); .)
|
|
|
- 3848 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 3849 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3850 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
- 3851 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3852 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3853 (. IF (et # SymTab.InvalidType)
|
|
|
- 3854 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 3855 AND (SymTab.ClassOf(et) #
|
|
|
- 3856 SymTab.ClReal) THEN
|
|
|
- 3857 SemError(211)
|
|
|
- 3858 ELSIF QbeGen.IsImm(q)
|
|
|
- 3859 AND SymTab.ConstInt(q, lo) THEN
|
|
|
- 3860 IF lo < 0 THEN lo := -lo END;
|
|
|
- 3861 QbeGen.IntStr(lo, q)
|
|
|
- 3862 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 3863 END;
|
|
|
- 3864 t := et; .)
|
|
|
- 3865 | "ODD" "(" Expr<et, q> ")"
|
|
|
- 3866 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3867 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ODD"));
|
|
|
- 3868 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3869 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3870 (. IF (et # SymTab.InvalidType)
|
|
|
- 3871 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3872 SemError(211) END;
|
|
|
- 3873 t := SymTab.BoolType();
|
|
|
- 3874 IF QbeGen.IsImm(q)
|
|
|
- 3875 AND SymTab.ConstInt(q, lo) THEN
|
|
|
- 3876 IF (lo MOD 2) # 0 THEN
|
|
|
- 3877 QbeGen.CopyOp("1", q)
|
|
|
- 3878 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3879 END
|
|
|
- 3880 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 3881 END; .)
|
|
|
- 3882 | "TRUNC" "(" Expr<et, q> ")"
|
|
|
- 3883 (. (* TRUNC(x): real -> INTEGER, as the VAL builtin *)
|
|
|
- 3884 astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3885 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3886 AST.SetChild(astNode, 1, AST.MakeLeaf(AST.NkIdent, "INTEGER"));
|
|
|
- 3887 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3285 AND (SymTab.UStrCompat(t, t2)
|
|
|
+ 3286 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 3287 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
+ 3288 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
+ 3289 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
+ 3290 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 3291 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
+ 3292 (* UString concatenation: a UCHAR operand becomes a
|
|
|
+ 3293 1-codepoint UString; the result is a descriptor in the
|
|
|
+ 3294 shim's concat buffer. Work on copies so neither
|
|
|
+ 3295 operand is clobbered. *)
|
|
|
+ 3296 t := SymTab.NewUStr();
|
|
|
+ 3297 QbeGen.CopyOp("@", q)
|
|
|
+ 3298 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 3299 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 3300 OR (SymTab.IsStrType(t)
|
|
|
+ 3301 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 3302 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 3303 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 3304 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 3305 1-character string literal. When both operands are
|
|
|
+ 3306 constants, fold to a single string literal so a
|
|
|
+ 3307 constructor element stays compile-time. *)
|
|
|
+ 3308 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
+ 3309 qt, fok);
|
|
|
+ 3310 IF fok THEN QbeGen.CopyOp(qt, q)
|
|
|
+ 3311 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 3312 END;
|
|
|
+ 3313 t := SymTab.NewStr()
|
|
|
+ 3314 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 3315 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 3316 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 3317 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 3318 mw := lw;
|
|
|
+ 3319 IF rw > mw THEN mw := rw END;
|
|
|
+ 3320 t := SymTab.NewSet(
|
|
|
+ 3321 SymTab.NewSubR(0,
|
|
|
+ 3322 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 3323 QbeGen.CopyOp("@", q)
|
|
|
+ 3324 ELSE
|
|
|
+ 3325 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 3326 lt := t; rt := t2; t := res2
|
|
|
+ 3327 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 3328 IF t # SymTab.InvalidType THEN
|
|
|
+ 3329 isL := SymTab.IsLongFamily(t);
|
|
|
+ 3330 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 3331 folded := FALSE;
|
|
|
+ 3332 IF (NOT isL) AND (NOT isR)
|
|
|
+ 3333 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 3334 IF op = SymTab.OpAdd THEN
|
|
|
+ 3335 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 3336 ELSE
|
|
|
+ 3337 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 3338 END
|
|
|
+ 3339 END;
|
|
|
+ 3340 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 3341 ELSE
|
|
|
+ 3342 QbeGen.CopyOp("@", q)
|
|
|
+ 3343 END
|
|
|
+ 3344 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3345 END
|
|
|
+ 3346 END; .) }
|
|
|
+ 3347 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 3348 AddOp<VAR op: INTEGER>
|
|
|
+ 3349 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 3350 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 3351 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 3352 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3353 (. VAR t2, res2, lt, rt:
|
|
|
+ 3354 SymTab.TypeIndex;
|
|
|
+ 3355 op: INTEGER;
|
|
|
+ 3356 q2, qt, wq, qf:
|
|
|
+ 3357 QbeGen.QVal;
|
|
|
+ 3358 isR, isL, folded: BOOLEAN;
|
|
|
+ 3359 lw, rw, mw: CARDINAL;
|
|
|
+ 3360 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 3361 astA, astB: AST.Node;
|
|
|
+ 3362 astOp: INTEGER; .)
|
|
|
+ 3363 = Fact<t, q> (. astA := astCur; .) { MulOp<op>
|
|
|
+ 3364 Fact<t2, q2> (. astB := astCur; .)
|
|
|
+ 3365 (. astOp := AST.OpMul;
|
|
|
+ 3366 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
+ 3367 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
+ 3368 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
+ 3369 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
+ 3370 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 3371 astCur := astA;
|
|
|
+ 3372 IF op = SymTab.OpAnd THEN
|
|
|
+ 3373 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 3374 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 3375 t := SymTab.BoolType()
|
|
|
+ 3376 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 3377 IF t # SymTab.InvalidType THEN QbeGen.CopyOp("@", q)
|
|
|
+ 3378 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3379 END
|
|
|
+ 3380 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 3381 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 3382 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 3383 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 3384 mw := lw;
|
|
|
+ 3385 IF rw > mw THEN mw := rw END;
|
|
|
+ 3386 t := SymTab.NewSet(
|
|
|
+ 3387 SymTab.NewSubR(0,
|
|
|
+ 3388 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 3389 QbeGen.CopyOp("@", q)
|
|
|
+ 3390 ELSE
|
|
|
+ 3391 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 3392 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 3393 res2) THEN
|
|
|
+ 3394 lt := t; rt := t2; t := res2
|
|
|
+ 3395 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 3396 IF t # SymTab.InvalidType THEN
|
|
|
+ 3397 isL := SymTab.IsLongFamily(t);
|
|
|
+ 3398 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 3399 folded := FALSE;
|
|
|
+ 3400 IF (NOT isL) AND (NOT isR)
|
|
|
+ 3401 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 3402 IF op = SymTab.OpTimes THEN
|
|
|
+ 3403 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 3404 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 3405 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 3406 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 3407 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 3408 END
|
|
|
+ 3409 END;
|
|
|
+ 3410 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 3411 ELSE
|
|
|
+ 3412 QbeGen.CopyOp("@", q)
|
|
|
+ 3413 END
|
|
|
+ 3414 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3415 END
|
|
|
+ 3416 END; .) }
|
|
|
+ 3417 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 3418 MulOp<VAR op: INTEGER>
|
|
|
+ 3419 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 3420 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 3421 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 3422 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 3423 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 3424 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3425 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 3426 et, dt, t2, st, ct2, et2:
|
|
|
+ 3427 SymTab.TypeIndex;
|
|
|
+ 3428 dk: INTEGER;
|
|
|
+ 3429 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
+ 3430 QbeGen.QVal;
|
|
|
+ 3431 qn, vn: SymTab.Name;
|
|
|
+ 3432 vt: SymTab.TypeIndex;
|
|
|
+ 3433 c1, c2: INTEGER;
|
|
|
+ 3434 lo, hi: INTEGER;
|
|
|
+ 3435 isMax: BOOLEAN;
|
|
|
+ 3436 called, isHigh, sfx, isCh,
|
|
|
+ 3437 isU, uok, isStr: BOOLEAN;
|
|
|
+ 3438 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
+ 3439 astD: AST.Node;
|
|
|
+ 3440 astCall: BOOLEAN;
|
|
|
+ 3441 astNode, astNot: AST.Node;
|
|
|
+ 3442 j: CARDINAL;
|
|
|
+ 3443 astArg2: AST.Node;
|
|
|
+ 3444 astBrace: AST.Node;
|
|
|
+ 3445 astRes: AST.Node; mname: SymTab.Name; isM: BOOLEAN;
|
|
|
+ 3446 isConvF: BOOLEAN;
|
|
|
+ 3447 fi, fj: CARDINAL; .)
|
|
|
+ 3448 = (. astIsLit := FALSE; .)
|
|
|
+ 3449 ( "__LINE__" (. QbeGen.IntStr(M2S.line, q);
|
|
|
+ 3450 astIsLit := TRUE;
|
|
|
+ 3451 astCur := AST.MakeLeaf(
|
|
|
+ 3452 AST.NkIntLit, q);
|
|
|
+ 3453 t := SymTab.IntType(); .)
|
|
|
+ 3454 | "__FILE__" (. (* fold to the quoted file name *)
|
|
|
+ 3455 s[0] := '"'; fi := 1; fj := 0;
|
|
|
+ 3456 WHILE (M2S.fileName[fj] # CHR(0))
|
|
|
+ 3457 AND (fi < HIGH(s)) DO
|
|
|
+ 3458 s[fi] := M2S.fileName[fj];
|
|
|
+ 3459 INC(fi); INC(fj)
|
|
|
+ 3460 END;
|
|
|
+ 3461 s[fi] := '"';
|
|
|
+ 3462 s[fi + 1] := CHR(0);
|
|
|
+ 3463 astIsLit := TRUE;
|
|
|
+ 3464 astCur := AST.MakeLeaf(
|
|
|
+ 3465 AST.NkStrLit, s);
|
|
|
+ 3466 t := SymTab.NewStr();
|
|
|
+ 3467 QbeGen.DeclStr(s, q); .)
|
|
|
+ 3468 | integer (. LexString(s);
|
|
|
+ 3469 QbeGen.NormInt(s, q); astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s);
|
|
|
+ 3470 t := SymTab.IntType(); .)
|
|
|
+ 3471 | charConst (. LexString(s);
|
|
|
+ 3472 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 3473 astIsLit := TRUE;
|
|
|
+ 3474 astCur := AST.MakeLeaf(
|
|
|
+ 3475 AST.NkCharLit, s);
|
|
|
+ 3476 t := SymTab.CharType(); .)
|
|
|
+ 3477 | real (. LexString(s);
|
|
|
+ 3478 QbeGen.NormReal(s, q);
|
|
|
+ 3479 astIsLit := TRUE;
|
|
|
+ 3480 astCur := AST.MakeLeaf(
|
|
|
+ 3481 AST.NkRealLit, s);
|
|
|
+ 3482 t := SymTab.RealType(); .)
|
|
|
+ 3483 | string (. LexString(s);
|
|
|
+ 3484 astIsLit := TRUE;
|
|
|
+ 3485 astCur := AST.MakeLeaf(
|
|
|
+ 3486 AST.NkStrLit, s);
|
|
|
+ 3487 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3488 t := SymTab.CharType();
|
|
|
+ 3489 QbeGen.IntStr(
|
|
|
+ 3490 QbeGen.CharVal(s), q)
|
|
|
+ 3491 ELSIF SymTab.StrLen(s) = 2 THEN
|
|
|
+ 3492 (* empty string: a string value
|
|
|
+ 3493 for arrays, 0 for CHAR *)
|
|
|
+ 3494 t := SymTab.NewEmptyStr();
|
|
|
+ 3495 QbeGen.DeclStr(s, q)
|
|
|
+ 3496 ELSE t := SymTab.NewStr();
|
|
|
+ 3497 QbeGen.DeclStr(s, q);
|
|
|
+ 3498 (* a literal's value IS its
|
|
|
+ 3499 static descriptor address *)
|
|
|
+ 3500 END; .)
|
|
|
+ 3501 | ustring (. LexString(s);
|
|
|
+ 3502 astIsLit := TRUE;
|
|
|
+ 3503 astCur := AST.MakeLeaf(
|
|
|
+ 3504 AST.NkStrLit, s);
|
|
|
+ 3505 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 3506 uok);
|
|
|
+ 3507 IF NOT uok THEN
|
|
|
+ 3508 SemError(234);
|
|
|
+ 3509 t := SymTab.InvalidType
|
|
|
+ 3510 ELSIF isU THEN
|
|
|
+ 3511 t := SymTab.UCharType();
|
|
|
+ 3512 QbeGen.IntStr(ucp, q)
|
|
|
+ 3513 ELSE
|
|
|
+ 3514 t := SymTab.NewUStr();
|
|
|
+ 3515 END; .)
|
|
|
+ 3516 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
+ 3517 astNArgs := 0; called := FALSE;
|
|
|
+ 3518 t := dt;
|
|
|
+ 3519 IF dk = SymTab.KindConst THEN
|
|
|
+ 3520 QbeGen.CopyOp(qd, q)
|
|
|
+ 3521 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 3522 END; .)
|
|
|
+ 3523 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
+ 3524 astBrace := astCur; .) ]
|
|
|
+ 3525 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 3526 (. astCall := TRUE;
|
|
|
+ 3527 IF (SymTab.SymKind(qn) = SymTab.KindType)
|
|
|
+ 3528 OR (SymTab.SymKind(qn) = SymTab.KindPredef) THEN
|
|
|
+ 3529 (* T(x): emit as the VAL builtin so Lower's
|
|
|
+ 3530 conversion rules apply unchanged *)
|
|
|
+ 3531 astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3532 AST.SetChild(astNode, 0,
|
|
|
+ 3533 AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3534 AST.SetChild(astNode, 1,
|
|
|
+ 3535 AST.MakeLeaf(AST.NkIdent, qn));
|
|
|
+ 3536 IF astNArgs = 1 THEN
|
|
|
+ 3537 AST.SetChild(astNode, 2, astArgs[0])
|
|
|
+ 3538 END;
|
|
|
+ 3539 isConvF := TRUE
|
|
|
+ 3540 ELSE astNode := AstCallNode(astD)
|
|
|
+ 3541 END;
|
|
|
+ 3542 astRes := astNode;
|
|
|
+ 3543 t := ct2;
|
|
|
+ 3544 QbeGen.CopyOp(q2, q);
|
|
|
+ 3545 IF isConvF AND QbeGen.IsImm(convQ)
|
|
|
+ 3546 AND OrdClass(convT) AND OrdClass(ct2) THEN
|
|
|
+ 3547 QbeGen.CopyOp(convQ, q)
|
|
|
+ 3548 END;
|
|
|
+ 3549 sfx := FALSE; .)
|
|
|
+ 3550 { ResultComp<t, q, sfx, astRes, mname, methCls, isM>
|
|
|
+ 3551 [ (. astNArgs := 0; .)
|
|
|
+ 3552 ArgList<mname, t, q, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 3553 (. astNode := AstCallNode(astRes);
|
|
|
+ 3554 astRes := astNode;
|
|
|
+ 3555 t := ct2;
|
|
|
+ 3556 QbeGen.CopyOp(q2, q);
|
|
|
+ 3557 sfx := FALSE; .) ] }
|
|
|
+ 3558 (. IF sfx THEN
|
|
|
+ 3559 IF t = SymTab.InvalidType THEN
|
|
|
+ 3560 QbeGen.CopyOp("0", q)
|
|
|
+ 3561 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 3562 SymTab.ClRecord)
|
|
|
+ 3563 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
+ 3564 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
+ 3565 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 3566 QbeGen.CopyOp("@", q)
|
|
|
+ 3567 END
|
|
|
+ 3568 END; .) ]
|
|
|
+ 3569 (. IF called THEN
|
|
|
+ 3570 astCur := astRes
|
|
|
+ 3571 ELSIF astCall THEN
|
|
|
+ 3572 astCur := astBrace
|
|
|
+ 3573 ELSE astCur := astD
|
|
|
+ 3574 END;
|
|
|
+ 3575 astIsLit := TRUE;
|
|
|
+ 3576 IF NOT called
|
|
|
+ 3577 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 3578 (* bare zero-arg function
|
|
|
+ 3579 call (parentheses may be
|
|
|
+ 3580 omitted); a proper or
|
|
|
+ 3581 parameterised proc here
|
|
|
+ 3582 is 230 *)
|
|
|
+ 3583 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 3584 AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
|
|
|
+ 3585 t := SymTab.ProcRes(qn);
|
|
|
+ 3586 QbeGen.CopyOp("@", q);
|
|
|
+ 3587 astCur := AST.MakeNode(AST.NkCall);
|
|
|
+ 3588 AST.SetChild(astCur, 0, astD)
|
|
|
+ 3589 ELSE
|
|
|
+ 3590 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 3591 QbeGen.CopyOp("@", q)
|
|
|
+ 3592 END
|
|
|
+ 3593 END; .)
|
|
|
+ 3594 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 3595 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 3596 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
+ 3597 isU := FALSE; .)
|
|
|
+ 3598 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3599 isStr := TRUE;
|
|
|
+ 3600 isU := FALSE;
|
|
|
+ 3601 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3602 dt := SymTab.CharType();
|
|
|
+ 3603 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 3604 qd)
|
|
|
+ 3605 ELSE
|
|
|
+ 3606 dt := SymTab.NewStr();
|
|
|
+ 3607 QbeGen.DeclStr(s, qd);
|
|
|
+ 3608 END;
|
|
|
+ 3609 dk := -1;
|
|
|
+ 3610 qn[0] := CHR(0); .)
|
|
|
+ 3611 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3612 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
+ 3613 uok);
|
|
|
+ 3614 isStr := FALSE;
|
|
|
+ 3615 IF NOT uok THEN
|
|
|
+ 3616 SemError(234);
|
|
|
+ 3617 dt := SymTab.InvalidType
|
|
|
+ 3618 ELSIF isU THEN
|
|
|
+ 3619 (* one codepoint: a UCHAR;
|
|
|
+ 3620 LEN is 1, HIGH is 0 *)
|
|
|
+ 3621 dt := SymTab.UCharType();
|
|
|
+ 3622 QbeGen.IntStr(ucp, qd)
|
|
|
+ 3623 ELSE
|
|
|
+ 3624 dt := SymTab.NewUStr();
|
|
|
+ 3625 END;
|
|
|
+ 3626 dk := -1;
|
|
|
+ 3627 qn[0] := CHR(0); .) )
|
|
|
+ 3628 ")"
|
|
|
+ 3629 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3630 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
+ 3631 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
+ 3632 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3633 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
+ 3634 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3635 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3636 IF (dt # SymTab.InvalidType)
|
|
|
+ 3637 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
+ 3638 (* UString: the count is
|
|
|
+ 3639 the descriptor header *)
|
|
|
+ 3640 t := SymTab.IntType();
|
|
|
+ 3641 QbeGen.CopyOp("@", q)
|
|
|
+ 3642 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 3643 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
+ 3644 (* single UCHAR codepoint *)
|
|
|
+ 3645 IF isHigh THEN
|
|
|
+ 3646 QbeGen.CopyOp("0", qr)
|
|
|
+ 3647 ELSE
|
|
|
+ 3648 QbeGen.CopyOp("1", qr)
|
|
|
+ 3649 END;
|
|
|
+ 3650 t := SymTab.IntType();
|
|
|
+ 3651 QbeGen.CopyOp(qr, q)
|
|
|
+ 3652 ELSIF isStr THEN
|
|
|
+ 3653 (* fold: content length at
|
|
|
+ 3654 compile time *)
|
|
|
+ 3655 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3656 c1 := 1
|
|
|
+ 3657 ELSE
|
|
|
+ 3658 c1 :=
|
|
|
+ 3659 SymTab.StrLen(s) - 2
|
|
|
+ 3660 END;
|
|
|
+ 3661 IF isHigh THEN
|
|
|
+ 3662 DEC(c1)
|
|
|
+ 3663 END;
|
|
|
+ 3664 QbeGen.IntStr(c1, qr);
|
|
|
+ 3665 t := SymTab.IntType();
|
|
|
+ 3666 QbeGen.CopyOp(qr, q)
|
|
|
+ 3667 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 3668 t := SymTab.InvalidType;
|
|
|
+ 3669 QbeGen.CopyOp("0", q)
|
|
|
+ 3670 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 3671 SymTab.ClArray THEN
|
|
|
+ 3672 SemError(217);
|
|
|
+ 3673 t := SymTab.InvalidType;
|
|
|
+ 3674 QbeGen.CopyOp("0", q)
|
|
|
+ 3675 ELSE
|
|
|
+ 3676 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3677 t := SymTab.IntType();
|
|
|
+ 3678 QbeGen.CopyOp("@", q)
|
|
|
+ 3679 ELSE
|
|
|
+ 3680 IF isHigh THEN
|
|
|
+ 3681 QbeGen.IntStr(
|
|
|
+ 3682 SymTab.ArrayHi(dt), qr)
|
|
|
+ 3683 ELSE
|
|
|
+ 3684 QbeGen.IntStr(VAL(
|
|
|
+ 3685 INTEGER,
|
|
|
+ 3686 SymTab.ArrayLen(dt)),
|
|
|
+ 3687 qr)
|
|
|
+ 3688 END;
|
|
|
+ 3689 t := SymTab.IntType();
|
|
|
+ 3690 QbeGen.CopyOp(qr, q)
|
|
|
+ 3691 END
|
|
|
+ 3692 END; .)
|
|
|
+ 3693 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3694 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3695 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
+ 3696 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3697 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3698 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3699 t := SymTab.InvalidType;
|
|
|
+ 3700 QbeGen.CopyOp("0", q)
|
|
|
+ 3701 ELSE
|
|
|
+ 3702 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 3703 SymTab.ObjectSize(dt)), q);
|
|
|
+ 3704 t := SymTab.IntType()
|
|
|
+ 3705 END; .)
|
|
|
+ 3706 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
+ 3707 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
+ 3708 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
+ 3709 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3710 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3711 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
+ 3712 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3713 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
+ 3714 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3715 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3716 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3717 (* set shift/rotate: isMax
|
|
|
+ 3718 doubles as "rotate" *)
|
|
|
+ 3719 IF (et # SymTab.InvalidType)
|
|
|
+ 3720 AND (SymTab.ClassOf(et) =
|
|
|
+ 3721 SymTab.ClSet) THEN
|
|
|
+ 3722 t := et;
|
|
|
+ 3723 QbeGen.CopyOp("@", q)
|
|
|
+ 3724 ELSE SemError(230);
|
|
|
+ 3725 t := SymTab.InvalidType;
|
|
|
+ 3726 QbeGen.CopyOp("0", q)
|
|
|
+ 3727 END; .)
|
|
|
+ 3728 | ( "MIN" (. isMax := FALSE; .)
|
|
|
+ 3729 | "MAX" (. isMax := TRUE; .) )
|
|
|
+ 3730 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3731 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3732 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3733 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
+ 3734 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3735 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
+ 3736 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3737 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3738 IF (dt # SymTab.InvalidType)
|
|
|
+ 3739 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
+ 3740 (* REAL/LONGREAL: the
|
|
|
+ 3741 implementation bounds *)
|
|
|
+ 3742 IF isMax THEN
|
|
|
+ 3743 QbeGen.NormReal(
|
|
|
+ 3744 "3.402823e38", q)
|
|
|
+ 3745 ELSE QbeGen.NormReal(
|
|
|
+ 3746 "-3.402823e38", q)
|
|
|
+ 3747 END;
|
|
|
+ 3748 t := SymTab.RealType()
|
|
|
+ 3749 ELSIF (dt #
|
|
|
+ 3750 SymTab.InvalidType)
|
|
|
+ 3751 AND (SymTab.ClassOf(dt) =
|
|
|
+ 3752 SymTab.ClLong) THEN
|
|
|
+ 3753 IF isMax THEN
|
|
|
+ 3754 QbeGen.CopyOp(
|
|
|
+ 3755 "9223372036854775807", q)
|
|
|
+ 3756 ELSE QbeGen.CopyOp(
|
|
|
+ 3757 "-9223372036854775808", q)
|
|
|
+ 3758 END;
|
|
|
+ 3759 t := SymTab.LongType()
|
|
|
+ 3760 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
+ 3761 hi) THEN
|
|
|
+ 3762 IF isMax THEN
|
|
|
+ 3763 QbeGen.IntStr(hi, q)
|
|
|
+ 3764 ELSE QbeGen.IntStr(lo, q)
|
|
|
+ 3765 END;
|
|
|
+ 3766 (* a set's bounds are those
|
|
|
+ 3767 of its base type *)
|
|
|
+ 3768 IF SymTab.ClassOf(dt) =
|
|
|
+ 3769 SymTab.ClSet THEN
|
|
|
+ 3770 t := SymTab.SetBase(dt)
|
|
|
+ 3771 ELSE t := SymTab.IntType()
|
|
|
+ 3772 END
|
|
|
+ 3773 ELSE SemError(230);
|
|
|
+ 3774 t := SymTab.InvalidType;
|
|
|
+ 3775 QbeGen.CopyOp("0", q)
|
|
|
+ 3776 END; .)
|
|
|
+ 3777 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3778 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3779 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
+ 3780 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3781 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3782 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3783 t := SymTab.InvalidType;
|
|
|
+ 3784 QbeGen.CopyOp("0", q)
|
|
|
+ 3785 ELSE
|
|
|
+ 3786 IF sfx
|
|
|
+ 3787 OR (dk = SymTab.KindVar)
|
|
|
+ 3788 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 3789 QbeGen.CopyOp("@", q)
|
|
|
+ 3790 ELSE SemError(230);
|
|
|
+ 3791 QbeGen.CopyOp("0", q)
|
|
|
+ 3792 END;
|
|
|
+ 3793 t := SymTab.AddrType()
|
|
|
+ 3794 END; .)
|
|
|
+ 3795 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 3796 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3797 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
+ 3798 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3799 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3800 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3801 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3802 SemError(211) END;
|
|
|
+ 3803 t := SymTab.CharType(); .)
|
|
|
+ 3804 | "ORD" "(" Expr<et, q> ")"
|
|
|
+ 3805 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3806 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
+ 3807 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3808 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3809 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 3810 IF (SymTab.ClassOf(et) #
|
|
|
+ 3811 SymTab.ClChar)
|
|
|
+ 3812 AND (SymTab.ClassOf(et) #
|
|
|
+ 3813 SymTab.ClBool)
|
|
|
+ 3814 AND (SymTab.ClassOf(et) #
|
|
|
+ 3815 SymTab.ClEnum)
|
|
|
+ 3816 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3817 SemError(211) END
|
|
|
+ 3818 END;
|
|
|
+ 3819 t := SymTab.IntType(); .)
|
|
|
+ 3820 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 3821 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3822 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
+ 3823 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3824 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3825 (. IF QbeGen.IsImm(q)
|
|
|
+ 3826 AND SymTab.ConstInt(q, lo) THEN
|
|
|
+ 3827 IF (lo >= VAL(INTEGER, ORD("a"))) AND (lo <= VAL(INTEGER, ORD("z"))) THEN lo := lo - 32 END;
|
|
|
+ 3828 QbeGen.IntStr(lo, q)
|
|
|
+ 3829 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 3830 END;
|
|
|
+ 3831 t := SymTab.CharType(); .)
|
|
|
+ 3832 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 3833 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3834 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
+ 3835 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3836 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3837 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 3838 CHAR -> UCHAR (identity);
|
|
|
+ 3839 INTEGER familly -> UCHAR
|
|
|
+ 3840 (codepoint value). *)
|
|
|
+ 3841 IF (et # SymTab.InvalidType)
|
|
|
+ 3842 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 3843 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3844 SemError(211) END;
|
|
|
+ 3845 t := SymTab.UCharType(); .)
|
|
|
+ 3846 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 3847 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3848 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
+ 3849 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3850 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3851 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3852 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3853 SemError(211) END;
|
|
|
+ 3854 t := SymTab.CharType(); .)
|
|
|
+ 3855 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 3856 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3857 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
+ 3858 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3859 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3860 (. (* UORD(u): the codepoint as a
|
|
|
+ 3861 32-bit ordinal (INTEGER),
|
|
|
+ 3862 cf. ORD for CHAR. *)
|
|
|
+ 3863 IF (et # SymTab.InvalidType)
|
|
|
+ 3864 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3865 SemError(211) END;
|
|
|
+ 3866 t := SymTab.IntType(); .)
|
|
|
+ 3867 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 3868 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3869 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
+ 3870 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3871 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3872 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3873 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 3874 AND (SymTab.ClassOf(et) #
|
|
|
+ 3875 SymTab.ClReal) THEN
|
|
|
+ 3876 SemError(211)
|
|
|
+ 3877 ELSIF QbeGen.IsImm(q)
|
|
|
+ 3878 AND SymTab.ConstInt(q, lo) THEN
|
|
|
+ 3879 IF lo < 0 THEN lo := -lo END;
|
|
|
+ 3880 QbeGen.IntStr(lo, q)
|
|
|
+ 3881 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 3882 END;
|
|
|
+ 3883 t := et; .)
|
|
|
+ 3884 | "ODD" "(" Expr<et, q> ")"
|
|
|
+ 3885 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3886 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ODD"));
|
|
|
+ 3887 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
3888 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3889 (. t := SymTab.IntType();
|
|
|
- 3890 QbeGen.CopyOp("@", q); .)
|
|
|
- 3891 | "FLOAT" "(" Expr<et, q> ")"
|
|
|
- 3892 (. (* FLOAT(i): integer -> REAL, as the VAL builtin *)
|
|
|
- 3893 astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3894 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3895 AST.SetChild(astNode, 1, AST.MakeLeaf(AST.NkIdent, "REAL"));
|
|
|
- 3896 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3897 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3898 (. t := SymTab.RealType();
|
|
|
- 3899 IF QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo) THEN QbeGen.NormReal(q, qa); QbeGen.CopyOp(qa, q)
|
|
|
- 3900 ELSE QbeGen.CopyOp("@", q) END; .)
|
|
|
- 3901 | ( "VAL" | "CONVERT" | "CAST" ) "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
- 3902 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3903 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3904 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3905 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3906 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3907 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 3908 SemError(201);
|
|
|
- 3909 t := SymTab.InvalidType
|
|
|
- 3910 ELSE vt := SymTab.SymType(vn);
|
|
|
- 3911 IF vt = SymTab.InvalidType THEN
|
|
|
- 3912 t := SymTab.InvalidType
|
|
|
- 3913 ELSIF et =
|
|
|
- 3914 SymTab.InvalidType THEN
|
|
|
- 3915 t := vt
|
|
|
- 3916 ELSE
|
|
|
- 3917 c1 := SymTab.ClassOf(et);
|
|
|
- 3918 c2 := SymTab.ClassOf(vt);
|
|
|
- 3919 IF (c1 = SymTab.ClInt)
|
|
|
- 3920 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3921 IF NOT QbeGen.IsImm(q) THEN QbeGen.WidenLong(q, qa); QbeGen.CopyOp(qa, q) END;
|
|
|
- 3922 t := vt
|
|
|
- 3923 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3924 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3925 IF NOT (QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo)) THEN QbeGen.NarrowLong(q, qa); QbeGen.CopyOp(qa, q) END;
|
|
|
- 3926 t := vt
|
|
|
- 3927 ELSIF (c1 = SymTab.ClInt)
|
|
|
- 3928 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3929 IF QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo) THEN QbeGen.NormReal(q, qa) ELSE QbeGen.ConvIR(q, qa) END;
|
|
|
- 3930 QbeGen.CopyOp(qa, q);
|
|
|
- 3931 t := vt
|
|
|
- 3932 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3933 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3934 IF QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo) THEN QbeGen.NormReal(q, qa) ELSE QbeGen.ConvLR(q, qa) END;
|
|
|
- 3935 QbeGen.CopyOp(qa, q);
|
|
|
- 3936 t := vt
|
|
|
- 3937 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3938 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3939 QbeGen.ConvRI(q, qa);
|
|
|
- 3940 QbeGen.CopyOp(qa, q);
|
|
|
+ 3889 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3890 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3891 SemError(211) END;
|
|
|
+ 3892 t := SymTab.BoolType();
|
|
|
+ 3893 IF QbeGen.IsImm(q)
|
|
|
+ 3894 AND SymTab.ConstInt(q, lo) THEN
|
|
|
+ 3895 IF (lo MOD 2) # 0 THEN
|
|
|
+ 3896 QbeGen.CopyOp("1", q)
|
|
|
+ 3897 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3898 END
|
|
|
+ 3899 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 3900 END; .)
|
|
|
+ 3901 | "TRUNC" "(" Expr<et, q> ")"
|
|
|
+ 3902 (. (* TRUNC(x): real -> INTEGER, as the VAL builtin *)
|
|
|
+ 3903 astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3904 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3905 AST.SetChild(astNode, 1, AST.MakeLeaf(AST.NkIdent, "INTEGER"));
|
|
|
+ 3906 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3907 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3908 (. t := SymTab.IntType();
|
|
|
+ 3909 QbeGen.CopyOp("@", q); .)
|
|
|
+ 3910 | "FLOAT" "(" Expr<et, q> ")"
|
|
|
+ 3911 (. (* FLOAT(i): integer -> REAL, as the VAL builtin *)
|
|
|
+ 3912 astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3913 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3914 AST.SetChild(astNode, 1, AST.MakeLeaf(AST.NkIdent, "REAL"));
|
|
|
+ 3915 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3916 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3917 (. t := SymTab.RealType();
|
|
|
+ 3918 IF QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo) THEN QbeGen.NormReal(q, qa); QbeGen.CopyOp(qa, q)
|
|
|
+ 3919 ELSE QbeGen.CopyOp("@", q) END; .)
|
|
|
+ 3920 | ( "VAL" | "CONVERT" | "CAST" ) "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
+ 3921 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3922 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3923 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3924 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3925 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3926 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 3927 SemError(201);
|
|
|
+ 3928 t := SymTab.InvalidType
|
|
|
+ 3929 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 3930 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3931 t := SymTab.InvalidType
|
|
|
+ 3932 ELSIF et =
|
|
|
+ 3933 SymTab.InvalidType THEN
|
|
|
+ 3934 t := vt
|
|
|
+ 3935 ELSE
|
|
|
+ 3936 c1 := SymTab.ClassOf(et);
|
|
|
+ 3937 c2 := SymTab.ClassOf(vt);
|
|
|
+ 3938 IF (c1 = SymTab.ClInt)
|
|
|
+ 3939 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3940 IF NOT QbeGen.IsImm(q) THEN QbeGen.WidenLong(q, qa); QbeGen.CopyOp(qa, q) END;
|
|
|
3941 t := vt
|
|
|
- 3942 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3943 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3944 QbeGen.ConvRL(q, qa);
|
|
|
- 3945 QbeGen.CopyOp(qa, q);
|
|
|
- 3946 t := vt
|
|
|
- 3947 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3948 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3949 t := vt
|
|
|
- 3950 ELSIF ((c1 = SymTab.ClInt)
|
|
|
- 3951 OR (c1 =
|
|
|
- 3952 SymTab.ClChar)
|
|
|
- 3953 OR (c1 =
|
|
|
- 3954 SymTab.ClBool)
|
|
|
- 3955 OR (c1 =
|
|
|
- 3956 SymTab.ClEnum))
|
|
|
- 3957 AND ((c2 = SymTab.ClInt)
|
|
|
- 3958 OR (c2 =
|
|
|
- 3959 SymTab.ClChar)
|
|
|
- 3960 OR (c2 =
|
|
|
- 3961 SymTab.ClBool)
|
|
|
- 3962 OR (c2 =
|
|
|
- 3963 SymTab.ClEnum)) THEN
|
|
|
- 3964 t := vt
|
|
|
- 3965 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 3966 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 3967 t := vt
|
|
|
- 3968 ELSIF ((c1 = SymTab.ClProc)
|
|
|
- 3969 AND (c2 = SymTab.ClProc))
|
|
|
- 3970 OR ((c1 = SymTab.ClProc) AND (c2 = SymTab.ClPtr))
|
|
|
- 3971 OR ((c1 = SymTab.ClPtr) AND (c2 = SymTab.ClProc)) THEN
|
|
|
- 3972 t := vt
|
|
|
- 3973 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3974 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3975 t := vt
|
|
|
- 3976 ELSIF ((c1 = SymTab.ClSet) AND (c2 = SymTab.ClInt))
|
|
|
- 3977 OR ((c1 = SymTab.ClInt) AND (c2 = SymTab.ClSet)) THEN
|
|
|
- 3978 (* a set <-> its machine word (BITSET) *)
|
|
|
- 3979 t := vt
|
|
|
- 3980 ELSE SemError(230);
|
|
|
- 3981 t := SymTab.InvalidType
|
|
|
- 3982 END
|
|
|
- 3983 END
|
|
|
- 3984 END; .)
|
|
|
- 3985 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
- 3986 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
- 3987 QbeGen.CopyOp(sq, q); .)
|
|
|
- 3988 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
- 3989 IF SymTab.BoolCheck(t2) THEN
|
|
|
- 3990 t := SymTab.BoolType()
|
|
|
- 3991 ELSE SemError(212);
|
|
|
- 3992 t := SymTab.InvalidType END;
|
|
|
- 3993 IF t # SymTab.InvalidType THEN
|
|
|
- 3994 QbeGen.CopyOp("@", q)
|
|
|
- 3995 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3996 END;
|
|
|
- 3997 astIsLit := TRUE;
|
|
|
- 3998 astCur := AST.MakeUn(
|
|
|
- 3999 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
- 4000 )
|
|
|
- 4001 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .)
|
|
|
- 4002 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 4003 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 4004 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 4005 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 4006 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 4007 (. VAR astNode: AST.Node; .)
|
|
|
- 4008 = "{" (. t := SymTab.NewSet(
|
|
|
- 4009 SymTab.NewSubR(0, 255));
|
|
|
- 4010 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
- 4011 QbeGen.NewSetTemp(8, q);
|
|
|
- 4012 QbeGen.SetZero(q, 8); .)
|
|
|
- 4013 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
- 4014 "}" (. astCur := astNode; .) .
|
|
|
- 4015 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
- 4016 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
- 4017 declared type sets the width (set) or element type (array). *)
|
|
|
- 4018 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 4019 (. VAR nw: CARDINAL;
|
|
|
- 4020 astNode, astTail: AST.Node;
|
|
|
- 4021 savedCls: INTEGER; .)
|
|
|
- 4022 = "{" (. savedCls := braceCls;
|
|
|
- 4023 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
- 4024 AST.SetTy(astNode, vt);
|
|
|
- 4025 astTail := astNode;
|
|
|
- 4026 IF vt = SymTab.InvalidType THEN
|
|
|
- 4027 braceCls := -1
|
|
|
- 4028 ELSE braceCls :=
|
|
|
- 4029 SymTab.ClassOf(vt)
|
|
|
- 4030 END;
|
|
|
- 4031 IF braceCls = SymTab.ClSet THEN
|
|
|
- 4032 IF vt = SymTab.InvalidType THEN
|
|
|
- 4033 nw := 8
|
|
|
- 4034 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 4035 IF nw = 0 THEN nw := 8 END
|
|
|
- 4036 END;
|
|
|
- 4037 QbeGen.NewSetTemp(nw, q);
|
|
|
- 4038 QbeGen.SetZero(q, nw)
|
|
|
- 4039 ELSIF (braceCls =
|
|
|
- 4040 SymTab.ClArray)
|
|
|
- 4041 OR (braceCls =
|
|
|
- 4042 SymTab.ClRecord)
|
|
|
- 4043 OR (braceCls =
|
|
|
- 4044 SymTab.ClClass) THEN
|
|
|
- 4045 QbeGen.CtorBegin(vt)
|
|
|
- 4046 ELSE
|
|
|
- 4047 IF vt # SymTab.InvalidType THEN
|
|
|
- 4048 SemError(230) END;
|
|
|
- 4049 braceCls := -1
|
|
|
- 4050 END; .)
|
|
|
- 4051 [ BraceElem<vt, q, astNode, astTail>
|
|
|
- 4052 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
- 4053 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
- 4054 OR (braceCls =
|
|
|
- 4055 SymTab.ClRecord)
|
|
|
- 4056 OR (braceCls =
|
|
|
- 4057 SymTab.ClClass) THEN
|
|
|
- 4058 QbeGen.CtorEnd(q)
|
|
|
- 4059 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
- 4060 QbeGen.CopyOp("0", q)
|
|
|
- 4061 END;
|
|
|
- 4062 braceCls := savedCls; .)
|
|
|
- 4063 (. astCur := astNode; .) .
|
|
|
- 4064 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
- 4065 VAR node, tail: AST.Node>
|
|
|
- 4066 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 4067 qe, q2: QbeGen.QVal;
|
|
|
- 4068 v, v2, reps, k: INTEGER;
|
|
|
- 4069 elem: SymTab.TypeIndex;
|
|
|
- 4070 lo: INTEGER;
|
|
|
- 4071 span: CARDINAL;
|
|
|
- 4072 cl, cl2: INTEGER;
|
|
|
- 4073 hasR, hasB: BOOLEAN;
|
|
|
- 4074 astEl: AST.Node; .)
|
|
|
- 4075 = (. hasR := FALSE; hasB := FALSE;
|
|
|
- 4076 reps := 1; .)
|
|
|
- 4077 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 4078 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 4079 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 4080 hasR := TRUE; .) ]
|
|
|
- 4081 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
- 4082 (. IF braceCls = SymTab.ClSet THEN
|
|
|
- 4083 IF hasB THEN SemError(230) END;
|
|
|
- 4084 lo := SymTab.SetBaseLo(vt);
|
|
|
- 4085 span := SymTab.SetCount(vt);
|
|
|
- 4086 IF (et = SymTab.InvalidType)
|
|
|
- 4087 OR (hasR AND (et2 =
|
|
|
- 4088 SymTab.InvalidType)) THEN
|
|
|
- 4089 ELSE cl :=
|
|
|
- 4090 SymTab.ClassOf(et);
|
|
|
- 4091 IF hasR THEN
|
|
|
- 4092 cl2 :=
|
|
|
- 4093 SymTab.ClassOf(et2)
|
|
|
- 4094 ELSE cl2 := SymTab.ClInt
|
|
|
- 4095 END;
|
|
|
- 4096 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 4097 OR (hasR AND NOT
|
|
|
- 4098 SymTab.SetElemClassOk(cl2))
|
|
|
- 4099 THEN
|
|
|
- 4100 SemError(222)
|
|
|
- 4101 ELSIF hasR
|
|
|
- 4102 AND SymTab.ConstInt(qe, v)
|
|
|
- 4103 AND SymTab.ConstInt(q2,
|
|
|
- 4104 v2)
|
|
|
- 4105 AND ((v < lo)
|
|
|
- 4106 OR (v2 < lo)
|
|
|
- 4107 OR (v >= lo +
|
|
|
- 4108 VAL(INTEGER, span))
|
|
|
- 4109 OR (v2 >= lo +
|
|
|
- 4110 VAL(INTEGER, span))
|
|
|
- 4111 OR (v > v2)) THEN
|
|
|
- 4112 SemError(222)
|
|
|
- 4113 ELSIF hasR THEN
|
|
|
- 4114 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 4115 lo, span)
|
|
|
- 4116 ELSIF SymTab.ConstInt(qe,
|
|
|
- 4117 v)
|
|
|
- 4118 AND ((v < lo)
|
|
|
- 4119 OR (v >= lo +
|
|
|
- 4120 VAL(INTEGER,
|
|
|
- 4121 span))) THEN
|
|
|
- 4122 SemError(222)
|
|
|
- 4123 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 4124 lo, span)
|
|
|
- 4125 END
|
|
|
- 4126 END
|
|
|
- 4127 ELSIF (braceCls = SymTab.ClArray)
|
|
|
- 4128 OR (braceCls =
|
|
|
- 4129 SymTab.ClRecord)
|
|
|
- 4130 OR (braceCls =
|
|
|
- 4131 SymTab.ClClass) THEN
|
|
|
- 4132 IF hasR THEN SemError(230) END;
|
|
|
- 4133 reps := 1;
|
|
|
- 4134 IF hasB THEN
|
|
|
- 4135 IF SymTab.ConstInt(q2, v2)
|
|
|
- 4136 AND (v2 >= 1) THEN
|
|
|
- 4137 reps := v2
|
|
|
- 4138 ELSE SemError(230)
|
|
|
- 4139 END
|
|
|
- 4140 END;
|
|
|
- 4141 k := 0;
|
|
|
- 4142 WHILE k < reps DO
|
|
|
- 4143 QbeGen.CtorElem(qe);
|
|
|
- 4144 INC(k)
|
|
|
+ 3942 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3943 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3944 IF NOT (QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo)) THEN QbeGen.NarrowLong(q, qa); QbeGen.CopyOp(qa, q) END;
|
|
|
+ 3945 t := vt
|
|
|
+ 3946 ELSIF (c1 = SymTab.ClInt)
|
|
|
+ 3947 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3948 IF QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo) THEN QbeGen.NormReal(q, qa) ELSE QbeGen.ConvIR(q, qa) END;
|
|
|
+ 3949 QbeGen.CopyOp(qa, q);
|
|
|
+ 3950 t := vt
|
|
|
+ 3951 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3952 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3953 IF QbeGen.IsImm(q) AND SymTab.ConstInt(q, lo) THEN QbeGen.NormReal(q, qa) ELSE QbeGen.ConvLR(q, qa) END;
|
|
|
+ 3954 QbeGen.CopyOp(qa, q);
|
|
|
+ 3955 t := vt
|
|
|
+ 3956 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3957 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3958 QbeGen.ConvRI(q, qa);
|
|
|
+ 3959 QbeGen.CopyOp(qa, q);
|
|
|
+ 3960 t := vt
|
|
|
+ 3961 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3962 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3963 QbeGen.ConvRL(q, qa);
|
|
|
+ 3964 QbeGen.CopyOp(qa, q);
|
|
|
+ 3965 t := vt
|
|
|
+ 3966 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3967 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3968 t := vt
|
|
|
+ 3969 ELSIF ((c1 = SymTab.ClInt)
|
|
|
+ 3970 OR (c1 =
|
|
|
+ 3971 SymTab.ClChar)
|
|
|
+ 3972 OR (c1 =
|
|
|
+ 3973 SymTab.ClBool)
|
|
|
+ 3974 OR (c1 =
|
|
|
+ 3975 SymTab.ClEnum))
|
|
|
+ 3976 AND ((c2 = SymTab.ClInt)
|
|
|
+ 3977 OR (c2 =
|
|
|
+ 3978 SymTab.ClChar)
|
|
|
+ 3979 OR (c2 =
|
|
|
+ 3980 SymTab.ClBool)
|
|
|
+ 3981 OR (c2 =
|
|
|
+ 3982 SymTab.ClEnum)) THEN
|
|
|
+ 3983 t := vt
|
|
|
+ 3984 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 3985 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 3986 t := vt
|
|
|
+ 3987 ELSIF ((c1 = SymTab.ClProc)
|
|
|
+ 3988 AND (c2 = SymTab.ClProc))
|
|
|
+ 3989 OR ((c1 = SymTab.ClProc) AND (c2 = SymTab.ClPtr))
|
|
|
+ 3990 OR ((c1 = SymTab.ClPtr) AND (c2 = SymTab.ClProc)) THEN
|
|
|
+ 3991 t := vt
|
|
|
+ 3992 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3993 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3994 t := vt
|
|
|
+ 3995 ELSIF ((c1 = SymTab.ClSet) AND (c2 = SymTab.ClInt))
|
|
|
+ 3996 OR ((c1 = SymTab.ClInt) AND (c2 = SymTab.ClSet)) THEN
|
|
|
+ 3997 (* a set <-> its machine word (BITSET) *)
|
|
|
+ 3998 t := vt
|
|
|
+ 3999 ELSE SemError(230);
|
|
|
+ 4000 t := SymTab.InvalidType
|
|
|
+ 4001 END
|
|
|
+ 4002 END
|
|
|
+ 4003 END; .)
|
|
|
+ 4004 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
+ 4005 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
+ 4006 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 4007 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
+ 4008 IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 4009 t := SymTab.BoolType()
|
|
|
+ 4010 ELSE SemError(212);
|
|
|
+ 4011 t := SymTab.InvalidType END;
|
|
|
+ 4012 IF t # SymTab.InvalidType THEN
|
|
|
+ 4013 QbeGen.CopyOp("@", q)
|
|
|
+ 4014 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 4015 END;
|
|
|
+ 4016 astIsLit := TRUE;
|
|
|
+ 4017 astCur := AST.MakeUn(
|
|
|
+ 4018 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
+ 4019 )
|
|
|
+ 4020 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .)
|
|
|
+ 4021 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 4022 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 4023 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 4024 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 4025 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 4026 (. VAR astNode: AST.Node; .)
|
|
|
+ 4027 = "{" (. t := SymTab.NewSet(
|
|
|
+ 4028 SymTab.NewSubR(0, 255));
|
|
|
+ 4029 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
+ 4030 QbeGen.NewSetTemp(8, q);
|
|
|
+ 4031 QbeGen.SetZero(q, 8); .)
|
|
|
+ 4032 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
+ 4033 "}" (. astCur := astNode; .) .
|
|
|
+ 4034 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
+ 4035 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
+ 4036 declared type sets the width (set) or element type (array). *)
|
|
|
+ 4037 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 4038 (. VAR nw: CARDINAL;
|
|
|
+ 4039 astNode, astTail: AST.Node;
|
|
|
+ 4040 savedCls: INTEGER; .)
|
|
|
+ 4041 = "{" (. savedCls := braceCls;
|
|
|
+ 4042 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
+ 4043 AST.SetTy(astNode, vt);
|
|
|
+ 4044 astTail := astNode;
|
|
|
+ 4045 IF vt = SymTab.InvalidType THEN
|
|
|
+ 4046 braceCls := -1
|
|
|
+ 4047 ELSE braceCls :=
|
|
|
+ 4048 SymTab.ClassOf(vt)
|
|
|
+ 4049 END;
|
|
|
+ 4050 IF braceCls = SymTab.ClSet THEN
|
|
|
+ 4051 IF vt = SymTab.InvalidType THEN
|
|
|
+ 4052 nw := 8
|
|
|
+ 4053 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 4054 IF nw = 0 THEN nw := 8 END
|
|
|
+ 4055 END;
|
|
|
+ 4056 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 4057 QbeGen.SetZero(q, nw)
|
|
|
+ 4058 ELSIF (braceCls =
|
|
|
+ 4059 SymTab.ClArray)
|
|
|
+ 4060 OR (braceCls =
|
|
|
+ 4061 SymTab.ClRecord)
|
|
|
+ 4062 OR (braceCls =
|
|
|
+ 4063 SymTab.ClClass) THEN
|
|
|
+ 4064 QbeGen.CtorBegin(vt)
|
|
|
+ 4065 ELSE
|
|
|
+ 4066 IF vt # SymTab.InvalidType THEN
|
|
|
+ 4067 SemError(230) END;
|
|
|
+ 4068 braceCls := -1
|
|
|
+ 4069 END; .)
|
|
|
+ 4070 [ BraceElem<vt, q, astNode, astTail>
|
|
|
+ 4071 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
+ 4072 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
+ 4073 OR (braceCls =
|
|
|
+ 4074 SymTab.ClRecord)
|
|
|
+ 4075 OR (braceCls =
|
|
|
+ 4076 SymTab.ClClass) THEN
|
|
|
+ 4077 QbeGen.CtorEnd(q)
|
|
|
+ 4078 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
+ 4079 QbeGen.CopyOp("0", q)
|
|
|
+ 4080 END;
|
|
|
+ 4081 braceCls := savedCls; .)
|
|
|
+ 4082 (. astCur := astNode; .) .
|
|
|
+ 4083 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
+ 4084 VAR node, tail: AST.Node>
|
|
|
+ 4085 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 4086 qe, q2: QbeGen.QVal;
|
|
|
+ 4087 v, v2, reps, k: INTEGER;
|
|
|
+ 4088 elem: SymTab.TypeIndex;
|
|
|
+ 4089 lo: INTEGER;
|
|
|
+ 4090 span: CARDINAL;
|
|
|
+ 4091 cl, cl2: INTEGER;
|
|
|
+ 4092 hasR, hasB: BOOLEAN;
|
|
|
+ 4093 astEl: AST.Node; .)
|
|
|
+ 4094 = (. hasR := FALSE; hasB := FALSE;
|
|
|
+ 4095 reps := 1; .)
|
|
|
+ 4096 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 4097 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 4098 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 4099 hasR := TRUE; .) ]
|
|
|
+ 4100 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
+ 4101 (. IF braceCls = SymTab.ClSet THEN
|
|
|
+ 4102 IF hasB THEN SemError(230) END;
|
|
|
+ 4103 lo := SymTab.SetBaseLo(vt);
|
|
|
+ 4104 span := SymTab.SetCount(vt);
|
|
|
+ 4105 IF (et = SymTab.InvalidType)
|
|
|
+ 4106 OR (hasR AND (et2 =
|
|
|
+ 4107 SymTab.InvalidType)) THEN
|
|
|
+ 4108 ELSE cl :=
|
|
|
+ 4109 SymTab.ClassOf(et);
|
|
|
+ 4110 IF hasR THEN
|
|
|
+ 4111 cl2 :=
|
|
|
+ 4112 SymTab.ClassOf(et2)
|
|
|
+ 4113 ELSE cl2 := SymTab.ClInt
|
|
|
+ 4114 END;
|
|
|
+ 4115 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 4116 OR (hasR AND NOT
|
|
|
+ 4117 SymTab.SetElemClassOk(cl2))
|
|
|
+ 4118 THEN
|
|
|
+ 4119 SemError(222)
|
|
|
+ 4120 ELSIF hasR
|
|
|
+ 4121 AND SymTab.ConstInt(qe, v)
|
|
|
+ 4122 AND SymTab.ConstInt(q2,
|
|
|
+ 4123 v2)
|
|
|
+ 4124 AND ((v < lo)
|
|
|
+ 4125 OR (v2 < lo)
|
|
|
+ 4126 OR (v >= lo +
|
|
|
+ 4127 VAL(INTEGER, span))
|
|
|
+ 4128 OR (v2 >= lo +
|
|
|
+ 4129 VAL(INTEGER, span))
|
|
|
+ 4130 OR (v > v2)) THEN
|
|
|
+ 4131 SemError(222)
|
|
|
+ 4132 ELSIF hasR THEN
|
|
|
+ 4133 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 4134 lo, span)
|
|
|
+ 4135 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 4136 v)
|
|
|
+ 4137 AND ((v < lo)
|
|
|
+ 4138 OR (v >= lo +
|
|
|
+ 4139 VAL(INTEGER,
|
|
|
+ 4140 span))) THEN
|
|
|
+ 4141 SemError(222)
|
|
|
+ 4142 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 4143 lo, span)
|
|
|
+ 4144 END
|
|
|
4145 END
|
|
|
- 4146 END; .)
|
|
|
- 4147 (. (* the BY form repeats the
|
|
|
- 4148 element; keep the AST in
|
|
|
- 4149 step with CtorElem *)
|
|
|
- 4150 k := 0;
|
|
|
- 4151 WHILE k < reps DO
|
|
|
- 4152 AstAppend(AST.NkBlock,
|
|
|
- 4153 node, tail, astEl);
|
|
|
- 4154 INC(k)
|
|
|
- 4155 END; .) .
|
|
|
- 4156 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 4157 qe, q2: QbeGen.QVal;
|
|
|
- 4158 v, v2: INTEGER;
|
|
|
- 4159 lo: INTEGER;
|
|
|
- 4160 span: CARDINAL;
|
|
|
- 4161 cl, cl2: INTEGER;
|
|
|
- 4162 hasR: BOOLEAN;
|
|
|
- 4163 astEl: AST.Node; .)
|
|
|
- 4164 = (. hasR := FALSE; .)
|
|
|
- 4165 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 4166 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 4167 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 4168 hasR := TRUE; .) ]
|
|
|
- 4169 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 4170 span := SymTab.SetCount(st);
|
|
|
- 4171 IF (et = SymTab.InvalidType)
|
|
|
- 4172 OR (hasR AND (et2 =
|
|
|
- 4173 SymTab.InvalidType)) THEN
|
|
|
- 4174 ELSE cl :=
|
|
|
- 4175 SymTab.ClassOf(et);
|
|
|
- 4176 IF hasR THEN
|
|
|
- 4177 cl2 :=
|
|
|
- 4178 SymTab.ClassOf(et2)
|
|
|
- 4179 ELSE cl2 := SymTab.ClInt
|
|
|
- 4180 END;
|
|
|
- 4181 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 4182 OR (hasR AND NOT
|
|
|
- 4183 SymTab.SetElemClassOk(cl2))
|
|
|
- 4184 THEN
|
|
|
- 4185 SemError(222)
|
|
|
- 4186 ELSIF hasR
|
|
|
- 4187 AND SymTab.ConstInt(qe, v)
|
|
|
- 4188 AND SymTab.ConstInt(q2,
|
|
|
- 4189 v2)
|
|
|
- 4190 AND ((v < lo)
|
|
|
- 4191 OR (v2 < lo)
|
|
|
- 4192 OR (v >= lo +
|
|
|
- 4193 VAL(INTEGER, span))
|
|
|
- 4194 OR (v2 >= lo +
|
|
|
- 4195 VAL(INTEGER, span))
|
|
|
- 4196 OR (v > v2)) THEN
|
|
|
- 4197 SemError(222)
|
|
|
- 4198 ELSIF hasR THEN
|
|
|
- 4199 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 4200 lo, span)
|
|
|
- 4201 ELSIF SymTab.ConstInt(qe,
|
|
|
- 4202 v)
|
|
|
- 4203 AND ((v < lo)
|
|
|
- 4204 OR (v >= lo +
|
|
|
- 4205 VAL(INTEGER,
|
|
|
- 4206 span))) THEN
|
|
|
- 4207 SemError(222)
|
|
|
- 4208 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 4209 lo, span)
|
|
|
- 4210 END
|
|
|
- 4211 END; .)
|
|
|
- 4212 (. AST.SetChild(node,
|
|
|
- 4213 AST.NChild(node), astEl); .) .
|
|
|
- 4214 GetIdent<VAR n: SymTab.Name>
|
|
|
- 4215 = ident (. LexName(n); .) .
|
|
|
- 4216
|
|
|
- 4217 END M2.
|
|
|
+ 4146 ELSIF (braceCls = SymTab.ClArray)
|
|
|
+ 4147 OR (braceCls =
|
|
|
+ 4148 SymTab.ClRecord)
|
|
|
+ 4149 OR (braceCls =
|
|
|
+ 4150 SymTab.ClClass) THEN
|
|
|
+ 4151 IF hasR THEN SemError(230) END;
|
|
|
+ 4152 reps := 1;
|
|
|
+ 4153 IF hasB THEN
|
|
|
+ 4154 IF SymTab.ConstInt(q2, v2)
|
|
|
+ 4155 AND (v2 >= 1) THEN
|
|
|
+ 4156 reps := v2
|
|
|
+ 4157 ELSE SemError(230)
|
|
|
+ 4158 END
|
|
|
+ 4159 END;
|
|
|
+ 4160 k := 0;
|
|
|
+ 4161 WHILE k < reps DO
|
|
|
+ 4162 QbeGen.CtorElem(qe);
|
|
|
+ 4163 INC(k)
|
|
|
+ 4164 END
|
|
|
+ 4165 END; .)
|
|
|
+ 4166 (. (* the BY form repeats the
|
|
|
+ 4167 element; keep the AST in
|
|
|
+ 4168 step with CtorElem *)
|
|
|
+ 4169 k := 0;
|
|
|
+ 4170 WHILE k < reps DO
|
|
|
+ 4171 AstAppend(AST.NkBlock,
|
|
|
+ 4172 node, tail, astEl);
|
|
|
+ 4173 INC(k)
|
|
|
+ 4174 END; .) .
|
|
|
+ 4175 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 4176 qe, q2: QbeGen.QVal;
|
|
|
+ 4177 v, v2: INTEGER;
|
|
|
+ 4178 lo: INTEGER;
|
|
|
+ 4179 span: CARDINAL;
|
|
|
+ 4180 cl, cl2: INTEGER;
|
|
|
+ 4181 hasR: BOOLEAN;
|
|
|
+ 4182 astEl: AST.Node; .)
|
|
|
+ 4183 = (. hasR := FALSE; .)
|
|
|
+ 4184 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 4185 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 4186 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 4187 hasR := TRUE; .) ]
|
|
|
+ 4188 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 4189 span := SymTab.SetCount(st);
|
|
|
+ 4190 IF (et = SymTab.InvalidType)
|
|
|
+ 4191 OR (hasR AND (et2 =
|
|
|
+ 4192 SymTab.InvalidType)) THEN
|
|
|
+ 4193 ELSE cl :=
|
|
|
+ 4194 SymTab.ClassOf(et);
|
|
|
+ 4195 IF hasR THEN
|
|
|
+ 4196 cl2 :=
|
|
|
+ 4197 SymTab.ClassOf(et2)
|
|
|
+ 4198 ELSE cl2 := SymTab.ClInt
|
|
|
+ 4199 END;
|
|
|
+ 4200 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 4201 OR (hasR AND NOT
|
|
|
+ 4202 SymTab.SetElemClassOk(cl2))
|
|
|
+ 4203 THEN
|
|
|
+ 4204 SemError(222)
|
|
|
+ 4205 ELSIF hasR
|
|
|
+ 4206 AND SymTab.ConstInt(qe, v)
|
|
|
+ 4207 AND SymTab.ConstInt(q2,
|
|
|
+ 4208 v2)
|
|
|
+ 4209 AND ((v < lo)
|
|
|
+ 4210 OR (v2 < lo)
|
|
|
+ 4211 OR (v >= lo +
|
|
|
+ 4212 VAL(INTEGER, span))
|
|
|
+ 4213 OR (v2 >= lo +
|
|
|
+ 4214 VAL(INTEGER, span))
|
|
|
+ 4215 OR (v > v2)) THEN
|
|
|
+ 4216 SemError(222)
|
|
|
+ 4217 ELSIF hasR THEN
|
|
|
+ 4218 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 4219 lo, span)
|
|
|
+ 4220 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 4221 v)
|
|
|
+ 4222 AND ((v < lo)
|
|
|
+ 4223 OR (v >= lo +
|
|
|
+ 4224 VAL(INTEGER,
|
|
|
+ 4225 span))) THEN
|
|
|
+ 4226 SemError(222)
|
|
|
+ 4227 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 4228 lo, span)
|
|
|
+ 4229 END
|
|
|
+ 4230 END; .)
|
|
|
+ 4231 (. AST.SetChild(node,
|
|
|
+ 4232 AST.NChild(node), astEl); .) .
|
|
|
+ 4233 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 4234 = ident (. LexName(n); .) .
|
|
|
+ 4235
|
|
|
+ 4236 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|