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