|
@@ -2684,1067 +2684,1001 @@ Listing:
|
|
|
2666 = (. neg := FALSE; astSign := 0; .)
|
|
2666 = (. neg := FALSE; astSign := 0; .)
|
|
|
2667 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
2667 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
2668 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
2668 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
- 2669 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
|
|
- 2670 IF QbeGen.IsImm(q) THEN
|
|
|
|
|
- 2671 QbeGen.NegFold(q, q)
|
|
|
|
|
- 2672 ELSE QbeGen.NewTemp(qt);
|
|
|
|
|
- 2673 QbeGen.NegQ(q, qt,
|
|
|
|
|
- 2674 SymTab.ClassOf(t)
|
|
|
|
|
- 2675 = SymTab.ClReal);
|
|
|
|
|
- 2676 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2677 END
|
|
|
|
|
- 2678 END;
|
|
|
|
|
- 2679 IF astSign < 0 THEN
|
|
|
|
|
- 2680 astCur := AST.MakeUn(
|
|
|
|
|
- 2681 AST.NkUnary, AST.OpSub, astA);
|
|
|
|
|
- 2682 astA := astCur
|
|
|
|
|
- 2683 END; .)
|
|
|
|
|
- 2684 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
- 2685 QbeGen.DelayBegin END; .)
|
|
|
|
|
- 2686 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
|
|
- 2687 QbeGen.DelayEnd END; .)
|
|
|
|
|
- 2688 (. astOp := AST.OpAdd;
|
|
|
|
|
- 2689 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
|
|
- 2690 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
|
|
- 2691 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
- 2692 astCur := astA;
|
|
|
|
|
- 2693 IF op = SymTab.OpOr THEN
|
|
|
|
|
- 2694 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
|
|
- 2695 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 2696 t := SymTab.BoolType()
|
|
|
|
|
- 2697 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 2698 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2699 QbeGen.Slot4(qs);
|
|
|
|
|
- 2700 QbeGen.NewLabel(lTrue);
|
|
|
|
|
- 2701 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 2702 QbeGen.NewLabel(lDone);
|
|
|
|
|
- 2703 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
|
|
- 2704 QbeGen.EmitLabel(lTrue);
|
|
|
|
|
- 2705 QbeGen.StoreW(qs, "1");
|
|
|
|
|
- 2706 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2707 QbeGen.EmitLabel(lNext);
|
|
|
|
|
- 2708 QbeGen.DelayFlush;
|
|
|
|
|
- 2709 QbeGen.StoreW(qs, q2);
|
|
|
|
|
- 2710 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2711 QbeGen.EmitLabel(lDone);
|
|
|
|
|
- 2712 QbeGen.LoadW(qs, qr);
|
|
|
|
|
- 2713 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2714 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2715 END
|
|
|
|
|
- 2716 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
- 2717 AND (SymTab.UStrCompat(t, t2)
|
|
|
|
|
- 2718 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
- 2719 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
|
|
- 2720 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
|
|
- 2721 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
|
|
- 2722 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
- 2723 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
|
|
- 2724 (* UString concatenation: a UCHAR operand becomes a
|
|
|
|
|
- 2725 1-codepoint UString; the result is a descriptor in the
|
|
|
|
|
- 2726 shim's concat buffer. Work on copies so neither
|
|
|
|
|
- 2727 operand is clobbered. *)
|
|
|
|
|
- 2728 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
|
|
- 2729 QbeGen.CopyOp(q, q2a)
|
|
|
|
|
- 2730 ELSE
|
|
|
|
|
- 2731 QbeGen.UStrFrom(q, q2a)
|
|
|
|
|
- 2732 END;
|
|
|
|
|
- 2733 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
|
|
- 2734 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
|
|
- 2735 ELSE
|
|
|
|
|
- 2736 QbeGen.UStrFrom(q2, q2b);
|
|
|
|
|
- 2737 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
|
|
- 2738 END;
|
|
|
|
|
- 2739 t := SymTab.NewUStr();
|
|
|
|
|
- 2740 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2741 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
- 2742 AND (SymTab.StrCompat(t, t2)
|
|
|
|
|
- 2743 OR (SymTab.IsStrType(t)
|
|
|
|
|
- 2744 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
|
|
- 2745 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
|
|
- 2746 AND SymTab.IsStrType(t2))) THEN
|
|
|
|
|
- 2747 (* string concatenation; a CHAR operand becomes a
|
|
|
|
|
- 2748 1-character string literal. When both operands are
|
|
|
|
|
- 2749 constants, fold to a single string literal so a
|
|
|
|
|
- 2750 constructor element stays compile-time. *)
|
|
|
|
|
- 2751 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
|
|
- 2752 qt, fok);
|
|
|
|
|
- 2753 IF NOT fok THEN
|
|
|
|
|
- 2754 IF SymTab.StrCompat(t, t2) THEN
|
|
|
|
|
- 2755 QbeGen.StrCat(q, q2, qt)
|
|
|
|
|
- 2756 ELSIF SymTab.IsStrType(t) THEN
|
|
|
|
|
- 2757 QbeGen.DeclCharStr(q2, qs);
|
|
|
|
|
- 2758 QbeGen.StrCat(q, qs, qt)
|
|
|
|
|
- 2759 ELSE
|
|
|
|
|
- 2760 QbeGen.DeclCharStr(q, qs);
|
|
|
|
|
- 2761 QbeGen.StrCat(qs, q2, qt)
|
|
|
|
|
- 2762 END
|
|
|
|
|
- 2763 END;
|
|
|
|
|
- 2764 t := SymTab.NewStr();
|
|
|
|
|
- 2765 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2766 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
- 2767 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 2768 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 2769 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 2770 mw := lw;
|
|
|
|
|
- 2771 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 2772 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2773 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
|
|
- 2774 ELSE
|
|
|
|
|
- 2775 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
|
|
- 2776 END;
|
|
|
|
|
- 2777 t := SymTab.NewSet(
|
|
|
|
|
- 2778 SymTab.NewSubR(0,
|
|
|
|
|
- 2779 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 2780 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2781 ELSE
|
|
|
|
|
- 2782 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
- 2783 lt := t; rt := t2; t := res2
|
|
|
|
|
- 2784 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 2785 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2786 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
- 2787 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 2788 folded := FALSE;
|
|
|
|
|
- 2789 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
- 2790 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 2791 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2792 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
|
|
- 2793 ELSE
|
|
|
|
|
- 2794 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
|
|
- 2795 END
|
|
|
|
|
- 2796 END;
|
|
|
|
|
- 2797 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
- 2798 ELSE
|
|
|
|
|
- 2799 IF isL THEN
|
|
|
|
|
- 2800 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
- 2801 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
- 2802 END;
|
|
|
|
|
- 2803 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
- 2804 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
- 2805 END;
|
|
|
|
|
- 2806 QbeGen.NewTemp(qt);
|
|
|
|
|
- 2807 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2808 QbeGen.Op3L("add", qt, q, q2)
|
|
|
|
|
- 2809 ELSE
|
|
|
|
|
- 2810 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
|
|
- 2811 END
|
|
|
|
|
- 2812 ELSE
|
|
|
|
|
- 2813 QbeGen.NewTemp(qt);
|
|
|
|
|
- 2814 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2815 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
|
|
- 2816 ELSE
|
|
|
|
|
- 2817 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
|
|
- 2818 END
|
|
|
|
|
- 2819 END;
|
|
|
|
|
- 2820 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2821 END
|
|
|
|
|
- 2822 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2823 END
|
|
|
|
|
- 2824 END; .) } .
|
|
|
|
|
- 2825 AddOp<VAR op: INTEGER>
|
|
|
|
|
- 2826 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
- 2827 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
- 2828 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
- 2829 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2830 (. VAR t2, res2, lt, rt:
|
|
|
|
|
- 2831 SymTab.TypeIndex;
|
|
|
|
|
- 2832 op: INTEGER;
|
|
|
|
|
- 2833 q2, qt, wq, qf:
|
|
|
|
|
- 2834 QbeGen.QVal;
|
|
|
|
|
- 2835 isR, isL, folded: BOOLEAN;
|
|
|
|
|
- 2836 lw, rw, mw: CARDINAL;
|
|
|
|
|
- 2837 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
|
|
- 2838 astA, astB: AST.Node;
|
|
|
|
|
- 2839 astOp: INTEGER; .)
|
|
|
|
|
- 2840 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 2841 QbeGen.DelayBegin END; .)
|
|
|
|
|
- 2842 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 2843 QbeGen.DelayEnd END; .)
|
|
|
|
|
- 2844 (. astOp := AST.OpMul;
|
|
|
|
|
- 2845 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
|
|
- 2846 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
|
|
- 2847 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
|
|
- 2848 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
|
|
- 2849 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
- 2850 astCur := astA;
|
|
|
|
|
- 2851 IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 2852 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
|
|
- 2853 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 2854 t := SymTab.BoolType()
|
|
|
|
|
- 2855 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 2856 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2857 QbeGen.Slot4(qs);
|
|
|
|
|
- 2858 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 2859 QbeGen.NewLabel(lFalse);
|
|
|
|
|
- 2860 QbeGen.NewLabel(lDone);
|
|
|
|
|
- 2861 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
|
|
- 2862 QbeGen.EmitLabel(lNext);
|
|
|
|
|
- 2863 QbeGen.DelayFlush;
|
|
|
|
|
- 2864 QbeGen.StoreW(qs, q2);
|
|
|
|
|
- 2865 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2866 QbeGen.EmitLabel(lFalse);
|
|
|
|
|
- 2867 QbeGen.StoreW(qs, "0");
|
|
|
|
|
- 2868 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2869 QbeGen.EmitLabel(lDone);
|
|
|
|
|
- 2870 QbeGen.LoadW(qs, qr);
|
|
|
|
|
- 2871 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2872 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2873 END
|
|
|
|
|
- 2874 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
- 2875 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 2876 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 2877 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 2878 mw := lw;
|
|
|
|
|
- 2879 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 2880 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 2881 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
- 2882 ELSE
|
|
|
|
|
- 2883 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
- 2884 END;
|
|
|
|
|
- 2885 t := SymTab.NewSet(
|
|
|
|
|
- 2886 SymTab.NewSubR(0,
|
|
|
|
|
- 2887 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 2888 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2889 ELSE
|
|
|
|
|
- 2890 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
- 2891 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
- 2892 res2) THEN
|
|
|
|
|
- 2893 lt := t; rt := t2; t := res2
|
|
|
|
|
- 2894 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 2895 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2896 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
- 2897 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 2898 folded := FALSE;
|
|
|
|
|
- 2899 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
- 2900 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 2901 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 2902 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
|
|
- 2903 ELSIF op = SymTab.OpDiv THEN
|
|
|
|
|
- 2904 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
|
|
- 2905 ELSIF op = SymTab.OpMod THEN
|
|
|
|
|
- 2906 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
|
|
- 2907 END
|
|
|
|
|
- 2908 END;
|
|
|
|
|
- 2909 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
- 2910 ELSE
|
|
|
|
|
- 2911 IF isL THEN
|
|
|
|
|
- 2912 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
- 2913 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
- 2914 END;
|
|
|
|
|
- 2915 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
- 2916 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
- 2917 END;
|
|
|
|
|
- 2918 QbeGen.NewTemp(qt);
|
|
|
|
|
- 2919 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 2920 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
|
|
- 2921 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
- 2922 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
- 2923 QbeGen.Op3L("div", qt, q, q2)
|
|
|
|
|
- 2924 ELSE
|
|
|
|
|
- 2925 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
|
|
- 2926 END
|
|
|
|
|
- 2927 ELSE
|
|
|
|
|
- 2928 QbeGen.NewTemp(qt);
|
|
|
|
|
- 2929 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 2930 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
- 2931 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
- 2932 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
- 2933 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
- 2934 ELSE
|
|
|
|
|
- 2935 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
- 2936 END
|
|
|
|
|
- 2937 END;
|
|
|
|
|
- 2938 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2939 END
|
|
|
|
|
- 2940 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2941 END
|
|
|
|
|
- 2942 END; .) } .
|
|
|
|
|
- 2943 MulOp<VAR op: INTEGER>
|
|
|
|
|
- 2944 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
- 2945 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
- 2946 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
- 2947 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
- 2948 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
|
|
- 2949 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2950 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
- 2951 et, dt, t2, st, ct2, et2:
|
|
|
|
|
- 2952 SymTab.TypeIndex;
|
|
|
|
|
- 2953 dk: INTEGER;
|
|
|
|
|
- 2954 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
|
|
- 2955 QbeGen.QVal;
|
|
|
|
|
- 2956 qn, vn: SymTab.Name;
|
|
|
|
|
- 2957 vt: SymTab.TypeIndex;
|
|
|
|
|
- 2958 c1, c2: INTEGER;
|
|
|
|
|
- 2959 lo, hi: INTEGER;
|
|
|
|
|
- 2960 isMax: BOOLEAN;
|
|
|
|
|
- 2961 called, isHigh, sfx, isCh,
|
|
|
|
|
- 2962 isU, uok, isStr: BOOLEAN;
|
|
|
|
|
- 2963 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
|
|
- 2964 astD: AST.Node;
|
|
|
|
|
- 2965 astCall: BOOLEAN;
|
|
|
|
|
- 2966 astNode, astNot: AST.Node;
|
|
|
|
|
- 2967 j: CARDINAL;
|
|
|
|
|
- 2968 astArg2: AST.Node;
|
|
|
|
|
- 2969 astBrace: AST.Node;
|
|
|
|
|
- 2970 astRes: AST.Node; .)
|
|
|
|
|
- 2971 = (. astIsLit := FALSE; .)
|
|
|
|
|
- 2972 ( integer (. LexString(s);
|
|
|
|
|
- 2973 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
|
|
- 2974 t := SymTab.IntType(); .)
|
|
|
|
|
- 2975 | charConst (. LexString(s);
|
|
|
|
|
- 2976 QbeGen.NormLit(s, q, isCh);
|
|
|
|
|
- 2977 IF twoPhase THEN
|
|
|
|
|
- 2978 astIsLit := TRUE;
|
|
|
|
|
- 2979 astCur := AST.MakeLeaf(
|
|
|
|
|
- 2980 AST.NkCharLit, s)
|
|
|
|
|
- 2981 END;
|
|
|
|
|
- 2982 t := SymTab.CharType(); .)
|
|
|
|
|
- 2983 | real (. LexString(s);
|
|
|
|
|
- 2984 QbeGen.NormReal(s, q);
|
|
|
|
|
- 2985 IF twoPhase THEN
|
|
|
|
|
- 2986 astIsLit := TRUE;
|
|
|
|
|
- 2987 astCur := AST.MakeLeaf(
|
|
|
|
|
- 2988 AST.NkRealLit, s)
|
|
|
|
|
- 2989 END;
|
|
|
|
|
- 2990 t := SymTab.RealType(); .)
|
|
|
|
|
- 2991 | string (. LexString(s);
|
|
|
|
|
- 2992 IF twoPhase THEN
|
|
|
|
|
- 2993 astIsLit := TRUE;
|
|
|
|
|
- 2994 astCur := AST.MakeLeaf(
|
|
|
|
|
- 2995 AST.NkStrLit, s)
|
|
|
|
|
- 2996 END;
|
|
|
|
|
- 2997 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 2998 t := SymTab.CharType();
|
|
|
|
|
- 2999 QbeGen.IntStr(
|
|
|
|
|
- 3000 QbeGen.CharVal(s), q)
|
|
|
|
|
- 3001 ELSE t := SymTab.NewStr();
|
|
|
|
|
- 3002 QbeGen.DeclStr(s, q);
|
|
|
|
|
- 3003 (* a literal's value IS its
|
|
|
|
|
- 3004 static descriptor address *)
|
|
|
|
|
- 3005 QbeGen.NoteAddr(q, q)
|
|
|
|
|
- 3006 END; .)
|
|
|
|
|
- 3007 | ustring (. LexString(s);
|
|
|
|
|
- 3008 IF twoPhase THEN
|
|
|
|
|
- 3009 astIsLit := TRUE;
|
|
|
|
|
- 3010 astCur := AST.MakeLeaf(
|
|
|
|
|
- 3011 AST.NkStrLit, s)
|
|
|
|
|
- 3012 END;
|
|
|
|
|
- 3013 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
|
|
- 3014 uok);
|
|
|
|
|
- 3015 IF NOT uok THEN
|
|
|
|
|
- 3016 SemError(234);
|
|
|
|
|
- 3017 t := SymTab.InvalidType
|
|
|
|
|
- 3018 ELSIF isU THEN
|
|
|
|
|
- 3019 t := SymTab.UCharType();
|
|
|
|
|
- 3020 QbeGen.IntStr(ucp, q)
|
|
|
|
|
- 3021 ELSE
|
|
|
|
|
- 3022 t := SymTab.NewUStr();
|
|
|
|
|
- 3023 QbeGen.NoteAddr(q, q)
|
|
|
|
|
- 3024 END; .)
|
|
|
|
|
- 3025 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
|
|
- 3026 astNArgs := 0; called := FALSE;
|
|
|
|
|
- 3027 t := dt;
|
|
|
|
|
- 3028 IF sfx THEN
|
|
|
|
|
- 3029 IF dt =
|
|
|
|
|
- 3030 SymTab.InvalidType THEN
|
|
|
|
|
- 3031 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3032 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3033 SymTab.ClRecord)
|
|
|
|
|
- 3034 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3035 SymTab.ClSet)
|
|
|
|
|
- 3036 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3037 SymTab.ClArray)
|
|
|
|
|
- 3038 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3039 SymTab.ClClass) THEN
|
|
|
|
|
- 3040 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 3041 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
- 3042 q)
|
|
|
|
|
- 3043 END
|
|
|
|
|
- 3044 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 3045 END;
|
|
|
|
|
- 3046 IF (dk = SymTab.KindVar)
|
|
|
|
|
- 3047 OR (dk = SymTab.KindParam)
|
|
|
|
|
- 3048 OR (dk =
|
|
|
|
|
- 3049 SymTab.KindField) THEN
|
|
|
|
|
- 3050 IF sfx THEN
|
|
|
|
|
- 3051 QbeGen.NoteAddr(q, qd)
|
|
|
|
|
- 3052 ELSE
|
|
|
|
|
- 3053 QbeGen.AddrOf(qn, qa);
|
|
|
|
|
- 3054 QbeGen.NoteAddr(q, qa)
|
|
|
|
|
- 3055 END
|
|
|
|
|
- 3056 ELSIF sfx
|
|
|
|
|
- 3057 AND (dt #
|
|
|
|
|
- 3058 SymTab.InvalidType)
|
|
|
|
|
- 3059 AND ((SymTab.ClassOf(dt) =
|
|
|
|
|
- 3060 SymTab.ClArray)
|
|
|
|
|
- 3061 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3062 SymTab.ClSet)
|
|
|
|
|
- 3063 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3064 SymTab.ClRecord)) THEN
|
|
|
|
|
- 3065 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 3066 END; .)
|
|
|
|
|
- 3067 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
|
|
- 3068 astBrace := astCur; .) ]
|
|
|
|
|
- 3069 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
|
|
- 3070 (. astCall := TRUE;
|
|
|
|
|
- 3071 astNode := AstCallNode(astD);
|
|
|
|
|
- 3072 astRes := astNode;
|
|
|
|
|
- 3073 t := ct2;
|
|
|
|
|
- 3074 QbeGen.CopyOp(q2, q);
|
|
|
|
|
- 3075 sfx := FALSE; .)
|
|
|
|
|
- 3076 { ResultComp<t, q, sfx, astRes> }
|
|
|
|
|
- 3077 (. IF sfx THEN
|
|
|
|
|
- 3078 IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 3079 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3080 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
- 3081 SymTab.ClRecord)
|
|
|
|
|
- 3082 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
|
|
- 3083 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
|
|
- 3084 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
|
|
- 3085 QbeGen.ElemLoad(q, t, q2);
|
|
|
|
|
- 3086 QbeGen.CopyOp(q2, q)
|
|
|
|
|
- 3087 END
|
|
|
|
|
- 3088 END; .) ]
|
|
|
|
|
- 3089 (. IF called THEN
|
|
|
|
|
- 3090 astCur := astRes
|
|
|
|
|
- 3091 ELSIF astCall THEN
|
|
|
|
|
- 3092 astCur := astBrace
|
|
|
|
|
- 3093 ELSE astCur := astD
|
|
|
|
|
- 3094 END;
|
|
|
|
|
- 3095 astIsLit := TRUE;
|
|
|
|
|
- 3096 IF NOT called
|
|
|
|
|
- 3097 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
- 3098 (* bare zero-arg function
|
|
|
|
|
- 3099 call (parentheses may be
|
|
|
|
|
- 3100 omitted); a proper or
|
|
|
|
|
- 3101 parameterised proc here
|
|
|
|
|
- 3102 is 230 *)
|
|
|
|
|
- 3103 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
- 3104 AND (SymTab.ProcRes(qn) #
|
|
|
|
|
- 3105 SymTab.InvalidType) THEN
|
|
|
|
|
- 3106 QbeGen.Mangled(qn,
|
|
|
|
|
- 3107 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 3108 QbeGen.CallBegin(qm0,
|
|
|
|
|
- 3109 SymTab.ProcRes(qn),
|
|
|
|
|
- 3110 SymTab.ProcDepthOf(qn),
|
|
|
|
|
- 3111 SymTab.IsExternal(qn));
|
|
|
|
|
- 3112 QbeGen.CallEnd(TRUE, q);
|
|
|
|
|
- 3113 astCur := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3114 AST.SetChild(astCur, 0, astD);
|
|
|
|
|
- 3115 t := SymTab.ProcRes(qn)
|
|
|
|
|
- 3116 ELSE
|
|
|
|
|
- 3117 (* procedure used as a
|
|
|
|
|
- 3118 value (assign to a
|
|
|
|
|
- 3119 procedure variable):
|
|
|
|
|
- 3120 its code address *)
|
|
|
|
|
- 3121 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
- 3122 QbeGen.Mangled(qn,
|
|
|
|
|
- 3123 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 3124 QbeGen.ProcAddr(qm0, q)
|
|
|
|
|
- 3125 END
|
|
|
|
|
- 3126 END; .)
|
|
|
|
|
- 3127 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
- 3128 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
- 3129 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
|
|
- 3130 isU := FALSE; .)
|
|
|
|
|
- 3131 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
- 3132 isStr := TRUE;
|
|
|
|
|
- 3133 isU := FALSE;
|
|
|
|
|
- 3134 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 3135 dt := SymTab.CharType();
|
|
|
|
|
- 3136 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
|
|
- 3137 qd)
|
|
|
|
|
- 3138 ELSE
|
|
|
|
|
- 3139 dt := SymTab.NewStr();
|
|
|
|
|
- 3140 QbeGen.DeclStr(s, qd);
|
|
|
|
|
- 3141 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 3142 END;
|
|
|
|
|
- 3143 dk := -1;
|
|
|
|
|
- 3144 qn[0] := CHR(0); .)
|
|
|
|
|
- 3145 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
- 3146 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
|
|
- 3147 uok);
|
|
|
|
|
- 3148 isStr := FALSE;
|
|
|
|
|
- 3149 IF NOT uok THEN
|
|
|
|
|
- 3150 SemError(234);
|
|
|
|
|
- 3151 dt := SymTab.InvalidType
|
|
|
|
|
- 3152 ELSIF isU THEN
|
|
|
|
|
- 3153 (* one codepoint: a UCHAR;
|
|
|
|
|
- 3154 LEN is 1, HIGH is 0 *)
|
|
|
|
|
- 3155 dt := SymTab.UCharType();
|
|
|
|
|
- 3156 QbeGen.IntStr(ucp, qd)
|
|
|
|
|
- 3157 ELSE
|
|
|
|
|
- 3158 dt := SymTab.NewUStr();
|
|
|
|
|
- 3159 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 3160 END;
|
|
|
|
|
- 3161 dk := -1;
|
|
|
|
|
- 3162 qn[0] := CHR(0); .) )
|
|
|
|
|
- 3163 ")"
|
|
|
|
|
- 3164 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3165 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
|
|
- 3166 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
|
|
- 3167 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
- 3168 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
|
|
- 3169 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3170 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
- 3171 IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 3172 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
|
|
- 3173 (* UString: the count is
|
|
|
|
|
- 3174 the descriptor header *)
|
|
|
|
|
- 3175 IF isHigh THEN
|
|
|
|
|
- 3176 QbeGen.UStrLen(qd, qr);
|
|
|
|
|
- 3177 QbeGen.DecQ(qr)
|
|
|
|
|
- 3178 ELSE
|
|
|
|
|
- 3179 QbeGen.UStrLen(qd, qr)
|
|
|
|
|
- 3180 END;
|
|
|
|
|
- 3181 t := SymTab.IntType();
|
|
|
|
|
- 3182 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3183 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
- 3184 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
|
|
- 3185 (* single UCHAR codepoint *)
|
|
|
|
|
- 3186 IF isHigh THEN
|
|
|
|
|
- 3187 QbeGen.CopyOp("0", qr)
|
|
|
|
|
- 3188 ELSE
|
|
|
|
|
- 3189 QbeGen.CopyOp("1", qr)
|
|
|
|
|
- 3190 END;
|
|
|
|
|
- 3191 t := SymTab.IntType();
|
|
|
|
|
- 3192 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3193 ELSIF isStr THEN
|
|
|
|
|
- 3194 (* fold: content length at
|
|
|
|
|
- 3195 compile time *)
|
|
|
|
|
- 3196 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 3197 c1 := 1
|
|
|
|
|
- 3198 ELSE
|
|
|
|
|
- 3199 c1 :=
|
|
|
|
|
- 3200 SymTab.StrLen(s) - 2
|
|
|
|
|
- 3201 END;
|
|
|
|
|
- 3202 IF isHigh THEN
|
|
|
|
|
- 3203 DEC(c1)
|
|
|
|
|
- 3204 END;
|
|
|
|
|
- 3205 QbeGen.IntStr(c1, qr);
|
|
|
|
|
- 3206 t := SymTab.IntType();
|
|
|
|
|
- 3207 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3208 ELSIF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 3209 t := SymTab.InvalidType;
|
|
|
|
|
- 3210 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3211 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 3212 SymTab.ClArray THEN
|
|
|
|
|
- 3213 SemError(217);
|
|
|
|
|
- 3214 t := SymTab.InvalidType;
|
|
|
|
|
- 3215 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3216 ELSE
|
|
|
|
|
- 3217 IF isHigh THEN
|
|
|
|
|
- 3218 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 3219 QbeGen.OpenHi(qd, qr)
|
|
|
|
|
- 3220 ELSE
|
|
|
|
|
- 3221 QbeGen.IntStr(
|
|
|
|
|
- 3222 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
- 3223 END
|
|
|
|
|
- 3224 ELSE
|
|
|
|
|
- 3225 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 3226 QbeGen.LoadCount(qd, qr)
|
|
|
|
|
- 3227 ELSE
|
|
|
|
|
- 3228 QbeGen.IntStr(VAL(
|
|
|
|
|
- 3229 INTEGER,
|
|
|
|
|
- 3230 SymTab.ArrayLen(dt)),
|
|
|
|
|
- 3231 qr)
|
|
|
|
|
- 3232 END
|
|
|
|
|
- 3233 END;
|
|
|
|
|
- 3234 t := SymTab.IntType();
|
|
|
|
|
- 3235 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 3236 END; .)
|
|
|
|
|
- 3237 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 3238 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3239 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
|
|
- 3240 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3241 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3242 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 3243 t := SymTab.InvalidType;
|
|
|
|
|
- 3244 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3245 ELSE
|
|
|
|
|
- 3246 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
- 3247 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
|
|
+ 2669 Term<t, q> (. astA := astCur;
|
|
|
|
|
+ 2670 IF neg AND QbeGen.IsImm(q) THEN
|
|
|
|
|
+ 2671 QbeGen.NegFold(q, q)
|
|
|
|
|
+ 2672 END;
|
|
|
|
|
+ 2673 IF astSign < 0 THEN
|
|
|
|
|
+ 2674 astCur := AST.MakeUn(
|
|
|
|
|
+ 2675 AST.NkUnary, AST.OpSub, astA);
|
|
|
|
|
+ 2676 astA := astCur
|
|
|
|
|
+ 2677 END; .)
|
|
|
|
|
+ 2678 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 2679 QbeGen.DelayBegin END; .)
|
|
|
|
|
+ 2680 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 2681 QbeGen.DelayEnd END; .)
|
|
|
|
|
+ 2682 (. astOp := AST.OpAdd;
|
|
|
|
|
+ 2683 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
|
|
+ 2684 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
|
|
+ 2685 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
+ 2686 astCur := astA;
|
|
|
|
|
+ 2687 IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 2688 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
|
|
+ 2689 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 2690 t := SymTab.BoolType()
|
|
|
|
|
+ 2691 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2692 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2693 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 2694 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2695 END
|
|
|
|
|
+ 2696 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
+ 2697 AND (SymTab.UStrCompat(t, t2)
|
|
|
|
|
+ 2698 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
+ 2699 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
|
|
+ 2700 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
|
|
+ 2701 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
|
|
+ 2702 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
+ 2703 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
|
|
+ 2704 (* UString concatenation: a UCHAR operand becomes a
|
|
|
|
|
+ 2705 1-codepoint UString; the result is a descriptor in the
|
|
|
|
|
+ 2706 shim's concat buffer. Work on copies so neither
|
|
|
|
|
+ 2707 operand is clobbered. *)
|
|
|
|
|
+ 2708 t := SymTab.NewUStr();
|
|
|
|
|
+ 2709 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 2710 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
+ 2711 AND (SymTab.StrCompat(t, t2)
|
|
|
|
|
+ 2712 OR (SymTab.IsStrType(t)
|
|
|
|
|
+ 2713 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
|
|
+ 2714 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
|
|
+ 2715 AND SymTab.IsStrType(t2))) THEN
|
|
|
|
|
+ 2716 (* string concatenation; a CHAR operand becomes a
|
|
|
|
|
+ 2717 1-character string literal. When both operands are
|
|
|
|
|
+ 2718 constants, fold to a single string literal so a
|
|
|
|
|
+ 2719 constructor element stays compile-time. *)
|
|
|
|
|
+ 2720 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
|
|
+ 2721 qt, fok);
|
|
|
|
|
+ 2722 IF fok THEN QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2723 ELSE QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 2724 END;
|
|
|
|
|
+ 2725 t := SymTab.NewStr()
|
|
|
|
|
+ 2726 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 2727 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 2728 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 2729 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 2730 mw := lw;
|
|
|
|
|
+ 2731 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 2732 t := SymTab.NewSet(
|
|
|
|
|
+ 2733 SymTab.NewSubR(0,
|
|
|
|
|
+ 2734 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 2735 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 2736 ELSE
|
|
|
|
|
+ 2737 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
+ 2738 lt := t; rt := t2; t := res2
|
|
|
|
|
+ 2739 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2740 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2741 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
+ 2742 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 2743 folded := FALSE;
|
|
|
|
|
+ 2744 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
+ 2745 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 2746 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 2747 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
|
|
+ 2748 ELSE
|
|
|
|
|
+ 2749 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
|
|
+ 2750 END
|
|
|
|
|
+ 2751 END;
|
|
|
|
|
+ 2752 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
+ 2753 ELSE
|
|
|
|
|
+ 2754 QbeGen.CopyOp("@", q)
|
|
|
|
|
+ 2755 END
|
|
|
|
|
+ 2756 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2757 END
|
|
|
|
|
+ 2758 END; .) } .
|
|
|
|
|
+ 2759 AddOp<VAR op: INTEGER>
|
|
|
|
|
+ 2760 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
+ 2761 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
+ 2762 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
+ 2763 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2764 (. VAR t2, res2, lt, rt:
|
|
|
|
|
+ 2765 SymTab.TypeIndex;
|
|
|
|
|
+ 2766 op: INTEGER;
|
|
|
|
|
+ 2767 q2, qt, wq, qf:
|
|
|
|
|
+ 2768 QbeGen.QVal;
|
|
|
|
|
+ 2769 isR, isL, folded: BOOLEAN;
|
|
|
|
|
+ 2770 lw, rw, mw: CARDINAL;
|
|
|
|
|
+ 2771 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
|
|
+ 2772 astA, astB: AST.Node;
|
|
|
|
|
+ 2773 astOp: INTEGER; .)
|
|
|
|
|
+ 2774 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 2775 QbeGen.DelayBegin END; .)
|
|
|
|
|
+ 2776 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 2777 QbeGen.DelayEnd END; .)
|
|
|
|
|
+ 2778 (. astOp := AST.OpMul;
|
|
|
|
|
+ 2779 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
|
|
+ 2780 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
|
|
+ 2781 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
|
|
+ 2782 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
|
|
+ 2783 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
+ 2784 astCur := astA;
|
|
|
|
|
+ 2785 IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 2786 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
|
|
+ 2787 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 2788 t := SymTab.BoolType()
|
|
|
|
|
+ 2789 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2790 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2791 QbeGen.Slot4(qs);
|
|
|
|
|
+ 2792 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 2793 QbeGen.NewLabel(lFalse);
|
|
|
|
|
+ 2794 QbeGen.NewLabel(lDone);
|
|
|
|
|
+ 2795 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
|
|
+ 2796 QbeGen.EmitLabel(lNext);
|
|
|
|
|
+ 2797 QbeGen.DelayFlush;
|
|
|
|
|
+ 2798 QbeGen.StoreW(qs, q2);
|
|
|
|
|
+ 2799 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 2800 QbeGen.EmitLabel(lFalse);
|
|
|
|
|
+ 2801 QbeGen.StoreW(qs, "0");
|
|
|
|
|
+ 2802 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 2803 QbeGen.EmitLabel(lDone);
|
|
|
|
|
+ 2804 QbeGen.LoadW(qs, qr);
|
|
|
|
|
+ 2805 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2806 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2807 END
|
|
|
|
|
+ 2808 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 2809 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 2810 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 2811 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 2812 mw := lw;
|
|
|
|
|
+ 2813 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 2814 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 2815 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
+ 2816 ELSE
|
|
|
|
|
+ 2817 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
+ 2818 END;
|
|
|
|
|
+ 2819 t := SymTab.NewSet(
|
|
|
|
|
+ 2820 SymTab.NewSubR(0,
|
|
|
|
|
+ 2821 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 2822 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2823 ELSE
|
|
|
|
|
+ 2824 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
+ 2825 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
+ 2826 res2) THEN
|
|
|
|
|
+ 2827 lt := t; rt := t2; t := res2
|
|
|
|
|
+ 2828 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2829 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2830 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
+ 2831 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 2832 folded := FALSE;
|
|
|
|
|
+ 2833 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
+ 2834 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 2835 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 2836 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
|
|
+ 2837 ELSIF op = SymTab.OpDiv THEN
|
|
|
|
|
+ 2838 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
|
|
+ 2839 ELSIF op = SymTab.OpMod THEN
|
|
|
|
|
+ 2840 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
|
|
+ 2841 END
|
|
|
|
|
+ 2842 END;
|
|
|
|
|
+ 2843 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
+ 2844 ELSE
|
|
|
|
|
+ 2845 IF isL THEN
|
|
|
|
|
+ 2846 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
+ 2847 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
+ 2848 END;
|
|
|
|
|
+ 2849 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
+ 2850 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
+ 2851 END;
|
|
|
|
|
+ 2852 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 2853 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 2854 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
|
|
+ 2855 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
+ 2856 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
+ 2857 QbeGen.Op3L("div", qt, q, q2)
|
|
|
|
|
+ 2858 ELSE
|
|
|
|
|
+ 2859 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
|
|
+ 2860 END
|
|
|
|
|
+ 2861 ELSE
|
|
|
|
|
+ 2862 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 2863 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 2864 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
+ 2865 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
+ 2866 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
+ 2867 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
+ 2868 ELSE
|
|
|
|
|
+ 2869 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
+ 2870 END
|
|
|
|
|
+ 2871 END;
|
|
|
|
|
+ 2872 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2873 END
|
|
|
|
|
+ 2874 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2875 END
|
|
|
|
|
+ 2876 END; .) } .
|
|
|
|
|
+ 2877 MulOp<VAR op: INTEGER>
|
|
|
|
|
+ 2878 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
+ 2879 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
+ 2880 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
+ 2881 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
+ 2882 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
|
|
+ 2883 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2884 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
+ 2885 et, dt, t2, st, ct2, et2:
|
|
|
|
|
+ 2886 SymTab.TypeIndex;
|
|
|
|
|
+ 2887 dk: INTEGER;
|
|
|
|
|
+ 2888 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
|
|
+ 2889 QbeGen.QVal;
|
|
|
|
|
+ 2890 qn, vn: SymTab.Name;
|
|
|
|
|
+ 2891 vt: SymTab.TypeIndex;
|
|
|
|
|
+ 2892 c1, c2: INTEGER;
|
|
|
|
|
+ 2893 lo, hi: INTEGER;
|
|
|
|
|
+ 2894 isMax: BOOLEAN;
|
|
|
|
|
+ 2895 called, isHigh, sfx, isCh,
|
|
|
|
|
+ 2896 isU, uok, isStr: BOOLEAN;
|
|
|
|
|
+ 2897 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
|
|
+ 2898 astD: AST.Node;
|
|
|
|
|
+ 2899 astCall: BOOLEAN;
|
|
|
|
|
+ 2900 astNode, astNot: AST.Node;
|
|
|
|
|
+ 2901 j: CARDINAL;
|
|
|
|
|
+ 2902 astArg2: AST.Node;
|
|
|
|
|
+ 2903 astBrace: AST.Node;
|
|
|
|
|
+ 2904 astRes: AST.Node; .)
|
|
|
|
|
+ 2905 = (. astIsLit := FALSE; .)
|
|
|
|
|
+ 2906 ( integer (. LexString(s);
|
|
|
|
|
+ 2907 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
|
|
+ 2908 t := SymTab.IntType(); .)
|
|
|
|
|
+ 2909 | charConst (. LexString(s);
|
|
|
|
|
+ 2910 QbeGen.NormLit(s, q, isCh);
|
|
|
|
|
+ 2911 IF twoPhase THEN
|
|
|
|
|
+ 2912 astIsLit := TRUE;
|
|
|
|
|
+ 2913 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2914 AST.NkCharLit, s)
|
|
|
|
|
+ 2915 END;
|
|
|
|
|
+ 2916 t := SymTab.CharType(); .)
|
|
|
|
|
+ 2917 | real (. LexString(s);
|
|
|
|
|
+ 2918 QbeGen.NormReal(s, q);
|
|
|
|
|
+ 2919 IF twoPhase THEN
|
|
|
|
|
+ 2920 astIsLit := TRUE;
|
|
|
|
|
+ 2921 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2922 AST.NkRealLit, s)
|
|
|
|
|
+ 2923 END;
|
|
|
|
|
+ 2924 t := SymTab.RealType(); .)
|
|
|
|
|
+ 2925 | string (. LexString(s);
|
|
|
|
|
+ 2926 IF twoPhase THEN
|
|
|
|
|
+ 2927 astIsLit := TRUE;
|
|
|
|
|
+ 2928 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2929 AST.NkStrLit, s)
|
|
|
|
|
+ 2930 END;
|
|
|
|
|
+ 2931 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 2932 t := SymTab.CharType();
|
|
|
|
|
+ 2933 QbeGen.IntStr(
|
|
|
|
|
+ 2934 QbeGen.CharVal(s), q)
|
|
|
|
|
+ 2935 ELSE t := SymTab.NewStr();
|
|
|
|
|
+ 2936 QbeGen.DeclStr(s, q);
|
|
|
|
|
+ 2937 (* a literal's value IS its
|
|
|
|
|
+ 2938 static descriptor address *)
|
|
|
|
|
+ 2939 QbeGen.NoteAddr(q, q)
|
|
|
|
|
+ 2940 END; .)
|
|
|
|
|
+ 2941 | ustring (. LexString(s);
|
|
|
|
|
+ 2942 IF twoPhase THEN
|
|
|
|
|
+ 2943 astIsLit := TRUE;
|
|
|
|
|
+ 2944 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2945 AST.NkStrLit, s)
|
|
|
|
|
+ 2946 END;
|
|
|
|
|
+ 2947 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
|
|
+ 2948 uok);
|
|
|
|
|
+ 2949 IF NOT uok THEN
|
|
|
|
|
+ 2950 SemError(234);
|
|
|
|
|
+ 2951 t := SymTab.InvalidType
|
|
|
|
|
+ 2952 ELSIF isU THEN
|
|
|
|
|
+ 2953 t := SymTab.UCharType();
|
|
|
|
|
+ 2954 QbeGen.IntStr(ucp, q)
|
|
|
|
|
+ 2955 ELSE
|
|
|
|
|
+ 2956 t := SymTab.NewUStr();
|
|
|
|
|
+ 2957 QbeGen.NoteAddr(q, q)
|
|
|
|
|
+ 2958 END; .)
|
|
|
|
|
+ 2959 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
|
|
+ 2960 astNArgs := 0; called := FALSE;
|
|
|
|
|
+ 2961 t := dt;
|
|
|
|
|
+ 2962 IF sfx THEN
|
|
|
|
|
+ 2963 IF dt =
|
|
|
|
|
+ 2964 SymTab.InvalidType THEN
|
|
|
|
|
+ 2965 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2966 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2967 SymTab.ClRecord)
|
|
|
|
|
+ 2968 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2969 SymTab.ClSet)
|
|
|
|
|
+ 2970 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2971 SymTab.ClArray)
|
|
|
|
|
+ 2972 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2973 SymTab.ClClass) THEN
|
|
|
|
|
+ 2974 QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2975 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
+ 2976 q)
|
|
|
|
|
+ 2977 END
|
|
|
|
|
+ 2978 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2979 END;
|
|
|
|
|
+ 2980 IF (dk = SymTab.KindVar)
|
|
|
|
|
+ 2981 OR (dk = SymTab.KindParam)
|
|
|
|
|
+ 2982 OR (dk =
|
|
|
|
|
+ 2983 SymTab.KindField) THEN
|
|
|
|
|
+ 2984 IF sfx THEN
|
|
|
|
|
+ 2985 QbeGen.NoteAddr(q, qd)
|
|
|
|
|
+ 2986 ELSE
|
|
|
|
|
+ 2987 QbeGen.AddrOf(qn, qa);
|
|
|
|
|
+ 2988 QbeGen.NoteAddr(q, qa)
|
|
|
|
|
+ 2989 END
|
|
|
|
|
+ 2990 ELSIF sfx
|
|
|
|
|
+ 2991 AND (dt #
|
|
|
|
|
+ 2992 SymTab.InvalidType)
|
|
|
|
|
+ 2993 AND ((SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2994 SymTab.ClArray)
|
|
|
|
|
+ 2995 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2996 SymTab.ClSet)
|
|
|
|
|
+ 2997 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2998 SymTab.ClRecord)) THEN
|
|
|
|
|
+ 2999 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 3000 END; .)
|
|
|
|
|
+ 3001 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
|
|
+ 3002 astBrace := astCur; .) ]
|
|
|
|
|
+ 3003 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
|
|
+ 3004 (. astCall := TRUE;
|
|
|
|
|
+ 3005 astNode := AstCallNode(astD);
|
|
|
|
|
+ 3006 astRes := astNode;
|
|
|
|
|
+ 3007 t := ct2;
|
|
|
|
|
+ 3008 QbeGen.CopyOp(q2, q);
|
|
|
|
|
+ 3009 sfx := FALSE; .)
|
|
|
|
|
+ 3010 { ResultComp<t, q, sfx, astRes> }
|
|
|
|
|
+ 3011 (. IF sfx THEN
|
|
|
|
|
+ 3012 IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 3013 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3014 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
+ 3015 SymTab.ClRecord)
|
|
|
|
|
+ 3016 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
|
|
+ 3017 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
|
|
+ 3018 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
|
|
+ 3019 QbeGen.ElemLoad(q, t, q2);
|
|
|
|
|
+ 3020 QbeGen.CopyOp(q2, q)
|
|
|
|
|
+ 3021 END
|
|
|
|
|
+ 3022 END; .) ]
|
|
|
|
|
+ 3023 (. IF called THEN
|
|
|
|
|
+ 3024 astCur := astRes
|
|
|
|
|
+ 3025 ELSIF astCall THEN
|
|
|
|
|
+ 3026 astCur := astBrace
|
|
|
|
|
+ 3027 ELSE astCur := astD
|
|
|
|
|
+ 3028 END;
|
|
|
|
|
+ 3029 astIsLit := TRUE;
|
|
|
|
|
+ 3030 IF NOT called
|
|
|
|
|
+ 3031 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
+ 3032 (* bare zero-arg function
|
|
|
|
|
+ 3033 call (parentheses may be
|
|
|
|
|
+ 3034 omitted); a proper or
|
|
|
|
|
+ 3035 parameterised proc here
|
|
|
|
|
+ 3036 is 230 *)
|
|
|
|
|
+ 3037 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
+ 3038 AND (SymTab.ProcRes(qn) #
|
|
|
|
|
+ 3039 SymTab.InvalidType) THEN
|
|
|
|
|
+ 3040 QbeGen.Mangled(qn,
|
|
|
|
|
+ 3041 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
+ 3042 QbeGen.CallBegin(qm0,
|
|
|
|
|
+ 3043 SymTab.ProcRes(qn),
|
|
|
|
|
+ 3044 SymTab.ProcDepthOf(qn),
|
|
|
|
|
+ 3045 SymTab.IsExternal(qn));
|
|
|
|
|
+ 3046 QbeGen.CallEnd(TRUE, q);
|
|
|
|
|
+ 3047 astCur := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3048 AST.SetChild(astCur, 0, astD);
|
|
|
|
|
+ 3049 t := SymTab.ProcRes(qn)
|
|
|
|
|
+ 3050 ELSE
|
|
|
|
|
+ 3051 (* procedure used as a
|
|
|
|
|
+ 3052 value (assign to a
|
|
|
|
|
+ 3053 procedure variable):
|
|
|
|
|
+ 3054 its code address *)
|
|
|
|
|
+ 3055 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
+ 3056 QbeGen.Mangled(qn,
|
|
|
|
|
+ 3057 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
+ 3058 QbeGen.ProcAddr(qm0, q)
|
|
|
|
|
+ 3059 END
|
|
|
|
|
+ 3060 END; .)
|
|
|
|
|
+ 3061 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
+ 3062 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
+ 3063 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
|
|
+ 3064 isU := FALSE; .)
|
|
|
|
|
+ 3065 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
+ 3066 isStr := TRUE;
|
|
|
|
|
+ 3067 isU := FALSE;
|
|
|
|
|
+ 3068 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 3069 dt := SymTab.CharType();
|
|
|
|
|
+ 3070 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
|
|
+ 3071 qd)
|
|
|
|
|
+ 3072 ELSE
|
|
|
|
|
+ 3073 dt := SymTab.NewStr();
|
|
|
|
|
+ 3074 QbeGen.DeclStr(s, qd);
|
|
|
|
|
+ 3075 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 3076 END;
|
|
|
|
|
+ 3077 dk := -1;
|
|
|
|
|
+ 3078 qn[0] := CHR(0); .)
|
|
|
|
|
+ 3079 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
|
|
+ 3080 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
|
|
+ 3081 uok);
|
|
|
|
|
+ 3082 isStr := FALSE;
|
|
|
|
|
+ 3083 IF NOT uok THEN
|
|
|
|
|
+ 3084 SemError(234);
|
|
|
|
|
+ 3085 dt := SymTab.InvalidType
|
|
|
|
|
+ 3086 ELSIF isU THEN
|
|
|
|
|
+ 3087 (* one codepoint: a UCHAR;
|
|
|
|
|
+ 3088 LEN is 1, HIGH is 0 *)
|
|
|
|
|
+ 3089 dt := SymTab.UCharType();
|
|
|
|
|
+ 3090 QbeGen.IntStr(ucp, qd)
|
|
|
|
|
+ 3091 ELSE
|
|
|
|
|
+ 3092 dt := SymTab.NewUStr();
|
|
|
|
|
+ 3093 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 3094 END;
|
|
|
|
|
+ 3095 dk := -1;
|
|
|
|
|
+ 3096 qn[0] := CHR(0); .) )
|
|
|
|
|
+ 3097 ")"
|
|
|
|
|
+ 3098 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3099 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3100 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
|
|
+ 3101 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3102 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
|
|
+ 3103 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3104 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
+ 3105 IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 3106 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
|
|
+ 3107 (* UString: the count is
|
|
|
|
|
+ 3108 the descriptor header *)
|
|
|
|
|
+ 3109 IF isHigh THEN
|
|
|
|
|
+ 3110 QbeGen.UStrLen(qd, qr);
|
|
|
|
|
+ 3111 QbeGen.DecQ(qr)
|
|
|
|
|
+ 3112 ELSE
|
|
|
|
|
+ 3113 QbeGen.UStrLen(qd, qr)
|
|
|
|
|
+ 3114 END;
|
|
|
|
|
+ 3115 t := SymTab.IntType();
|
|
|
|
|
+ 3116 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3117 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 3118 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
|
|
+ 3119 (* single UCHAR codepoint *)
|
|
|
|
|
+ 3120 IF isHigh THEN
|
|
|
|
|
+ 3121 QbeGen.CopyOp("0", qr)
|
|
|
|
|
+ 3122 ELSE
|
|
|
|
|
+ 3123 QbeGen.CopyOp("1", qr)
|
|
|
|
|
+ 3124 END;
|
|
|
|
|
+ 3125 t := SymTab.IntType();
|
|
|
|
|
+ 3126 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3127 ELSIF isStr THEN
|
|
|
|
|
+ 3128 (* fold: content length at
|
|
|
|
|
+ 3129 compile time *)
|
|
|
|
|
+ 3130 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 3131 c1 := 1
|
|
|
|
|
+ 3132 ELSE
|
|
|
|
|
+ 3133 c1 :=
|
|
|
|
|
+ 3134 SymTab.StrLen(s) - 2
|
|
|
|
|
+ 3135 END;
|
|
|
|
|
+ 3136 IF isHigh THEN
|
|
|
|
|
+ 3137 DEC(c1)
|
|
|
|
|
+ 3138 END;
|
|
|
|
|
+ 3139 QbeGen.IntStr(c1, qr);
|
|
|
|
|
+ 3140 t := SymTab.IntType();
|
|
|
|
|
+ 3141 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3142 ELSIF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3143 t := SymTab.InvalidType;
|
|
|
|
|
+ 3144 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3145 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 3146 SymTab.ClArray THEN
|
|
|
|
|
+ 3147 SemError(217);
|
|
|
|
|
+ 3148 t := SymTab.InvalidType;
|
|
|
|
|
+ 3149 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3150 ELSE
|
|
|
|
|
+ 3151 IF isHigh THEN
|
|
|
|
|
+ 3152 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
+ 3153 QbeGen.OpenHi(qd, qr)
|
|
|
|
|
+ 3154 ELSE
|
|
|
|
|
+ 3155 QbeGen.IntStr(
|
|
|
|
|
+ 3156 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
+ 3157 END
|
|
|
|
|
+ 3158 ELSE
|
|
|
|
|
+ 3159 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
+ 3160 QbeGen.LoadCount(qd, qr)
|
|
|
|
|
+ 3161 ELSE
|
|
|
|
|
+ 3162 QbeGen.IntStr(VAL(
|
|
|
|
|
+ 3163 INTEGER,
|
|
|
|
|
+ 3164 SymTab.ArrayLen(dt)),
|
|
|
|
|
+ 3165 qr)
|
|
|
|
|
+ 3166 END
|
|
|
|
|
+ 3167 END;
|
|
|
|
|
+ 3168 t := SymTab.IntType();
|
|
|
|
|
+ 3169 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 3170 END; .)
|
|
|
|
|
+ 3171 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 3172 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3173 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
|
|
+ 3174 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3175 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3176 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3177 t := SymTab.InvalidType;
|
|
|
|
|
+ 3178 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3179 ELSE
|
|
|
|
|
+ 3180 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
+ 3181 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
+ 3182 t := SymTab.IntType()
|
|
|
|
|
+ 3183 END; .)
|
|
|
|
|
+ 3184 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
|
|
+ 3185 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
|
|
+ 3186 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
|
|
+ 3187 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3188 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3189 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
|
|
+ 3190 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3191 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
|
|
+ 3192 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
+ 3193 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
+ 3194 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
+ 3195 (* set shift/rotate: isMax
|
|
|
|
|
+ 3196 doubles as "rotate" *)
|
|
|
|
|
+ 3197 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3198 AND (SymTab.ClassOf(et) =
|
|
|
|
|
+ 3199 SymTab.ClSet) THEN
|
|
|
|
|
+ 3200 QbeGen.SetShift(q, q2,
|
|
|
|
|
+ 3201 SymTab.SetWords(et),
|
|
|
|
|
+ 3202 SymTab.SetCount(et), isMax,
|
|
|
|
|
+ 3203 qt);
|
|
|
|
|
+ 3204 t := et;
|
|
|
|
|
+ 3205 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 3206 ELSE SemError(230);
|
|
|
|
|
+ 3207 t := SymTab.InvalidType;
|
|
|
|
|
+ 3208 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3209 END; .)
|
|
|
|
|
+ 3210 | ( "MIN" (. isMax := FALSE; .)
|
|
|
|
|
+ 3211 | "MAX" (. isMax := TRUE; .) )
|
|
|
|
|
+ 3212 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 3213 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3214 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3215 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
|
|
+ 3216 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
+ 3217 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
|
|
+ 3218 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3219 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
+ 3220 IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 3221 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
|
|
+ 3222 (* REAL/LONGREAL: the
|
|
|
|
|
+ 3223 implementation bounds *)
|
|
|
|
|
+ 3224 IF isMax THEN
|
|
|
|
|
+ 3225 QbeGen.NormReal(
|
|
|
|
|
+ 3226 "3.402823e38", q)
|
|
|
|
|
+ 3227 ELSE QbeGen.NormReal(
|
|
|
|
|
+ 3228 "-3.402823e38", q)
|
|
|
|
|
+ 3229 END;
|
|
|
|
|
+ 3230 t := SymTab.RealType()
|
|
|
|
|
+ 3231 ELSIF (dt #
|
|
|
|
|
+ 3232 SymTab.InvalidType)
|
|
|
|
|
+ 3233 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 3234 SymTab.ClLong) THEN
|
|
|
|
|
+ 3235 IF isMax THEN
|
|
|
|
|
+ 3236 QbeGen.CopyOp(
|
|
|
|
|
+ 3237 "9223372036854775807", q)
|
|
|
|
|
+ 3238 ELSE QbeGen.CopyOp(
|
|
|
|
|
+ 3239 "-9223372036854775808", q)
|
|
|
|
|
+ 3240 END;
|
|
|
|
|
+ 3241 t := SymTab.LongType()
|
|
|
|
|
+ 3242 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
|
|
+ 3243 hi) THEN
|
|
|
|
|
+ 3244 IF isMax THEN
|
|
|
|
|
+ 3245 QbeGen.IntStr(hi, q)
|
|
|
|
|
+ 3246 ELSE QbeGen.IntStr(lo, q)
|
|
|
|
|
+ 3247 END;
|
|
|
3248 t := SymTab.IntType()
|
|
3248 t := SymTab.IntType()
|
|
|
- 3249 END; .)
|
|
|
|
|
- 3250 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
|
|
- 3251 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
|
|
- 3252 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
|
|
- 3253 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3254 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
- 3255 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
|
|
- 3256 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
- 3257 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
|
|
- 3258 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
- 3259 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
- 3260 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
- 3261 (* set shift/rotate: isMax
|
|
|
|
|
- 3262 doubles as "rotate" *)
|
|
|
|
|
- 3263 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3264 AND (SymTab.ClassOf(et) =
|
|
|
|
|
- 3265 SymTab.ClSet) THEN
|
|
|
|
|
- 3266 QbeGen.SetShift(q, q2,
|
|
|
|
|
- 3267 SymTab.SetWords(et),
|
|
|
|
|
- 3268 SymTab.SetCount(et), isMax,
|
|
|
|
|
- 3269 qt);
|
|
|
|
|
- 3270 t := et;
|
|
|
|
|
- 3271 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 3272 ELSE SemError(230);
|
|
|
|
|
- 3273 t := SymTab.InvalidType;
|
|
|
|
|
- 3274 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3275 END; .)
|
|
|
|
|
- 3276 | ( "MIN" (. isMax := FALSE; .)
|
|
|
|
|
- 3277 | "MAX" (. isMax := TRUE; .) )
|
|
|
|
|
- 3278 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 3279 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3280 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
|
|
- 3281 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
|
|
- 3282 ELSE AST.SetChild(astNode, 0,
|
|
|
|
|
- 3283 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
|
|
|
|
+ 3249 ELSE SemError(230);
|
|
|
|
|
+ 3250 t := SymTab.InvalidType;
|
|
|
|
|
+ 3251 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3252 END; .)
|
|
|
|
|
+ 3253 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 3254 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3255 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
|
|
+ 3256 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3257 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3258 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3259 t := SymTab.InvalidType;
|
|
|
|
|
+ 3260 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3261 ELSE
|
|
|
|
|
+ 3262 IF sfx THEN
|
|
|
|
|
+ 3263 QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 3264 ELSIF (dk = SymTab.KindVar)
|
|
|
|
|
+ 3265 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
+ 3266 QbeGen.AddrOf(qn, q)
|
|
|
|
|
+ 3267 ELSE SemError(230);
|
|
|
|
|
+ 3268 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3269 END;
|
|
|
|
|
+ 3270 t := SymTab.AddrType()
|
|
|
|
|
+ 3271 END; .)
|
|
|
|
|
+ 3272 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3273 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3274 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
|
|
+ 3275 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3276 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3277 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3278 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 3279 SemError(211) END;
|
|
|
|
|
+ 3280 t := SymTab.CharType(); .)
|
|
|
|
|
+ 3281 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
+ 3282 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3283 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
3284 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
3284 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3285 astCur := astNode; astIsLit := TRUE;
|
|
|
|
|
- 3286 IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 3287 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
|
|
- 3288 (* REAL/LONGREAL: the
|
|
|
|
|
- 3289 implementation bounds *)
|
|
|
|
|
- 3290 IF isMax THEN
|
|
|
|
|
- 3291 QbeGen.NormReal(
|
|
|
|
|
- 3292 "3.402823e38", q)
|
|
|
|
|
- 3293 ELSE QbeGen.NormReal(
|
|
|
|
|
- 3294 "-3.402823e38", q)
|
|
|
|
|
- 3295 END;
|
|
|
|
|
- 3296 t := SymTab.RealType()
|
|
|
|
|
- 3297 ELSIF (dt #
|
|
|
|
|
- 3298 SymTab.InvalidType)
|
|
|
|
|
- 3299 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
- 3300 SymTab.ClLong) THEN
|
|
|
|
|
- 3301 IF isMax THEN
|
|
|
|
|
- 3302 QbeGen.CopyOp(
|
|
|
|
|
- 3303 "9223372036854775807", q)
|
|
|
|
|
- 3304 ELSE QbeGen.CopyOp(
|
|
|
|
|
- 3305 "-9223372036854775808", q)
|
|
|
|
|
- 3306 END;
|
|
|
|
|
- 3307 t := SymTab.LongType()
|
|
|
|
|
- 3308 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
|
|
- 3309 hi) THEN
|
|
|
|
|
- 3310 IF isMax THEN
|
|
|
|
|
- 3311 QbeGen.IntStr(hi, q)
|
|
|
|
|
- 3312 ELSE QbeGen.IntStr(lo, q)
|
|
|
|
|
- 3313 END;
|
|
|
|
|
- 3314 t := SymTab.IntType()
|
|
|
|
|
- 3315 ELSE SemError(230);
|
|
|
|
|
- 3316 t := SymTab.InvalidType;
|
|
|
|
|
- 3317 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3318 END; .)
|
|
|
|
|
- 3319 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
|
|
+ 3285 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3286 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
+ 3287 IF (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3288 SymTab.ClChar)
|
|
|
|
|
+ 3289 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3290 SymTab.ClBool)
|
|
|
|
|
+ 3291 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3292 SymTab.ClEnum)
|
|
|
|
|
+ 3293 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 3294 SemError(211) END
|
|
|
|
|
+ 3295 END;
|
|
|
|
|
+ 3296 t := SymTab.IntType(); .)
|
|
|
|
|
+ 3297 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3298 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3299 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
|
|
+ 3300 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3301 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3302 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
+ 3303 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3304 t := SymTab.CharType(); .)
|
|
|
|
|
+ 3305 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3306 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3307 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
|
|
+ 3308 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3309 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3310 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
+ 3311 CHAR -> UCHAR (identity);
|
|
|
|
|
+ 3312 INTEGER familly -> UCHAR
|
|
|
|
|
+ 3313 (codepoint value). *)
|
|
|
|
|
+ 3314 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3315 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
+ 3316 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 3317 SemError(211) END;
|
|
|
|
|
+ 3318 t := SymTab.UCharType(); .)
|
|
|
|
|
+ 3319 | "CHR8" "(" Expr<et, q> ")"
|
|
|
3320 (. astNode := AST.MakeNode(AST.NkCall);
|
|
3320 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3321 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
|
|
|
|
+ 3321 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
3322 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
3322 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
3323 astCur := astNode; astIsLit := TRUE; .)
|
|
3323 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3324 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 3325 t := SymTab.InvalidType;
|
|
|
|
|
- 3326 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3327 ELSE
|
|
|
|
|
- 3328 IF sfx THEN
|
|
|
|
|
- 3329 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 3330 ELSIF (dk = SymTab.KindVar)
|
|
|
|
|
- 3331 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
- 3332 QbeGen.AddrOf(qn, q)
|
|
|
|
|
- 3333 ELSE SemError(230);
|
|
|
|
|
- 3334 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3335 END;
|
|
|
|
|
- 3336 t := SymTab.AddrType()
|
|
|
|
|
- 3337 END; .)
|
|
|
|
|
- 3338 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 3339 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3340 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
|
|
- 3341 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3342 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3343 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3344 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 3345 SemError(211) END;
|
|
|
|
|
- 3346 t := SymTab.CharType(); .)
|
|
|
|
|
- 3347 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
- 3348 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3349 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
|
|
- 3350 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3351 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3352 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
- 3353 IF (SymTab.ClassOf(et) #
|
|
|
|
|
- 3354 SymTab.ClChar)
|
|
|
|
|
- 3355 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 3356 SymTab.ClBool)
|
|
|
|
|
- 3357 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 3358 SymTab.ClEnum)
|
|
|
|
|
- 3359 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 3360 SemError(211) END
|
|
|
|
|
- 3361 END;
|
|
|
|
|
- 3362 t := SymTab.IntType(); .)
|
|
|
|
|
- 3363 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
- 3364 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3365 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
|
|
- 3366 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3367 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3368 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
- 3369 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3370 t := SymTab.CharType(); .)
|
|
|
|
|
- 3371 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 3372 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3373 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
|
|
- 3374 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3375 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3376 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
- 3377 CHAR -> UCHAR (identity);
|
|
|
|
|
- 3378 INTEGER familly -> UCHAR
|
|
|
|
|
- 3379 (codepoint value). *)
|
|
|
|
|
- 3380 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3381 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
- 3382 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 3383 SemError(211) END;
|
|
|
|
|
- 3384 t := SymTab.UCharType(); .)
|
|
|
|
|
- 3385 | "CHR8" "(" Expr<et, q> ")"
|
|
|
|
|
- 3386 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3387 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
|
|
- 3388 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3389 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3390 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3391 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 3392 SemError(211) END;
|
|
|
|
|
- 3393 QbeGen.WidenLong(q, qa);
|
|
|
|
|
- 3394 QbeGen.CheckRange(qa, "0", "255");
|
|
|
|
|
- 3395 t := SymTab.CharType(); .)
|
|
|
|
|
- 3396 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
- 3397 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3398 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
|
|
- 3399 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3400 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3401 (. (* UORD(u): the codepoint as a
|
|
|
|
|
- 3402 32-bit ordinal (INTEGER),
|
|
|
|
|
- 3403 cf. ORD for CHAR. *)
|
|
|
|
|
- 3404 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3405 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 3406 SemError(211) END;
|
|
|
|
|
- 3407 t := SymTab.IntType(); .)
|
|
|
|
|
- 3408 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
- 3409 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3410 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
|
|
- 3411 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
- 3412 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3413 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 3414 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
- 3415 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 3416 SymTab.ClReal) THEN
|
|
|
|
|
- 3417 SemError(211)
|
|
|
|
|
- 3418 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
- 3419 SymTab.ClassOf(et) =
|
|
|
|
|
- 3420 SymTab.ClReal);
|
|
|
|
|
- 3421 QbeGen.CopyOp(qa, q)
|
|
|
|
|
- 3422 END;
|
|
|
|
|
- 3423 t := et; .)
|
|
|
|
|
- 3424 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
|
|
- 3425 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
- 3426 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
|
|
- 3427 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
- 3428 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
- 3429 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
- 3430 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
- 3431 SemError(201);
|
|
|
|
|
- 3432 t := SymTab.InvalidType
|
|
|
|
|
- 3433 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
- 3434 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3435 t := SymTab.InvalidType
|
|
|
|
|
- 3436 ELSIF et =
|
|
|
|
|
- 3437 SymTab.InvalidType THEN
|
|
|
|
|
- 3438 t := vt
|
|
|
|
|
- 3439 ELSE
|
|
|
|
|
- 3440 c1 := SymTab.ClassOf(et);
|
|
|
|
|
- 3441 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
- 3442 IF (c1 = SymTab.ClInt)
|
|
|
|
|
- 3443 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
- 3444 QbeGen.WidenLong(q, qa);
|
|
|
|
|
- 3445 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3446 t := vt
|
|
|
|
|
- 3447 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
- 3448 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
- 3449 QbeGen.NarrowLong(q, qa);
|
|
|
|
|
- 3450 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3451 t := vt
|
|
|
|
|
- 3452 ELSIF (c1 = SymTab.ClInt)
|
|
|
|
|
- 3453 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3454 QbeGen.ConvIR(q, qa);
|
|
|
|
|
- 3455 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3456 t := vt
|
|
|
|
|
- 3457 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
- 3458 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3459 QbeGen.ConvLR(q, qa);
|
|
|
|
|
- 3460 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3461 t := vt
|
|
|
|
|
- 3462 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3463 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
- 3464 QbeGen.ConvRI(q, qa);
|
|
|
|
|
- 3465 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3466 t := vt
|
|
|
|
|
- 3467 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3468 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
- 3469 QbeGen.ConvRL(q, qa);
|
|
|
|
|
- 3470 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3471 t := vt
|
|
|
|
|
- 3472 ELSIF ((c1 = SymTab.ClInt)
|
|
|
|
|
- 3473 OR (c1 =
|
|
|
|
|
- 3474 SymTab.ClChar)
|
|
|
|
|
- 3475 OR (c1 =
|
|
|
|
|
- 3476 SymTab.ClBool)
|
|
|
|
|
- 3477 OR (c1 =
|
|
|
|
|
- 3478 SymTab.ClEnum))
|
|
|
|
|
- 3479 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
- 3480 OR (c2 =
|
|
|
|
|
- 3481 SymTab.ClChar)
|
|
|
|
|
- 3482 OR (c2 =
|
|
|
|
|
- 3483 SymTab.ClBool)
|
|
|
|
|
- 3484 OR (c2 =
|
|
|
|
|
- 3485 SymTab.ClEnum)) THEN
|
|
|
|
|
- 3486 t := vt
|
|
|
|
|
- 3487 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
- 3488 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
- 3489 t := vt
|
|
|
|
|
- 3490 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3491 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3492 t := vt
|
|
|
|
|
- 3493 ELSE SemError(230);
|
|
|
|
|
- 3494 t := SymTab.InvalidType
|
|
|
|
|
- 3495 END
|
|
|
|
|
- 3496 END
|
|
|
|
|
- 3497 END; .)
|
|
|
|
|
- 3498 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
|
|
- 3499 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
|
|
- 3500 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
- 3501 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
|
|
- 3502 IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 3503 t := SymTab.BoolType()
|
|
|
|
|
- 3504 ELSE SemError(212);
|
|
|
|
|
- 3505 t := SymTab.InvalidType END;
|
|
|
|
|
- 3506 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 3507 QbeGen.NotQ(q2, q)
|
|
|
|
|
- 3508 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3509 END;
|
|
|
|
|
- 3510 astIsLit := TRUE;
|
|
|
|
|
- 3511 astCur := AST.MakeUn(
|
|
|
|
|
- 3512 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
|
|
- 3513 )
|
|
|
|
|
- 3514 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
|
|
- 3515 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
- 3516 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
- 3517 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
- 3518 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 3519 (. VAR astNode: AST.Node; .)
|
|
|
|
|
- 3520 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
- 3521 SymTab.NewSubR(0, 255));
|
|
|
|
|
- 3522 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
|
|
- 3523 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
- 3524 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
- 3525 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
|
|
- 3526 "}" (. astCur := astNode; .) .
|
|
|
|
|
- 3527 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
|
|
- 3528 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
|
|
- 3529 declared type sets the width (set) or element type (array). *)
|
|
|
|
|
- 3530 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 3531 (. VAR nw: CARDINAL;
|
|
|
|
|
- 3532 astNode, astTail: AST.Node;
|
|
|
|
|
- 3533 savedCls: INTEGER; .)
|
|
|
|
|
- 3534 = "{" (. savedCls := braceCls;
|
|
|
|
|
- 3535 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
|
|
- 3536 AST.SetTy(astNode, vt);
|
|
|
|
|
- 3537 astTail := astNode;
|
|
|
|
|
- 3538 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3539 braceCls := -1
|
|
|
|
|
- 3540 ELSE braceCls :=
|
|
|
|
|
- 3541 SymTab.ClassOf(vt)
|
|
|
|
|
- 3542 END;
|
|
|
|
|
- 3543 IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
- 3544 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3545 nw := 8
|
|
|
|
|
- 3546 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
- 3547 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
- 3548 END;
|
|
|
|
|
- 3549 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
- 3550 QbeGen.SetZero(q, nw)
|
|
|
|
|
- 3551 ELSIF (braceCls =
|
|
|
|
|
- 3552 SymTab.ClArray)
|
|
|
|
|
- 3553 OR (braceCls =
|
|
|
|
|
- 3554 SymTab.ClRecord)
|
|
|
|
|
- 3555 OR (braceCls =
|
|
|
|
|
- 3556 SymTab.ClClass) THEN
|
|
|
|
|
- 3557 QbeGen.CtorBegin(vt)
|
|
|
|
|
- 3558 ELSE
|
|
|
|
|
- 3559 IF vt # SymTab.InvalidType THEN
|
|
|
|
|
- 3560 SemError(230) END;
|
|
|
|
|
- 3561 braceCls := -1
|
|
|
|
|
- 3562 END; .)
|
|
|
|
|
- 3563 [ BraceElem<vt, q, astNode, astTail>
|
|
|
|
|
- 3564 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
|
|
- 3565 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
|
|
- 3566 OR (braceCls =
|
|
|
|
|
- 3567 SymTab.ClRecord)
|
|
|
|
|
- 3568 OR (braceCls =
|
|
|
|
|
- 3569 SymTab.ClClass) THEN
|
|
|
|
|
- 3570 QbeGen.CtorEnd(q)
|
|
|
|
|
- 3571 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
|
|
- 3572 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3573 END;
|
|
|
|
|
- 3574 braceCls := savedCls; .)
|
|
|
|
|
- 3575 (. astCur := astNode; .) .
|
|
|
|
|
- 3576 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
|
|
- 3577 VAR node, tail: AST.Node>
|
|
|
|
|
- 3578 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 3579 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 3580 v, v2, reps, k: INTEGER;
|
|
|
|
|
- 3581 elem: SymTab.TypeIndex;
|
|
|
|
|
- 3582 lo: INTEGER;
|
|
|
|
|
- 3583 span: CARDINAL;
|
|
|
|
|
- 3584 cl, cl2: INTEGER;
|
|
|
|
|
- 3585 hasR, hasB: BOOLEAN;
|
|
|
|
|
- 3586 astEl: AST.Node; .)
|
|
|
|
|
- 3587 = (. hasR := FALSE; hasB := FALSE;
|
|
|
|
|
- 3588 reps := 1; .)
|
|
|
|
|
- 3589 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
- 3590 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
- 3591 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
- 3592 hasR := TRUE; .) ]
|
|
|
|
|
- 3593 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
|
|
- 3594 (. IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
- 3595 IF hasB THEN SemError(230) END;
|
|
|
|
|
- 3596 lo := SymTab.SetBaseLo(vt);
|
|
|
|
|
- 3597 span := SymTab.SetCount(vt);
|
|
|
|
|
- 3598 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 3599 OR (hasR AND (et2 =
|
|
|
|
|
- 3600 SymTab.InvalidType)) THEN
|
|
|
|
|
- 3601 ELSE cl :=
|
|
|
|
|
- 3602 SymTab.ClassOf(et);
|
|
|
|
|
- 3603 IF hasR THEN
|
|
|
|
|
- 3604 cl2 :=
|
|
|
|
|
- 3605 SymTab.ClassOf(et2)
|
|
|
|
|
- 3606 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 3607 END;
|
|
|
|
|
- 3608 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
- 3609 OR (hasR AND NOT
|
|
|
|
|
- 3610 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
- 3611 THEN
|
|
|
|
|
- 3612 SemError(222)
|
|
|
|
|
- 3613 ELSIF hasR
|
|
|
|
|
- 3614 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
- 3615 AND SymTab.ConstInt(q2,
|
|
|
|
|
- 3616 v2)
|
|
|
|
|
- 3617 AND ((v < lo)
|
|
|
|
|
- 3618 OR (v2 < lo)
|
|
|
|
|
- 3619 OR (v >= lo +
|
|
|
|
|
- 3620 VAL(INTEGER, span))
|
|
|
|
|
- 3621 OR (v2 >= lo +
|
|
|
|
|
- 3622 VAL(INTEGER, span))
|
|
|
|
|
- 3623 OR (v > v2)) THEN
|
|
|
|
|
- 3624 SemError(222)
|
|
|
|
|
- 3625 ELSIF hasR THEN
|
|
|
|
|
- 3626 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 3627 lo, span)
|
|
|
|
|
- 3628 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 3629 v)
|
|
|
|
|
- 3630 AND ((v < lo)
|
|
|
|
|
- 3631 OR (v >= lo +
|
|
|
|
|
- 3632 VAL(INTEGER,
|
|
|
|
|
- 3633 span))) THEN
|
|
|
|
|
- 3634 SemError(222)
|
|
|
|
|
- 3635 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 3636 lo, span)
|
|
|
|
|
- 3637 END
|
|
|
|
|
- 3638 END
|
|
|
|
|
- 3639 ELSIF (braceCls = SymTab.ClArray)
|
|
|
|
|
- 3640 OR (braceCls =
|
|
|
|
|
- 3641 SymTab.ClRecord)
|
|
|
|
|
- 3642 OR (braceCls =
|
|
|
|
|
- 3643 SymTab.ClClass) THEN
|
|
|
|
|
- 3644 IF hasR THEN SemError(230) END;
|
|
|
|
|
- 3645 reps := 1;
|
|
|
|
|
- 3646 IF hasB THEN
|
|
|
|
|
- 3647 IF SymTab.ConstInt(q2, v2)
|
|
|
|
|
- 3648 AND (v2 >= 1) THEN
|
|
|
|
|
- 3649 reps := v2
|
|
|
|
|
- 3650 ELSE SemError(230)
|
|
|
|
|
- 3651 END
|
|
|
|
|
- 3652 END;
|
|
|
|
|
- 3653 k := 0;
|
|
|
|
|
- 3654 WHILE k < reps DO
|
|
|
|
|
- 3655 QbeGen.CtorElem(qe);
|
|
|
|
|
- 3656 INC(k)
|
|
|
|
|
- 3657 END
|
|
|
|
|
- 3658 END; .)
|
|
|
|
|
- 3659 (. (* the BY form repeats the
|
|
|
|
|
- 3660 element; keep the AST in
|
|
|
|
|
- 3661 step with CtorElem *)
|
|
|
|
|
- 3662 k := 0;
|
|
|
|
|
- 3663 WHILE k < reps DO
|
|
|
|
|
- 3664 AstAppend(AST.NkBlock,
|
|
|
|
|
- 3665 node, tail, astEl);
|
|
|
|
|
- 3666 INC(k)
|
|
|
|
|
- 3667 END; .) .
|
|
|
|
|
- 3668 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 3669 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 3670 v, v2: INTEGER;
|
|
|
|
|
- 3671 lo: INTEGER;
|
|
|
|
|
- 3672 span: CARDINAL;
|
|
|
|
|
- 3673 cl, cl2: INTEGER;
|
|
|
|
|
- 3674 hasR: BOOLEAN;
|
|
|
|
|
- 3675 astEl: AST.Node; .)
|
|
|
|
|
- 3676 = (. hasR := FALSE; .)
|
|
|
|
|
- 3677 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
- 3678 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
- 3679 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
- 3680 hasR := TRUE; .) ]
|
|
|
|
|
- 3681 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
- 3682 span := SymTab.SetCount(st);
|
|
|
|
|
- 3683 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 3684 OR (hasR AND (et2 =
|
|
|
|
|
- 3685 SymTab.InvalidType)) THEN
|
|
|
|
|
- 3686 ELSE cl :=
|
|
|
|
|
- 3687 SymTab.ClassOf(et);
|
|
|
|
|
- 3688 IF hasR THEN
|
|
|
|
|
- 3689 cl2 :=
|
|
|
|
|
- 3690 SymTab.ClassOf(et2)
|
|
|
|
|
- 3691 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 3692 END;
|
|
|
|
|
- 3693 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
- 3694 OR (hasR AND NOT
|
|
|
|
|
- 3695 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
- 3696 THEN
|
|
|
|
|
- 3697 SemError(222)
|
|
|
|
|
- 3698 ELSIF hasR
|
|
|
|
|
- 3699 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
- 3700 AND SymTab.ConstInt(q2,
|
|
|
|
|
- 3701 v2)
|
|
|
|
|
- 3702 AND ((v < lo)
|
|
|
|
|
- 3703 OR (v2 < lo)
|
|
|
|
|
- 3704 OR (v >= lo +
|
|
|
|
|
- 3705 VAL(INTEGER, span))
|
|
|
|
|
- 3706 OR (v2 >= lo +
|
|
|
|
|
- 3707 VAL(INTEGER, span))
|
|
|
|
|
- 3708 OR (v > v2)) THEN
|
|
|
|
|
- 3709 SemError(222)
|
|
|
|
|
- 3710 ELSIF hasR THEN
|
|
|
|
|
- 3711 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 3712 lo, span)
|
|
|
|
|
- 3713 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 3714 v)
|
|
|
|
|
- 3715 AND ((v < lo)
|
|
|
|
|
- 3716 OR (v >= lo +
|
|
|
|
|
- 3717 VAL(INTEGER,
|
|
|
|
|
- 3718 span))) THEN
|
|
|
|
|
- 3719 SemError(222)
|
|
|
|
|
- 3720 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 3721 lo, span)
|
|
|
|
|
- 3722 END
|
|
|
|
|
- 3723 END; .)
|
|
|
|
|
- 3724 (. AST.SetChild(node,
|
|
|
|
|
- 3725 AST.NChild(node), astEl); .) .
|
|
|
|
|
- 3726 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
- 3727 = ident (. LexName(n); .) .
|
|
|
|
|
- 3728
|
|
|
|
|
- 3729 END M2.
|
|
|
|
|
|
|
+ 3324 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3325 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 3326 SemError(211) END;
|
|
|
|
|
+ 3327 QbeGen.WidenLong(q, qa);
|
|
|
|
|
+ 3328 QbeGen.CheckRange(qa, "0", "255");
|
|
|
|
|
+ 3329 t := SymTab.CharType(); .)
|
|
|
|
|
+ 3330 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3331 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3332 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
|
|
+ 3333 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3334 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3335 (. (* UORD(u): the codepoint as a
|
|
|
|
|
+ 3336 32-bit ordinal (INTEGER),
|
|
|
|
|
+ 3337 cf. ORD for CHAR. *)
|
|
|
|
|
+ 3338 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3339 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 3340 SemError(211) END;
|
|
|
|
|
+ 3341 t := SymTab.IntType(); .)
|
|
|
|
|
+ 3342 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3343 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3344 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
|
|
+ 3345 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
|
|
+ 3346 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3347 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3348 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
+ 3349 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3350 SymTab.ClReal) THEN
|
|
|
|
|
+ 3351 SemError(211)
|
|
|
|
|
+ 3352 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
+ 3353 SymTab.ClassOf(et) =
|
|
|
|
|
+ 3354 SymTab.ClReal);
|
|
|
|
|
+ 3355 QbeGen.CopyOp(qa, q)
|
|
|
|
|
+ 3356 END;
|
|
|
|
|
+ 3357 t := et; .)
|
|
|
|
|
+ 3358 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
|
|
+ 3359 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 3360 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
|
|
+ 3361 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
|
|
+ 3362 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
|
|
+ 3363 astCur := astNode; astIsLit := TRUE; .)
|
|
|
|
|
+ 3364 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
+ 3365 SemError(201);
|
|
|
|
|
+ 3366 t := SymTab.InvalidType
|
|
|
|
|
+ 3367 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
+ 3368 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3369 t := SymTab.InvalidType
|
|
|
|
|
+ 3370 ELSIF et =
|
|
|
|
|
+ 3371 SymTab.InvalidType THEN
|
|
|
|
|
+ 3372 t := vt
|
|
|
|
|
+ 3373 ELSE
|
|
|
|
|
+ 3374 c1 := SymTab.ClassOf(et);
|
|
|
|
|
+ 3375 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
+ 3376 IF (c1 = SymTab.ClInt)
|
|
|
|
|
+ 3377 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
+ 3378 QbeGen.WidenLong(q, qa);
|
|
|
|
|
+ 3379 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3380 t := vt
|
|
|
|
|
+ 3381 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
+ 3382 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
+ 3383 QbeGen.NarrowLong(q, qa);
|
|
|
|
|
+ 3384 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3385 t := vt
|
|
|
|
|
+ 3386 ELSIF (c1 = SymTab.ClInt)
|
|
|
|
|
+ 3387 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3388 QbeGen.ConvIR(q, qa);
|
|
|
|
|
+ 3389 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3390 t := vt
|
|
|
|
|
+ 3391 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
+ 3392 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3393 QbeGen.ConvLR(q, qa);
|
|
|
|
|
+ 3394 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3395 t := vt
|
|
|
|
|
+ 3396 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3397 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
+ 3398 QbeGen.ConvRI(q, qa);
|
|
|
|
|
+ 3399 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3400 t := vt
|
|
|
|
|
+ 3401 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3402 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
+ 3403 QbeGen.ConvRL(q, qa);
|
|
|
|
|
+ 3404 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3405 t := vt
|
|
|
|
|
+ 3406 ELSIF ((c1 = SymTab.ClInt)
|
|
|
|
|
+ 3407 OR (c1 =
|
|
|
|
|
+ 3408 SymTab.ClChar)
|
|
|
|
|
+ 3409 OR (c1 =
|
|
|
|
|
+ 3410 SymTab.ClBool)
|
|
|
|
|
+ 3411 OR (c1 =
|
|
|
|
|
+ 3412 SymTab.ClEnum))
|
|
|
|
|
+ 3413 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
+ 3414 OR (c2 =
|
|
|
|
|
+ 3415 SymTab.ClChar)
|
|
|
|
|
+ 3416 OR (c2 =
|
|
|
|
|
+ 3417 SymTab.ClBool)
|
|
|
|
|
+ 3418 OR (c2 =
|
|
|
|
|
+ 3419 SymTab.ClEnum)) THEN
|
|
|
|
|
+ 3420 t := vt
|
|
|
|
|
+ 3421 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
+ 3422 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
+ 3423 t := vt
|
|
|
|
|
+ 3424 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3425 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3426 t := vt
|
|
|
|
|
+ 3427 ELSE SemError(230);
|
|
|
|
|
+ 3428 t := SymTab.InvalidType
|
|
|
|
|
+ 3429 END
|
|
|
|
|
+ 3430 END
|
|
|
|
|
+ 3431 END; .)
|
|
|
|
|
+ 3432 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
|
|
+ 3433 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
|
|
+ 3434 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
+ 3435 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
|
|
+ 3436 IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 3437 t := SymTab.BoolType()
|
|
|
|
|
+ 3438 ELSE SemError(212);
|
|
|
|
|
+ 3439 t := SymTab.InvalidType END;
|
|
|
|
|
+ 3440 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 3441 QbeGen.NotQ(q2, q)
|
|
|
|
|
+ 3442 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3443 END;
|
|
|
|
|
+ 3444 astIsLit := TRUE;
|
|
|
|
|
+ 3445 astCur := AST.MakeUn(
|
|
|
|
|
+ 3446 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
|
|
+ 3447 )
|
|
|
|
|
+ 3448 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
|
|
+ 3449 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
+ 3450 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
+ 3451 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
+ 3452 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 3453 (. VAR astNode: AST.Node; .)
|
|
|
|
|
+ 3454 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
+ 3455 SymTab.NewSubR(0, 255));
|
|
|
|
|
+ 3456 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
|
|
+ 3457 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
+ 3458 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
+ 3459 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
|
|
+ 3460 "}" (. astCur := astNode; .) .
|
|
|
|
|
+ 3461 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
|
|
+ 3462 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
|
|
+ 3463 declared type sets the width (set) or element type (array). *)
|
|
|
|
|
+ 3464 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 3465 (. VAR nw: CARDINAL;
|
|
|
|
|
+ 3466 astNode, astTail: AST.Node;
|
|
|
|
|
+ 3467 savedCls: INTEGER; .)
|
|
|
|
|
+ 3468 = "{" (. savedCls := braceCls;
|
|
|
|
|
+ 3469 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
|
|
+ 3470 AST.SetTy(astNode, vt);
|
|
|
|
|
+ 3471 astTail := astNode;
|
|
|
|
|
+ 3472 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3473 braceCls := -1
|
|
|
|
|
+ 3474 ELSE braceCls :=
|
|
|
|
|
+ 3475 SymTab.ClassOf(vt)
|
|
|
|
|
+ 3476 END;
|
|
|
|
|
+ 3477 IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
+ 3478 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3479 nw := 8
|
|
|
|
|
+ 3480 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
+ 3481 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
+ 3482 END;
|
|
|
|
|
+ 3483 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
+ 3484 QbeGen.SetZero(q, nw)
|
|
|
|
|
+ 3485 ELSIF (braceCls =
|
|
|
|
|
+ 3486 SymTab.ClArray)
|
|
|
|
|
+ 3487 OR (braceCls =
|
|
|
|
|
+ 3488 SymTab.ClRecord)
|
|
|
|
|
+ 3489 OR (braceCls =
|
|
|
|
|
+ 3490 SymTab.ClClass) THEN
|
|
|
|
|
+ 3491 QbeGen.CtorBegin(vt)
|
|
|
|
|
+ 3492 ELSE
|
|
|
|
|
+ 3493 IF vt # SymTab.InvalidType THEN
|
|
|
|
|
+ 3494 SemError(230) END;
|
|
|
|
|
+ 3495 braceCls := -1
|
|
|
|
|
+ 3496 END; .)
|
|
|
|
|
+ 3497 [ BraceElem<vt, q, astNode, astTail>
|
|
|
|
|
+ 3498 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
|
|
+ 3499 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
|
|
+ 3500 OR (braceCls =
|
|
|
|
|
+ 3501 SymTab.ClRecord)
|
|
|
|
|
+ 3502 OR (braceCls =
|
|
|
|
|
+ 3503 SymTab.ClClass) THEN
|
|
|
|
|
+ 3504 QbeGen.CtorEnd(q)
|
|
|
|
|
+ 3505 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
|
|
+ 3506 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3507 END;
|
|
|
|
|
+ 3508 braceCls := savedCls; .)
|
|
|
|
|
+ 3509 (. astCur := astNode; .) .
|
|
|
|
|
+ 3510 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
|
|
+ 3511 VAR node, tail: AST.Node>
|
|
|
|
|
+ 3512 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 3513 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 3514 v, v2, reps, k: INTEGER;
|
|
|
|
|
+ 3515 elem: SymTab.TypeIndex;
|
|
|
|
|
+ 3516 lo: INTEGER;
|
|
|
|
|
+ 3517 span: CARDINAL;
|
|
|
|
|
+ 3518 cl, cl2: INTEGER;
|
|
|
|
|
+ 3519 hasR, hasB: BOOLEAN;
|
|
|
|
|
+ 3520 astEl: AST.Node; .)
|
|
|
|
|
+ 3521 = (. hasR := FALSE; hasB := FALSE;
|
|
|
|
|
+ 3522 reps := 1; .)
|
|
|
|
|
+ 3523 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
+ 3524 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
+ 3525 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
+ 3526 hasR := TRUE; .) ]
|
|
|
|
|
+ 3527 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
|
|
+ 3528 (. IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
+ 3529 IF hasB THEN SemError(230) END;
|
|
|
|
|
+ 3530 lo := SymTab.SetBaseLo(vt);
|
|
|
|
|
+ 3531 span := SymTab.SetCount(vt);
|
|
|
|
|
+ 3532 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 3533 OR (hasR AND (et2 =
|
|
|
|
|
+ 3534 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 3535 ELSE cl :=
|
|
|
|
|
+ 3536 SymTab.ClassOf(et);
|
|
|
|
|
+ 3537 IF hasR THEN
|
|
|
|
|
+ 3538 cl2 :=
|
|
|
|
|
+ 3539 SymTab.ClassOf(et2)
|
|
|
|
|
+ 3540 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 3541 END;
|
|
|
|
|
+ 3542 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
+ 3543 OR (hasR AND NOT
|
|
|
|
|
+ 3544 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
+ 3545 THEN
|
|
|
|
|
+ 3546 SemError(222)
|
|
|
|
|
+ 3547 ELSIF hasR
|
|
|
|
|
+ 3548 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 3549 AND SymTab.ConstInt(q2,
|
|
|
|
|
+ 3550 v2)
|
|
|
|
|
+ 3551 AND ((v < lo)
|
|
|
|
|
+ 3552 OR (v2 < lo)
|
|
|
|
|
+ 3553 OR (v >= lo +
|
|
|
|
|
+ 3554 VAL(INTEGER, span))
|
|
|
|
|
+ 3555 OR (v2 >= lo +
|
|
|
|
|
+ 3556 VAL(INTEGER, span))
|
|
|
|
|
+ 3557 OR (v > v2)) THEN
|
|
|
|
|
+ 3558 SemError(222)
|
|
|
|
|
+ 3559 ELSIF hasR THEN
|
|
|
|
|
+ 3560 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 3561 lo, span)
|
|
|
|
|
+ 3562 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 3563 v)
|
|
|
|
|
+ 3564 AND ((v < lo)
|
|
|
|
|
+ 3565 OR (v >= lo +
|
|
|
|
|
+ 3566 VAL(INTEGER,
|
|
|
|
|
+ 3567 span))) THEN
|
|
|
|
|
+ 3568 SemError(222)
|
|
|
|
|
+ 3569 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 3570 lo, span)
|
|
|
|
|
+ 3571 END
|
|
|
|
|
+ 3572 END
|
|
|
|
|
+ 3573 ELSIF (braceCls = SymTab.ClArray)
|
|
|
|
|
+ 3574 OR (braceCls =
|
|
|
|
|
+ 3575 SymTab.ClRecord)
|
|
|
|
|
+ 3576 OR (braceCls =
|
|
|
|
|
+ 3577 SymTab.ClClass) THEN
|
|
|
|
|
+ 3578 IF hasR THEN SemError(230) END;
|
|
|
|
|
+ 3579 reps := 1;
|
|
|
|
|
+ 3580 IF hasB THEN
|
|
|
|
|
+ 3581 IF SymTab.ConstInt(q2, v2)
|
|
|
|
|
+ 3582 AND (v2 >= 1) THEN
|
|
|
|
|
+ 3583 reps := v2
|
|
|
|
|
+ 3584 ELSE SemError(230)
|
|
|
|
|
+ 3585 END
|
|
|
|
|
+ 3586 END;
|
|
|
|
|
+ 3587 k := 0;
|
|
|
|
|
+ 3588 WHILE k < reps DO
|
|
|
|
|
+ 3589 QbeGen.CtorElem(qe);
|
|
|
|
|
+ 3590 INC(k)
|
|
|
|
|
+ 3591 END
|
|
|
|
|
+ 3592 END; .)
|
|
|
|
|
+ 3593 (. (* the BY form repeats the
|
|
|
|
|
+ 3594 element; keep the AST in
|
|
|
|
|
+ 3595 step with CtorElem *)
|
|
|
|
|
+ 3596 k := 0;
|
|
|
|
|
+ 3597 WHILE k < reps DO
|
|
|
|
|
+ 3598 AstAppend(AST.NkBlock,
|
|
|
|
|
+ 3599 node, tail, astEl);
|
|
|
|
|
+ 3600 INC(k)
|
|
|
|
|
+ 3601 END; .) .
|
|
|
|
|
+ 3602 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 3603 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 3604 v, v2: INTEGER;
|
|
|
|
|
+ 3605 lo: INTEGER;
|
|
|
|
|
+ 3606 span: CARDINAL;
|
|
|
|
|
+ 3607 cl, cl2: INTEGER;
|
|
|
|
|
+ 3608 hasR: BOOLEAN;
|
|
|
|
|
+ 3609 astEl: AST.Node; .)
|
|
|
|
|
+ 3610 = (. hasR := FALSE; .)
|
|
|
|
|
+ 3611 Expr<et, qe> (. astEl := astCur; .)
|
|
|
|
|
+ 3612 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
|
|
+ 3613 AST.NkSubrange, 0, astEl, astCur);
|
|
|
|
|
+ 3614 hasR := TRUE; .) ]
|
|
|
|
|
+ 3615 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
+ 3616 span := SymTab.SetCount(st);
|
|
|
|
|
+ 3617 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 3618 OR (hasR AND (et2 =
|
|
|
|
|
+ 3619 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 3620 ELSE cl :=
|
|
|
|
|
+ 3621 SymTab.ClassOf(et);
|
|
|
|
|
+ 3622 IF hasR THEN
|
|
|
|
|
+ 3623 cl2 :=
|
|
|
|
|
+ 3624 SymTab.ClassOf(et2)
|
|
|
|
|
+ 3625 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 3626 END;
|
|
|
|
|
+ 3627 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
+ 3628 OR (hasR AND NOT
|
|
|
|
|
+ 3629 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
+ 3630 THEN
|
|
|
|
|
+ 3631 SemError(222)
|
|
|
|
|
+ 3632 ELSIF hasR
|
|
|
|
|
+ 3633 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 3634 AND SymTab.ConstInt(q2,
|
|
|
|
|
+ 3635 v2)
|
|
|
|
|
+ 3636 AND ((v < lo)
|
|
|
|
|
+ 3637 OR (v2 < lo)
|
|
|
|
|
+ 3638 OR (v >= lo +
|
|
|
|
|
+ 3639 VAL(INTEGER, span))
|
|
|
|
|
+ 3640 OR (v2 >= lo +
|
|
|
|
|
+ 3641 VAL(INTEGER, span))
|
|
|
|
|
+ 3642 OR (v > v2)) THEN
|
|
|
|
|
+ 3643 SemError(222)
|
|
|
|
|
+ 3644 ELSIF hasR THEN
|
|
|
|
|
+ 3645 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 3646 lo, span)
|
|
|
|
|
+ 3647 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 3648 v)
|
|
|
|
|
+ 3649 AND ((v < lo)
|
|
|
|
|
+ 3650 OR (v >= lo +
|
|
|
|
|
+ 3651 VAL(INTEGER,
|
|
|
|
|
+ 3652 span))) THEN
|
|
|
|
|
+ 3653 SemError(222)
|
|
|
|
|
+ 3654 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 3655 lo, span)
|
|
|
|
|
+ 3656 END
|
|
|
|
|
+ 3657 END; .)
|
|
|
|
|
+ 3658 (. AST.SetChild(node,
|
|
|
|
|
+ 3659 AST.NChild(node), astEl); .) .
|
|
|
|
|
+ 3660 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
+ 3661 = ident (. LexName(n); .) .
|
|
|
|
|
+ 3662
|
|
|
|
|
+ 3663 END M2.
|
|
|
|
|
|
|
|
0 errors
|
|
0 errors
|
|
|
|
|
|