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