Forráskód Böngészése

lower L7: decouple Fact's runtime builtins and calls

Drop the emitter from Fact's always-runtime branches: ResultComp's
ElemLoad, the bare zero-arg call (Mangled/CallBegin/CallEnd),
ADR's AddrOf, SHIFT/ROTATE's SetShift, an open-array HIGH/LEN's
OpenHi/LoadCount, and CHR8's CheckRange.  Runtime results become "@";
the constant-producing builtins (fixed-array HIGH/LEN, SIZE/TSIZE,
MAX/MIN, ORD/CHR/VAL/...) keep their folding paths.

Suite 204/204; FIXPOINT OK (3,406,951 bytes).
Eric Streit 5 napja
szülő
commit
d469c78fb6
2 módosított fájl, 652 hozzáadás és 700 törlés
  1. 36 60
      compiler/src/M2.atg
  2. 616 640
      compiler/src/M2.lst

+ 36 - 60
compiler/src/M2.atg

@@ -2952,8 +2952,7 @@ PRODUCTIONS
   AND (SymTab.ClassOf(t) # SymTab.ClSet)
   AND (SymTab.ClassOf(t) # SymTab.ClSet)
   AND (SymTab.ClassOf(t) # SymTab.ClArray)
   AND (SymTab.ClassOf(t) # SymTab.ClArray)
   AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
   AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
-                                               QbeGen.ElemLoad(q, t, q2);
-                                               QbeGen.CopyOp(q2, q)
+                                                QbeGen.CopyOp("@", q)
                                              END
                                              END
                                            END; .) ]
                                            END; .) ]
                                         (. IF called THEN
                                         (. IF called THEN
@@ -2970,29 +2969,16 @@ PRODUCTIONS
                                                 omitted); a proper or
                                                 omitted); a proper or
                                                 parameterised proc here
                                                 parameterised proc here
                                                 is 230 *)
                                                 is 230 *)
-                                             IF (SymTab.ProcNPar(qn) = 0)
- AND (SymTab.ProcRes(qn) #
-                                                   SymTab.InvalidType) THEN
-                                               QbeGen.Mangled(qn,
-                                                 SymTab.ProcUid(qn), qm0);
-                                               QbeGen.CallBegin(qm0,
-                                                 SymTab.ProcRes(qn),
-                                                 SymTab.ProcDepthOf(qn),
-                                                 SymTab.IsExternal(qn));
-                                               QbeGen.CallEnd(TRUE, q);
-                                               astCur := AST.MakeNode(AST.NkCall);
-                                               AST.SetChild(astCur, 0, astD);
-                                               t := SymTab.ProcRes(qn)
-                                             ELSE
-                                               (* procedure used as a
-                                                  value (assign to a
-                                                  procedure variable):
-                                                  its code address *)
-                                               t := SymTab.ProcTypeOf(qn);
-                                               QbeGen.Mangled(qn,
-                                                 SymTab.ProcUid(qn), qm0);
-                                               QbeGen.ProcAddr(qm0, q)
-                                             END
+                                              IF (SymTab.ProcNPar(qn) = 0)
+ AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
+                                                t := SymTab.ProcRes(qn);
+                                                QbeGen.CopyOp("@", q);
+                                                astCur := AST.MakeNode(AST.NkCall);
+                                                AST.SetChild(astCur, 0, astD)
+                                              ELSE
+                                                t := SymTab.ProcTypeOf(qn);
+                                                QbeGen.CopyOp("@", q)
+                                              END
                                            END; .)
                                            END; .)
     | ( "HIGH"                          (. isHigh := TRUE; .)
     | ( "HIGH"                          (. isHigh := TRUE; .)
       | ( "LEN" | "LENGTH" )            (. isHigh := FALSE; .) )
       | ( "LEN" | "LENGTH" )            (. isHigh := FALSE; .) )
@@ -3084,25 +3070,22 @@ PRODUCTIONS
                                              t := SymTab.InvalidType;
                                              t := SymTab.InvalidType;
                                              QbeGen.CopyOp("0", q)
                                              QbeGen.CopyOp("0", q)
                                            ELSE
                                            ELSE
-                                             IF isHigh THEN
-                                               IF SymTab.IsOpenArray(dt) THEN
-                                                 QbeGen.OpenHi(qd, qr)
-                                               ELSE
-                                                 QbeGen.IntStr(
-                                                   SymTab.ArrayHi(dt), qr)
-                                               END
-                                             ELSE
-                                               IF SymTab.IsOpenArray(dt) THEN
-                                                 QbeGen.LoadCount(qd, qr)
-                                               ELSE
-                                                 QbeGen.IntStr(VAL(
-                                                   INTEGER,
-                                                   SymTab.ArrayLen(dt)),
-                                                   qr)
-                                               END
-                                             END;
-                                              t := SymTab.IntType();
-                                              QbeGen.CopyOp(qr, q)
+                                              IF SymTab.IsOpenArray(dt) THEN
+                                                t := SymTab.IntType();
+                                                QbeGen.CopyOp("@", q)
+                                              ELSE
+                                                IF isHigh THEN
+                                                  QbeGen.IntStr(
+                                                    SymTab.ArrayHi(dt), qr)
+                                                ELSE
+                                                  QbeGen.IntStr(VAL(
+                                                    INTEGER,
+                                                    SymTab.ArrayLen(dt)),
+                                                    qr)
+                                                END;
+                                                t := SymTab.IntType();
+                                                QbeGen.CopyOp(qr, q)
+                                              END
                                             END; .)
                                             END; .)
     | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
     | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
     (. astNode := AST.MakeNode(AST.NkCall);
     (. astNode := AST.MakeNode(AST.NkCall);
@@ -3133,12 +3116,8 @@ PRODUCTIONS
                                            IF (et # SymTab.InvalidType)
                                            IF (et # SymTab.InvalidType)
                                               AND (SymTab.ClassOf(et) =
                                               AND (SymTab.ClassOf(et) =
                                                  SymTab.ClSet) THEN
                                                  SymTab.ClSet) THEN
-                                             QbeGen.SetShift(q, q2,
-                                               SymTab.SetWords(et),
-                                               SymTab.SetCount(et), isMax,
-                                               qt);
-                                             t := et;
-                                             QbeGen.CopyOp(qt, q)
+                                              t := et;
+                                              QbeGen.CopyOp("@", q)
                                            ELSE SemError(230);
                                            ELSE SemError(230);
                                              t := SymTab.InvalidType;
                                              t := SymTab.InvalidType;
                                              QbeGen.CopyOp("0", q)
                                              QbeGen.CopyOp("0", q)
@@ -3195,14 +3174,13 @@ PRODUCTIONS
                                              t := SymTab.InvalidType;
                                              t := SymTab.InvalidType;
                                              QbeGen.CopyOp("0", q)
                                              QbeGen.CopyOp("0", q)
                                            ELSE
                                            ELSE
-                                             IF sfx THEN
-                                               QbeGen.CopyOp(qd, q)
-                                             ELSIF (dk = SymTab.KindVar)
-                                                OR (dk = SymTab.KindParam) THEN
-                                               QbeGen.AddrOf(qn, q)
-                                             ELSE SemError(230);
-                                               QbeGen.CopyOp("0", q)
-                                             END;
+                                              IF sfx
+                                                 OR (dk = SymTab.KindVar)
+                                                 OR (dk = SymTab.KindParam) THEN
+                                                QbeGen.CopyOp("@", q)
+                                              ELSE SemError(230);
+                                                QbeGen.CopyOp("0", q)
+                                              END;
                                              t := SymTab.AddrType()
                                              t := SymTab.AddrType()
                                            END; .)
                                            END; .)
     | "CHR" "(" Expr<et, q> ")"
     | "CHR" "(" Expr<et, q> ")"
@@ -3260,8 +3238,6 @@ PRODUCTIONS
                                         (. IF (et # SymTab.InvalidType)
                                         (. IF (et # SymTab.InvalidType)
   AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
   AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
                                              SemError(211) END;
                                              SemError(211) END;
-                                           QbeGen.WidenLong(q, qa);
-                                           QbeGen.CheckRange(qa, "0", "255");
                                            t := SymTab.CharType(); .)
                                            t := SymTab.CharType(); .)
     | "UORD" "(" Expr<et, q> ")"
     | "UORD" "(" Expr<et, q> ")"
     (. astNode := AST.MakeNode(AST.NkCall);
     (. astNode := AST.MakeNode(AST.NkCall);

+ 616 - 640
compiler/src/M2.lst

@@ -2970,651 +2970,627 @@ Listing:
  2952    AND (SymTab.ClassOf(t) # SymTab.ClSet)
  2952    AND (SymTab.ClassOf(t) # SymTab.ClSet)
  2953    AND (SymTab.ClassOf(t) # SymTab.ClArray)
  2953    AND (SymTab.ClassOf(t) # SymTab.ClArray)
  2954    AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
  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)
+ 2955                                                  QbeGen.CopyOp("@", q)
+ 2956                                               END
+ 2957                                             END; .) ]
+ 2958                                          (. IF called THEN
+ 2959                                               astCur := astRes
+ 2960                                             ELSIF astCall THEN
+ 2961                                               astCur := astBrace
+ 2962                                             ELSE astCur := astD
+ 2963                                             END;
+ 2964                                              astIsLit := TRUE;
+ 2965                                              IF NOT called
+ 2966   AND (dk = SymTab.KindProc) THEN
+ 2967                                               (* bare zero-arg function
+ 2968                                                  call (parentheses may be
+ 2969                                                  omitted); a proper or
+ 2970                                                  parameterised proc here
+ 2971                                                  is 230 *)
+ 2972                                                IF (SymTab.ProcNPar(qn) = 0)
+ 2973   AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
+ 2974                                                  t := SymTab.ProcRes(qn);
+ 2975                                                  QbeGen.CopyOp("@", q);
+ 2976                                                  astCur := AST.MakeNode(AST.NkCall);
+ 2977                                                  AST.SetChild(astCur, 0, astD)
+ 2978                                                ELSE
+ 2979                                                  t := SymTab.ProcTypeOf(qn);
+ 2980                                                  QbeGen.CopyOp("@", q)
+ 2981                                                END
+ 2982                                             END; .)
+ 2983      | ( "HIGH"                          (. isHigh := TRUE; .)
+ 2984        | ( "LEN" | "LENGTH" )            (. isHigh := FALSE; .) )
+ 2985        "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
+ 2986                                              isU := FALSE; .)
+ 2987            | string                       (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
+ 2988                                              isStr := TRUE;
+ 2989                                              isU := FALSE;
+ 2990                                              IF SymTab.StrLen(s) = 3 THEN
+ 2991                                                dt := SymTab.CharType();
+ 2992                                                QbeGen.IntStr(QbeGen.CharVal(s),
+ 2993                                                  qd)
+ 2994                                              ELSE
+ 2995                                                dt := SymTab.NewStr();
+ 2996                                                QbeGen.DeclStr(s, qd);
+ 2997                                                QbeGen.NoteAddr(qd, qd)
+ 2998                                              END;
+ 2999                                              dk := -1;
+ 3000                                              qn[0] := CHR(0); .)
+ 3001            | ustring                      (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
+ 3002                                              QbeGen.DeclUStr(s, qd, isU, ucp,
+ 3003                                                uok);
+ 3004                                              isStr := FALSE;
+ 3005                                              IF NOT uok THEN
+ 3006                                                SemError(234);
+ 3007                                                dt := SymTab.InvalidType
+ 3008                                              ELSIF isU THEN
+ 3009                                                (* one codepoint: a UCHAR;
+ 3010                                                   LEN is 1, HIGH is 0 *)
+ 3011                                                dt := SymTab.UCharType();
+ 3012                                                QbeGen.IntStr(ucp, qd)
+ 3013                                              ELSE
+ 3014                                                dt := SymTab.NewUStr();
+ 3015                                                QbeGen.NoteAddr(qd, qd)
+ 3016                                              END;
+ 3017                                              dk := -1;
+ 3018                                              qn[0] := CHR(0); .) )
+ 3019        ")"
+ 3020                                          (. astNode := AST.MakeNode(AST.NkCall);
+ 3021     IF isHigh THEN AST.SetChild(astNode, 0,
+ 3022       AST.MakeLeaf(AST.NkIdent, "HIGH"))
+ 3023     ELSE AST.SetChild(astNode, 0,
+ 3024       AST.MakeLeaf(AST.NkIdent, "LEN")) END;
+ 3025     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3026     astCur := astNode; astIsLit := TRUE;
+ 3027                                             IF (dt # SymTab.InvalidType)
+ 3028    AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
+ 3029                                               (* UString: the count is
+ 3030                                                  the descriptor header *)
+ 3031                                               IF isHigh THEN
+ 3032                                                 QbeGen.UStrLen(qd, qr);
+ 3033                                                 QbeGen.DecQ(qr)
+ 3034                                               ELSE
+ 3035                                                 QbeGen.UStrLen(qd, qr)
+ 3036                                               END;
+ 3037                                               t := SymTab.IntType();
+ 3038                                               QbeGen.CopyOp(qr, q)
+ 3039                                             ELSIF (dt # SymTab.InvalidType)
+ 3040    AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
+ 3041                                               (* single UCHAR codepoint *)
+ 3042                                               IF isHigh THEN
+ 3043                                                 QbeGen.CopyOp("0", qr)
+ 3044                                               ELSE
+ 3045                                                 QbeGen.CopyOp("1", qr)
+ 3046                                               END;
+ 3047                                               t := SymTab.IntType();
+ 3048                                               QbeGen.CopyOp(qr, q)
+ 3049                                             ELSIF isStr THEN
+ 3050                                               (* fold: content length at
+ 3051                                                  compile time *)
+ 3052                                               IF SymTab.StrLen(s) = 3 THEN
+ 3053                                                 c1 := 1
+ 3054                                               ELSE
+ 3055                                                 c1 :=
+ 3056                                                   SymTab.StrLen(s) - 2
+ 3057                                               END;
+ 3058                                               IF isHigh THEN
+ 3059                                                 DEC(c1)
  3060                                               END;
  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 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                                                 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                                             END;
- 3232                                             t := SymTab.IntType(); .)
- 3233      | "CAP" "(" Expr<et, q> ")"
+ 3061                                               QbeGen.IntStr(c1, qr);
+ 3062                                               t := SymTab.IntType();
+ 3063                                               QbeGen.CopyOp(qr, q)
+ 3064                                             ELSIF dt = SymTab.InvalidType THEN
+ 3065                                               t := SymTab.InvalidType;
+ 3066                                               QbeGen.CopyOp("0", q)
+ 3067                                             ELSIF SymTab.ClassOf(dt) #
+ 3068                                                   SymTab.ClArray THEN
+ 3069                                               SemError(217);
+ 3070                                               t := SymTab.InvalidType;
+ 3071                                               QbeGen.CopyOp("0", q)
+ 3072                                             ELSE
+ 3073                                                IF SymTab.IsOpenArray(dt) THEN
+ 3074                                                  t := SymTab.IntType();
+ 3075                                                  QbeGen.CopyOp("@", q)
+ 3076                                                ELSE
+ 3077                                                  IF isHigh THEN
+ 3078                                                    QbeGen.IntStr(
+ 3079                                                      SymTab.ArrayHi(dt), qr)
+ 3080                                                  ELSE
+ 3081                                                    QbeGen.IntStr(VAL(
+ 3082                                                      INTEGER,
+ 3083                                                      SymTab.ArrayLen(dt)),
+ 3084                                                      qr)
+ 3085                                                  END;
+ 3086                                                  t := SymTab.IntType();
+ 3087                                                  QbeGen.CopyOp(qr, q)
+ 3088                                                END
+ 3089                                              END; .)
+ 3090      | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
+ 3091      (. astNode := AST.MakeNode(AST.NkCall);
+ 3092     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
+ 3093     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3094     astCur := astNode; astIsLit := TRUE; .)
+ 3095                                          (. IF dt = SymTab.InvalidType THEN
+ 3096                                               t := SymTab.InvalidType;
+ 3097                                               QbeGen.CopyOp("0", q)
+ 3098                                             ELSE
+ 3099                                               QbeGen.IntStr(VAL(INTEGER,
+ 3100                                                 SymTab.ObjectSize(dt)), q);
+ 3101                                               t := SymTab.IntType()
+ 3102                                             END; .)
+ 3103      | ( "SHIFT"                         (. isMax := FALSE; .)
+ 3104        | "ROTATE"                        (. isMax := TRUE; .) )
+ 3105        "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
+ 3106                                          (. astNode := AST.MakeNode(AST.NkCall);
+ 3107     IF isMax THEN AST.SetChild(astNode, 0,
+ 3108       AST.MakeLeaf(AST.NkIdent, "ROTATE"))
+ 3109     ELSE AST.SetChild(astNode, 0,
+ 3110       AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
+ 3111     IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
+ 3112     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
+ 3113     astCur := astNode; astIsLit := TRUE;
+ 3114                                             (* set shift/rotate: isMax
+ 3115                                                doubles as "rotate" *)
+ 3116                                             IF (et # SymTab.InvalidType)
+ 3117                                                AND (SymTab.ClassOf(et) =
+ 3118                                                   SymTab.ClSet) THEN
+ 3119                                                t := et;
+ 3120                                                QbeGen.CopyOp("@", q)
+ 3121                                             ELSE SemError(230);
+ 3122                                               t := SymTab.InvalidType;
+ 3123                                               QbeGen.CopyOp("0", q)
+ 3124                                             END; .)
+ 3125      | ( "MIN"                           (. isMax := FALSE; .)
+ 3126        | "MAX"                           (. isMax := TRUE; .) )
+ 3127        "(" Design<dt, dk, qd, qn, sfx> ")"
+ 3128                                          (. astNode := AST.MakeNode(AST.NkCall);
+ 3129     IF isMax THEN AST.SetChild(astNode, 0,
+ 3130       AST.MakeLeaf(AST.NkIdent, "MAX"))
+ 3131     ELSE AST.SetChild(astNode, 0,
+ 3132       AST.MakeLeaf(AST.NkIdent, "MIN")) END;
+ 3133     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3134     astCur := astNode; astIsLit := TRUE;
+ 3135                                             IF (dt # SymTab.InvalidType)
+ 3136   AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
+ 3137                                               (* REAL/LONGREAL: the
+ 3138                                                  implementation bounds *)
+ 3139                                               IF isMax THEN
+ 3140                                                 QbeGen.NormReal(
+ 3141                                                   "3.402823e38", q)
+ 3142                                               ELSE QbeGen.NormReal(
+ 3143                                                   "-3.402823e38", q)
+ 3144                                               END;
+ 3145                                               t := SymTab.RealType()
+ 3146                                             ELSIF (dt #
+ 3147                                                SymTab.InvalidType)
+ 3148   AND (SymTab.ClassOf(dt) =
+ 3149                                                   SymTab.ClLong) THEN
+ 3150                                               IF isMax THEN
+ 3151                                                 QbeGen.CopyOp(
+ 3152                                                   "9223372036854775807", q)
+ 3153                                               ELSE QbeGen.CopyOp(
+ 3154                                                   "-9223372036854775808", q)
+ 3155                                               END;
+ 3156                                               t := SymTab.LongType()
+ 3157                                             ELSIF SymTab.TypeBounds(dt, lo,
+ 3158                                                      hi) THEN
+ 3159                                               IF isMax THEN
+ 3160                                                 QbeGen.IntStr(hi, q)
+ 3161                                               ELSE QbeGen.IntStr(lo, q)
+ 3162                                               END;
+ 3163                                               t := SymTab.IntType()
+ 3164                                             ELSE SemError(230);
+ 3165                                               t := SymTab.InvalidType;
+ 3166                                               QbeGen.CopyOp("0", q)
+ 3167                                             END; .)
+ 3168      | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
+ 3169      (. astNode := AST.MakeNode(AST.NkCall);
+ 3170     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
+ 3171     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3172     astCur := astNode; astIsLit := TRUE; .)
+ 3173                                          (. IF dt = SymTab.InvalidType THEN
+ 3174                                               t := SymTab.InvalidType;
+ 3175                                               QbeGen.CopyOp("0", q)
+ 3176                                             ELSE
+ 3177                                                IF sfx
+ 3178                                                   OR (dk = SymTab.KindVar)
+ 3179                                                   OR (dk = SymTab.KindParam) THEN
+ 3180                                                  QbeGen.CopyOp("@", q)
+ 3181                                                ELSE SemError(230);
+ 3182                                                  QbeGen.CopyOp("0", q)
+ 3183                                                END;
+ 3184                                               t := SymTab.AddrType()
+ 3185                                             END; .)
+ 3186      | "CHR" "(" Expr<et, q> ")"
+ 3187      (. astNode := AST.MakeNode(AST.NkCall);
+ 3188     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
+ 3189     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3190     astCur := astNode; astIsLit := TRUE; .)
+ 3191                                          (. IF (et # SymTab.InvalidType)
+ 3192   AND NOT SymTab.IsIntFamily(et) THEN
+ 3193                                               SemError(211) END;
+ 3194                                             t := SymTab.CharType(); .)
+ 3195      | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
+ 3196      (. astNode := AST.MakeNode(AST.NkCall);
+ 3197     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
+ 3198     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3199     astCur := astNode; astIsLit := TRUE; .)
+ 3200                                          (. IF et # SymTab.InvalidType THEN
+ 3201                                               IF (SymTab.ClassOf(et) #
+ 3202                                                   SymTab.ClChar)
+ 3203   AND (SymTab.ClassOf(et) #
+ 3204                                                     SymTab.ClBool)
+ 3205   AND (SymTab.ClassOf(et) #
+ 3206                                                     SymTab.ClEnum)
+ 3207   AND NOT SymTab.IsIntFamily(et) THEN
+ 3208                                                 SemError(211) END
+ 3209                                             END;
+ 3210                                             t := SymTab.IntType(); .)
+ 3211      | "CAP" "(" Expr<et, q> ")"
+ 3212      (. astNode := AST.MakeNode(AST.NkCall);
+ 3213     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
+ 3214     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3215     astCur := astNode; astIsLit := TRUE; .)
+ 3216                                          (. QbeGen.CapQ(q, qa);
+ 3217                                             QbeGen.CopyOp(qa, q);
+ 3218                                             t := SymTab.CharType(); .)
+ 3219      | "UCHR" "(" Expr<et, q> ")"
+ 3220      (. astNode := AST.MakeNode(AST.NkCall);
+ 3221     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
+ 3222     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3223     astCur := astNode; astIsLit := TRUE; .)
+ 3224                                          (. (* UCHR: the UCHAR constructor.
+ 3225                                                CHAR -> UCHAR (identity);
+ 3226                                                INTEGER familly -> UCHAR
+ 3227                                                (codepoint value). *)
+ 3228                                             IF (et # SymTab.InvalidType)
+ 3229    AND (SymTab.ClassOf(et) # SymTab.ClChar)
+ 3230    AND NOT SymTab.IsIntFamily(et) THEN
+ 3231                                               SemError(211) END;
+ 3232                                             t := SymTab.UCharType(); .)
+ 3233      | "CHR8" "(" Expr<et, q> ")"
  3234      (. astNode := AST.MakeNode(AST.NkCall);
  3234      (. astNode := AST.MakeNode(AST.NkCall);
- 3235     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
+ 3235     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
  3236     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
  3236     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
  3237     astCur := astNode; astIsLit := TRUE; .)
  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). *)
+ 3238                                          (. IF (et # SymTab.InvalidType)
+ 3239    AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
+ 3240                                               SemError(211) END;
+ 3241                                             t := SymTab.CharType(); .)
+ 3242      | "UORD" "(" Expr<et, q> ")"
+ 3243      (. astNode := AST.MakeNode(AST.NkCall);
+ 3244     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
+ 3245     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3246     astCur := astNode; astIsLit := TRUE; .)
+ 3247                                          (. (* UORD(u): the codepoint as a
+ 3248                                                32-bit ordinal (INTEGER),
+ 3249                                                cf. ORD for CHAR. *)
  3250                                             IF (et # SymTab.InvalidType)
  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.ClReal)
- 3333    AND (c2 = SymTab.ClInt) THEN
- 3334                                                   QbeGen.ConvRI(q, qa);
- 3335                                                   QbeGen.CopyOp(qa, q);
- 3336                                                   t := vt
- 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.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.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.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.
+ 3251    AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
+ 3252                                               SemError(211) END;
+ 3253                                             t := SymTab.IntType(); .)
+ 3254      | "ABS" "(" Expr<et, q> ")"
+ 3255      (. astNode := AST.MakeNode(AST.NkCall);
+ 3256     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
+ 3257     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
+ 3258     astCur := astNode; astIsLit := TRUE; .)
+ 3259                                          (. IF (et # SymTab.InvalidType)
+ 3260   AND NOT SymTab.IsIntFamily(et)
+ 3261   AND (SymTab.ClassOf(et) #
+ 3262                                                  SymTab.ClReal) THEN
+ 3263                                               SemError(211)
+ 3264                                             ELSE QbeGen.AbsQ(q, qa,
+ 3265                                                    SymTab.ClassOf(et) =
+ 3266                                                      SymTab.ClReal);
+ 3267                                               QbeGen.CopyOp(qa, q)
+ 3268                                             END;
+ 3269                                             t := et; .)
+ 3270      | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
+ 3271      (. astNode := AST.MakeNode(AST.NkCall);
+ 3272     AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
+ 3273     IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
+ 3274     IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
+ 3275     astCur := astNode; astIsLit := TRUE; .)
+ 3276                                          (. IF NOT SymTab.Lookup(vn) THEN
+ 3277                                               SemError(201);
+ 3278                                               t := SymTab.InvalidType
+ 3279                                             ELSE vt := SymTab.SymType(vn);
+ 3280                                               IF vt = SymTab.InvalidType THEN
+ 3281                                                 t := SymTab.InvalidType
+ 3282                                               ELSIF et =
+ 3283                                                  SymTab.InvalidType THEN
+ 3284                                                 t := vt
+ 3285                                               ELSE
+ 3286                                                 c1 := SymTab.ClassOf(et);
+ 3287                                                 c2 := SymTab.ClassOf(vt);
+ 3288                                                 IF (c1 = SymTab.ClInt)
+ 3289    AND (c2 = SymTab.ClLong) THEN
+ 3290                                                   QbeGen.WidenLong(q, qa);
+ 3291                                                   QbeGen.CopyOp(qa, q);
+ 3292                                                   t := vt
+ 3293                                                 ELSIF (c1 = SymTab.ClLong)
+ 3294    AND (c2 = SymTab.ClInt) THEN
+ 3295                                                   QbeGen.NarrowLong(q, qa);
+ 3296                                                   QbeGen.CopyOp(qa, q);
+ 3297                                                   t := vt
+ 3298                                                 ELSIF (c1 = SymTab.ClInt)
+ 3299    AND (c2 = SymTab.ClReal) THEN
+ 3300                                                   QbeGen.ConvIR(q, qa);
+ 3301                                                   QbeGen.CopyOp(qa, q);
+ 3302                                                   t := vt
+ 3303                                                 ELSIF (c1 = SymTab.ClLong)
+ 3304    AND (c2 = SymTab.ClReal) THEN
+ 3305                                                   QbeGen.ConvLR(q, qa);
+ 3306                                                   QbeGen.CopyOp(qa, q);
+ 3307                                                   t := vt
+ 3308                                                 ELSIF (c1 = SymTab.ClReal)
+ 3309    AND (c2 = SymTab.ClInt) THEN
+ 3310                                                   QbeGen.ConvRI(q, qa);
+ 3311                                                   QbeGen.CopyOp(qa, q);
+ 3312                                                   t := vt
+ 3313                                                 ELSIF (c1 = SymTab.ClReal)
+ 3314    AND (c2 = SymTab.ClLong) THEN
+ 3315                                                   QbeGen.ConvRL(q, qa);
+ 3316                                                   QbeGen.CopyOp(qa, q);
+ 3317                                                   t := vt
+ 3318                                                 ELSIF ((c1 = SymTab.ClInt)
+ 3319                                                     OR (c1 =
+ 3320                                                        SymTab.ClChar)
+ 3321                                                     OR (c1 =
+ 3322                                                        SymTab.ClBool)
+ 3323                                                     OR (c1 =
+ 3324                                                        SymTab.ClEnum))
+ 3325   AND ((c2 = SymTab.ClInt)
+ 3326                                                     OR (c2 =
+ 3327                                                        SymTab.ClChar)
+ 3328                                                     OR (c2 =
+ 3329                                                        SymTab.ClBool)
+ 3330                                                     OR (c2 =
+ 3331                                                        SymTab.ClEnum)) THEN
+ 3332                                                   t := vt
+ 3333                                                 ELSIF (c1 = SymTab.ClPtr)
+ 3334   AND (c2 = SymTab.ClPtr) THEN
+ 3335                                                   t := vt
+ 3336                                                 ELSIF (c1 = SymTab.ClReal)
+ 3337   AND (c2 = SymTab.ClReal) THEN
+ 3338                                                   t := vt
+ 3339                                                 ELSE SemError(230);
+ 3340                                                   t := SymTab.InvalidType
+ 3341                                                 END
+ 3342                                               END
+ 3343                                             END; .)
+ 3344      | "(" Expr<et, q> ")"               (. t := et; astIsLit := TRUE; .)
+ 3345      | SetLit<st, sq>                    (. astIsLit := TRUE; t := st;
+ 3346                                             QbeGen.CopyOp(sq, q); .)
+ 3347      | ( "NOT" | "~" ) Fact<t2, q2>      (. astNot := astCur;
+ 3348                                             IF SymTab.BoolCheck(t2) THEN
+ 3349                                               t := SymTab.BoolType()
+ 3350                                             ELSE SemError(212);
+ 3351                                               t := SymTab.InvalidType END;
+ 3352                                             IF t # SymTab.InvalidType THEN
+ 3353                                               QbeGen.NotQ(q2, q)
+ 3354                                             ELSE QbeGen.CopyOp("0", q)
+ 3355                                             END;
+ 3356                                             astIsLit := TRUE;
+ 3357                                             astCur := AST.MakeUn(
+ 3358                                               AST.NkUnary, AST.OpNot, astNot); .)
+ 3359      )
+ 3360      (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
+ 3361    (* Set literals are SET OF [0..255] (8 words); elements validated
+ 3362       0..255 statically when foldable (222 otherwise), runtime trap
+ 3363       for computed elements. Ranges always lower via SetRange. *)
+ 3364    SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
+ 3365                                          (. VAR astNode: AST.Node; .)
+ 3366      = "{"                               (. t := SymTab.NewSet(
+ 3367                                               SymTab.NewSubR(0, 255));
+ 3368                                             astNode := AST.MakeNode(AST.NkSetLit);
+ 3369                                             QbeGen.NewSetTemp(8, q);
+ 3370                                             QbeGen.SetZero(q, 8); .)
+ 3371        [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
+ 3372        "}"                               (. astCur := astNode; .) .
+ 3373    (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
+ 3374       or ArrayName{...} (an array constructor, GNU Modula-2).  The
+ 3375       declared type sets the width (set) or element type (array). *)
+ 3376    TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
+ 3377                                          (. VAR nw: CARDINAL;
+ 3378                                               astNode, astTail: AST.Node;
+ 3379                                               savedCls: INTEGER; .)
+ 3380      = "{"                               (. savedCls := braceCls;
+ 3381                                             astNode := AST.MakeNode(AST.NkBraceLit);
+ 3382                                             AST.SetTy(astNode, vt);
+ 3383                                             astTail := astNode;
+ 3384                                             IF vt = SymTab.InvalidType THEN
+ 3385                                               braceCls := -1
+ 3386                                             ELSE braceCls :=
+ 3387                                                    SymTab.ClassOf(vt)
+ 3388                                             END;
+ 3389                                             IF braceCls = SymTab.ClSet THEN
+ 3390                                               IF vt = SymTab.InvalidType THEN
+ 3391                                                 nw := 8
+ 3392                                               ELSE nw := SymTab.SetWords(vt);
+ 3393                                                 IF nw = 0 THEN nw := 8 END
+ 3394                                               END;
+ 3395                                               QbeGen.NewSetTemp(nw, q);
+ 3396                                               QbeGen.SetZero(q, nw)
+ 3397                                             ELSIF (braceCls =
+ 3398                                                    SymTab.ClArray)
+ 3399                                                OR (braceCls =
+ 3400                                                    SymTab.ClRecord)
+ 3401                                                OR (braceCls =
+ 3402                                                    SymTab.ClClass) THEN
+ 3403                                               QbeGen.CtorBegin(vt)
+ 3404                                             ELSE
+ 3405                                               IF vt # SymTab.InvalidType THEN
+ 3406                                                 SemError(230) END;
+ 3407                                               braceCls := -1
+ 3408                                             END; .)
+ 3409        [ BraceElem<vt, q, astNode, astTail>
+ 3410          { "," BraceElem<vt, q, astNode, astTail> } ]
+ 3411        "}"                               (. IF (braceCls = SymTab.ClArray)
+ 3412                                                OR (braceCls =
+ 3413                                                   SymTab.ClRecord)
+ 3414                                                OR (braceCls =
+ 3415                                                   SymTab.ClClass) THEN
+ 3416                                               QbeGen.CtorEnd(q)
+ 3417                                             ELSIF braceCls # SymTab.ClSet THEN
+ 3418                                               QbeGen.CopyOp("0", q)
+ 3419                                             END;
+ 3420                                             braceCls := savedCls; .)
+ 3421                                          (. astCur := astNode; .) .
+ 3422    BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
+ 3423              VAR node, tail: AST.Node>
+ 3424                                          (. VAR et, et2: SymTab.TypeIndex;
+ 3425                                               qe, q2: QbeGen.QVal;
+ 3426                                               v, v2, reps, k: INTEGER;
+ 3427                                               elem: SymTab.TypeIndex;
+ 3428                                               lo: INTEGER;
+ 3429                                               span: CARDINAL;
+ 3430                                               cl, cl2: INTEGER;
+ 3431                                               hasR, hasB: BOOLEAN;
+ 3432                                               astEl: AST.Node; .)
+ 3433      =                                   (. hasR := FALSE; hasB := FALSE;
+ 3434                                             reps := 1; .)
+ 3435        Expr<et, qe> (. astEl := astCur; .)
+ 3436        [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
+ 3437                                               AST.NkSubrange, 0, astEl, astCur);
+ 3438                                             hasR := TRUE; .) ]
+ 3439        [ "BY" Expr<et2, q2>              (. hasB := TRUE; .) ]
+ 3440                                          (. IF braceCls = SymTab.ClSet THEN
+ 3441                                               IF hasB THEN SemError(230) END;
+ 3442                                               lo := SymTab.SetBaseLo(vt);
+ 3443                                               span := SymTab.SetCount(vt);
+ 3444                                               IF (et = SymTab.InvalidType)
+ 3445                                                  OR (hasR AND (et2 =
+ 3446                                                     SymTab.InvalidType)) THEN
+ 3447                                               ELSE cl :=
+ 3448                                                      SymTab.ClassOf(et);
+ 3449                                                 IF hasR THEN
+ 3450                                                   cl2 :=
+ 3451                                                     SymTab.ClassOf(et2)
+ 3452                                                 ELSE cl2 := SymTab.ClInt
+ 3453                                                 END;
+ 3454                                                 IF NOT SymTab.SetElemClassOk(cl)
+ 3455                                                    OR (hasR AND NOT
+ 3456                                                       SymTab.SetElemClassOk(cl2))
+ 3457                                                 THEN
+ 3458                                                   SemError(222)
+ 3459                                                 ELSIF hasR
+ 3460   AND SymTab.ConstInt(qe, v)
+ 3461   AND SymTab.ConstInt(q2,
+ 3462                                                       v2)
+ 3463   AND ((v < lo)
+ 3464                                                       OR (v2 < lo)
+ 3465                                                       OR (v >= lo +
+ 3466                                                          VAL(INTEGER, span))
+ 3467                                                       OR (v2 >= lo +
+ 3468                                                          VAL(INTEGER, span))
+ 3469                                                       OR (v > v2)) THEN
+ 3470                                                   SemError(222)
+ 3471                                                  ELSIF hasR THEN
+ 3472                                                    QbeGen.SetRange(sq, qe, q2,
+ 3473                                                      lo, span)
+ 3474                                                  ELSIF SymTab.ConstInt(qe,
+ 3475                                                          v)
+ 3476   AND ((v < lo)
+ 3477                                                        OR (v >= lo +
+ 3478                                                           VAL(INTEGER,
+ 3479                                                             span))) THEN
+ 3480                                                    SemError(222)
+ 3481                                                  ELSE QbeGen.SetBit(sq, qe,
+ 3482                                                    lo, span)
+ 3483                                                 END
+ 3484                                               END
+ 3485                                             ELSIF (braceCls = SymTab.ClArray)
+ 3486                                                OR (braceCls =
+ 3487                                                   SymTab.ClRecord)
+ 3488                                                OR (braceCls =
+ 3489                                                   SymTab.ClClass) THEN
+ 3490                                               IF hasR THEN SemError(230) END;
+ 3491                                               reps := 1;
+ 3492                                               IF hasB THEN
+ 3493                                                 IF SymTab.ConstInt(q2, v2)
+ 3494   AND (v2 >= 1) THEN
+ 3495                                                   reps := v2
+ 3496                                                 ELSE SemError(230)
+ 3497                                                 END
+ 3498                                               END;
+ 3499                                               k := 0;
+ 3500                                               WHILE k < reps DO
+ 3501                                                 QbeGen.CtorElem(qe);
+ 3502                                                 INC(k)
+ 3503                                               END
+ 3504                                             END; .)
+ 3505                                          (. (* the BY form repeats the
+ 3506                                               element; keep the AST in
+ 3507                                               step with CtorElem *)
+ 3508                                             k := 0;
+ 3509                                             WHILE k < reps DO
+ 3510                                               AstAppend(AST.NkBlock,
+ 3511                                                 node, tail, astEl);
+ 3512                                               INC(k)
+ 3513                                             END; .) .
+ 3514    SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node>         (. VAR et, et2: SymTab.TypeIndex;
+ 3515                                               qe, q2: QbeGen.QVal;
+ 3516                                               v, v2: INTEGER;
+ 3517                                               lo: INTEGER;
+ 3518                                               span: CARDINAL;
+ 3519                                               cl, cl2: INTEGER;
+ 3520                                               hasR: BOOLEAN;
+ 3521                                               astEl: AST.Node; .)
+ 3522      =                                   (. hasR := FALSE; .)
+ 3523        Expr<et, qe> (. astEl := astCur; .)
+ 3524        [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
+ 3525                                               AST.NkSubrange, 0, astEl, astCur);
+ 3526                                             hasR := TRUE; .) ]
+ 3527                                          (. lo := SymTab.SetBaseLo(st);
+ 3528                                             span := SymTab.SetCount(st);
+ 3529                                             IF (et = SymTab.InvalidType)
+ 3530                                                OR (hasR AND (et2 =
+ 3531                                                   SymTab.InvalidType)) THEN
+ 3532                                             ELSE cl :=
+ 3533                                                    SymTab.ClassOf(et);
+ 3534                                               IF hasR THEN
+ 3535                                                 cl2 :=
+ 3536                                                   SymTab.ClassOf(et2)
+ 3537                                               ELSE cl2 := SymTab.ClInt
+ 3538                                               END;
+ 3539                                               IF NOT SymTab.SetElemClassOk(cl)
+ 3540                                                  OR (hasR AND NOT
+ 3541                                                     SymTab.SetElemClassOk(cl2))
+ 3542                                               THEN
+ 3543                                                 SemError(222)
+ 3544                                               ELSIF hasR
+ 3545   AND SymTab.ConstInt(qe, v)
+ 3546   AND SymTab.ConstInt(q2,
+ 3547                                                     v2)
+ 3548   AND ((v < lo)
+ 3549                                                     OR (v2 < lo)
+ 3550                                                     OR (v >= lo +
+ 3551                                                        VAL(INTEGER, span))
+ 3552                                                     OR (v2 >= lo +
+ 3553                                                        VAL(INTEGER, span))
+ 3554                                                     OR (v > v2)) THEN
+ 3555                                                 SemError(222)
+ 3556                                                ELSIF hasR THEN
+ 3557                                                  QbeGen.SetRange(sq, qe, q2,
+ 3558                                                    lo, span)
+ 3559                                                ELSIF SymTab.ConstInt(qe,
+ 3560                                                        v)
+ 3561   AND ((v < lo)
+ 3562                                                      OR (v >= lo +
+ 3563                                                         VAL(INTEGER,
+ 3564                                                           span))) THEN
+ 3565                                                  SemError(222)
+ 3566                                                ELSE QbeGen.SetBit(sq, qe,
+ 3567                                                  lo, span)
+ 3568                                               END
+ 3569                                             END; .)
+ 3570                                          (. AST.SetChild(node,
+ 3571                                               AST.NChild(node), astEl); .) .
+ 3572    GetIdent<VAR n: SymTab.Name>
+ 3573      = ident                             (. LexName(n); .) .
+ 3574  
+ 3575  END M2.
 
 
     0 errors
     0 errors