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