Ver código fonte

lower L7: more flip coverage (WITH nesting, constructors, aggregate CONST)

- WITH: LowerWith popped every level, so a nested WITH lost the outer
  context; it now pops only the levels it pushed.
- Aggregate constructors (T{...} for arrays/records/classes) are
  lowered via CtorBegin/CtorElem/CtorEnd; the AST carries the BY repeat
  count so the element list matches CtorElem's calls.
- A CONST of an aggregate/string type is re-emitted from its AST (the
  grammar's CtorEnd/DeclStr are suppressed under NoEmit) and its
  recorded value refreshed, so later uses resolve the descriptor.
- lower_ok_files now generates the legacy image itself (it was
  comparing against a stale gen_ssa/<prog>.ssa).

Suite 204/204; FIXPOINT OK (3,524,425 bytes).
Eric Streit 4 dias atrás
pai
commit
ff16c2ce7b
4 arquivos alterados com 210 adições e 148 exclusões
  1. 5 1
      compiler/run_tests.sh
  2. 51 9
      compiler/src/Lower.mod
  3. 11 3
      compiler/src/M2.atg
  4. 143 135
      compiler/src/M2.lst

+ 5 - 1
compiler/run_tests.sh

@@ -473,7 +473,11 @@ lower_ok_files() {
   for f in "$@"; do
     case "$f" in */*) files="$files $f";; *) files="$files tests/$f";; esac
   done
-  rm -f "gen_ssa/${prog}L.ssa"
+  rm -f "gen_ssa/$prog.ssa" "gen_ssa/${prog}L.ssa"
+  # generate the legacy image first (self-contained)
+  if ./M2 $files 2>&1 | grep -q "Parsed correctly"; then :; else
+    fail=$((fail+1)); echo "FAIL(lower): $prog legacy rejected"; return
+  fi
   if ./M2 -lower $files 2>&1 | grep -q "Parsed correctly"; then :; else
     fail=$((fail+1)); echo "FAIL(lower): $prog rejected"; return
   fi

+ 51 - 9
compiler/src/Lower.mod

@@ -302,6 +302,15 @@ PROCEDURE GetConstVal (name: ARRAY OF CHAR; VAR v: ARRAY OF CHAR): BOOLEAN;
     RETURN v[0] # CHR(0)
   END GetConstVal;
 
+PROCEDURE SetConstVal (name: ARRAY OF CHAR; val: ARRAY OF CHAR);
+(* Refresh a CONST's recorded value after Lower re-emits its aggregate
+   constructor (the grammar's value was suppressed under NoEmit). *)
+  VAR i: INTEGER;
+  BEGIN
+    i := HashGet(symHash, symName, name);
+    IF i >= 0 THEN CopySpan(val, symVal, 0, VAL(CARDINAL, i) * 64) END
+  END SetConstVal;
+
 PROCEDURE ProcNameEq (i: CARDINAL; name: ARRAY OF CHAR): BOOLEAN;
   VAR j: CARDINAL;
   BEGIN
@@ -1720,10 +1729,12 @@ PROCEDURE LowerCase (n: AST.Node);
   END LowerCase;
 
 PROCEDURE LowerWith (n: AST.Node);
-(* WITH: push each record's base address, lower the body, pop. *)
-  VAR i: CARDINAL; dt: SymTab.TypeIndex; dk: INTEGER; qd: QbeGen.QVal;
-      qn: SymTab.Name; sfx: BOOLEAN;
+(* WITH: push each record's base address, lower the body, pop only the
+   levels this WITH pushed (a nested WITH must restore the outer one). *)
+  VAR i, base: CARDINAL; dt: SymTab.TypeIndex; dk: INTEGER;
+      qd: QbeGen.QVal; qn: SymTab.Name; sfx: BOOLEAN;
   BEGIN
+    base := withTop;
     i := 0;
     WHILE i + 1 < AST.NChild(n) DO
       LowerDesign(AST.Child(n, i), dt, dk, qd, qn, sfx);
@@ -1734,7 +1745,7 @@ PROCEDURE LowerWith (n: AST.Node);
       INC(i)
     END;
     LowerStmt(AST.Child(n, AST.NChild(n) - 1));
-    WHILE withTop > 0 DO DEC(withTop); QbeGen.PopWith END
+    WHILE withTop > base DO DEC(withTop); QbeGen.PopWith END
   END LowerWith;
 
 PROCEDURE LowerProcAddr (nm: ARRAY OF CHAR; VAR q: QbeGen.QVal);
@@ -1852,6 +1863,31 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
           END;
           seq := next
         END
+      ELSIF (t # SymTab.InvalidType)
+         AND ((SymTab.ClassOf(t) = SymTab.ClArray)
+              OR (SymTab.ClassOf(t) = SymTab.ClRecord)
+              OR (SymTab.ClassOf(t) = SymTab.ClClass)) THEN
+        (* T{...} aggregate constructor *)
+        QbeGen.CtorBegin(t);
+        seq := n;
+        WHILE seq # AST.NoNode DO
+          i := 0;
+          WHILE i < AST.NChild(seq) DO
+            el := AST.Child(seq, i);
+            IF AST.Kind(el) # AST.NkBlock THEN
+              LowerExpr(el, t2, q2);
+              QbeGen.CtorElem(q2)
+            END;
+            INC(i)
+          END;
+          next := AST.NoNode;
+          IF AST.NChild(seq) > 0 THEN
+            next := AST.Child(seq, AST.NChild(seq) - 1);
+            IF AST.Kind(next) # AST.NkBlock THEN next := AST.NoNode END
+          END;
+          seq := next
+        END;
+        QbeGen.CtorEnd(q)
       ELSE
         t := SymTab.InvalidType; QbeGen.CopyOp("0", q)
       END
@@ -2305,11 +2341,17 @@ PROCEDURE LowerDecls (seq: AST.Node);
         END
       ELSIF AST.Kind(c) = AST.NkConstDecl THEN
         Name(AST.Child(c, 0), nm);
-        (* The value is a constant expression (CHR(..), arithmetic, a
-           prior CONST): use the evaluated value recorded by NoteConstVal,
-           not the AST text.  Aggregates/strings store a descriptor
-           address and are not scalar data. *)
-        IF GetConstVal(nm, qv) AND QbeGen.IsImm(qv) THEN
+        kk := SymTab.ClassOf(AST.Ty(c));
+        IF (kk = SymTab.ClArray) OR (kk = SymTab.ClRecord)
+           OR (kk = SymTab.ClClass) OR (kk = SymTab.ClStr)
+           OR (kk = SymTab.ClUStr) THEN
+          (* aggregate/string CONST: re-emit the constructor/string so
+             its static data is produced (the grammar's CtorEnd/DeclStr
+             are suppressed under NoEmit), then refresh the value *)
+          LowerExpr(AST.Child(c, 1), ct, qv);
+          SetConstVal(nm, qv)
+        ELSIF GetConstVal(nm, qv) AND QbeGen.IsImm(qv) THEN
+          (* scalar: use the evaluated value recorded by NoteConstVal *)
           QbeGen.DeclConst(nm, qv, AST.Ty(c))
         END
       ELSIF AST.Kind(c) = AST.NkProcDecl THEN

+ 11 - 3
compiler/src/M2.atg

@@ -3743,7 +3743,8 @@ PRODUCTIONS
                                              cl, cl2: INTEGER;
                                              hasR, hasB: BOOLEAN;
                                              astEl: AST.Node; .)
-    =                                   (. hasR := FALSE; hasB := FALSE; .)
+    =                                   (. hasR := FALSE; hasB := FALSE;
+                                           reps := 1; .)
       Expr<et, qe> (. astEl := astCur; .)
       [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
                                              AST.NkSubrange, 0, astEl, astCur);
@@ -3814,8 +3815,15 @@ PRODUCTIONS
                                                INC(k)
                                              END
                                            END; .)
-                                        (. AstAppend(AST.NkBlock,
-                                             node, tail, astEl); .) .
+                                        (. (* the BY form repeats the
+                                             element; keep the AST in
+                                             step with CtorElem *)
+                                           k := 0;
+                                           WHILE k < reps DO
+                                             AstAppend(AST.NkBlock,
+                                               node, tail, astEl);
+                                             INC(k)
+                                           END; .) .
   SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node>         (. VAR et, et2: SymTab.TypeIndex;
                                              qe, q2: QbeGen.QVal;
                                              v, v2: INTEGER;

+ 143 - 135
compiler/src/M2.lst

@@ -3761,141 +3761,149 @@ Listing:
  3743                                               cl, cl2: INTEGER;
  3744                                               hasR, hasB: BOOLEAN;
  3745                                               astEl: AST.Node; .)
- 3746      =                                   (. hasR := FALSE; hasB := FALSE; .)
- 3747        Expr<et, qe> (. astEl := astCur; .)
- 3748        [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
- 3749                                               AST.NkSubrange, 0, astEl, astCur);
- 3750                                             hasR := TRUE; .) ]
- 3751        [ "BY" Expr<et2, q2>              (. hasB := TRUE; .) ]
- 3752                                          (. IF braceCls = SymTab.ClSet THEN
- 3753                                               IF hasB THEN SemError(230) END;
- 3754                                               lo := SymTab.SetBaseLo(vt);
- 3755                                               span := SymTab.SetCount(vt);
- 3756                                               IF (et = SymTab.InvalidType)
- 3757                                                  OR (hasR AND (et2 =
- 3758                                                     SymTab.InvalidType)) THEN
- 3759                                               ELSE cl :=
- 3760                                                      SymTab.ClassOf(et);
- 3761                                                 IF hasR THEN
- 3762                                                   cl2 :=
- 3763                                                     SymTab.ClassOf(et2)
- 3764                                                 ELSE cl2 := SymTab.ClInt
- 3765                                                 END;
- 3766                                                 IF NOT SymTab.SetElemClassOk(cl)
- 3767                                                    OR (hasR AND NOT
- 3768                                                       SymTab.SetElemClassOk(cl2))
- 3769                                                 THEN
- 3770                                                   SemError(222)
- 3771                                                 ELSIF hasR
- 3772   AND SymTab.ConstInt(qe, v)
- 3773   AND SymTab.ConstInt(q2,
- 3774                                                       v2)
- 3775   AND ((v < lo)
- 3776                                                       OR (v2 < lo)
- 3777                                                       OR (v >= lo +
- 3778                                                          VAL(INTEGER, span))
- 3779                                                       OR (v2 >= lo +
- 3780                                                          VAL(INTEGER, span))
- 3781                                                       OR (v > v2)) THEN
- 3782                                                   SemError(222)
- 3783                                                  ELSIF hasR THEN
- 3784                                                    QbeGen.SetRange(sq, qe, q2,
- 3785                                                      lo, span)
- 3786                                                  ELSIF SymTab.ConstInt(qe,
- 3787                                                          v)
- 3788   AND ((v < lo)
- 3789                                                        OR (v >= lo +
- 3790                                                           VAL(INTEGER,
- 3791                                                             span))) THEN
- 3792                                                    SemError(222)
- 3793                                                  ELSE QbeGen.SetBit(sq, qe,
- 3794                                                    lo, span)
- 3795                                                 END
- 3796                                               END
- 3797                                             ELSIF (braceCls = SymTab.ClArray)
- 3798                                                OR (braceCls =
- 3799                                                   SymTab.ClRecord)
- 3800                                                OR (braceCls =
- 3801                                                   SymTab.ClClass) THEN
- 3802                                               IF hasR THEN SemError(230) END;
- 3803                                               reps := 1;
- 3804                                               IF hasB THEN
- 3805                                                 IF SymTab.ConstInt(q2, v2)
- 3806   AND (v2 >= 1) THEN
- 3807                                                   reps := v2
- 3808                                                 ELSE SemError(230)
- 3809                                                 END
- 3810                                               END;
- 3811                                               k := 0;
- 3812                                               WHILE k < reps DO
- 3813                                                 QbeGen.CtorElem(qe);
- 3814                                                 INC(k)
- 3815                                               END
- 3816                                             END; .)
- 3817                                          (. AstAppend(AST.NkBlock,
- 3818                                               node, tail, astEl); .) .
- 3819    SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node>         (. VAR et, et2: SymTab.TypeIndex;
- 3820                                               qe, q2: QbeGen.QVal;
- 3821                                               v, v2: INTEGER;
- 3822                                               lo: INTEGER;
- 3823                                               span: CARDINAL;
- 3824                                               cl, cl2: INTEGER;
- 3825                                               hasR: BOOLEAN;
- 3826                                               astEl: AST.Node; .)
- 3827      =                                   (. hasR := FALSE; .)
- 3828        Expr<et, qe> (. astEl := astCur; .)
- 3829        [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
- 3830                                               AST.NkSubrange, 0, astEl, astCur);
- 3831                                             hasR := TRUE; .) ]
- 3832                                          (. lo := SymTab.SetBaseLo(st);
- 3833                                             span := SymTab.SetCount(st);
- 3834                                             IF (et = SymTab.InvalidType)
- 3835                                                OR (hasR AND (et2 =
- 3836                                                   SymTab.InvalidType)) THEN
- 3837                                             ELSE cl :=
- 3838                                                    SymTab.ClassOf(et);
- 3839                                               IF hasR THEN
- 3840                                                 cl2 :=
- 3841                                                   SymTab.ClassOf(et2)
- 3842                                               ELSE cl2 := SymTab.ClInt
- 3843                                               END;
- 3844                                               IF NOT SymTab.SetElemClassOk(cl)
- 3845                                                  OR (hasR AND NOT
- 3846                                                     SymTab.SetElemClassOk(cl2))
- 3847                                               THEN
- 3848                                                 SemError(222)
- 3849                                               ELSIF hasR
- 3850   AND SymTab.ConstInt(qe, v)
- 3851   AND SymTab.ConstInt(q2,
- 3852                                                     v2)
- 3853   AND ((v < lo)
- 3854                                                     OR (v2 < lo)
- 3855                                                     OR (v >= lo +
- 3856                                                        VAL(INTEGER, span))
- 3857                                                     OR (v2 >= lo +
- 3858                                                        VAL(INTEGER, span))
- 3859                                                     OR (v > v2)) THEN
- 3860                                                 SemError(222)
- 3861                                                ELSIF hasR THEN
- 3862                                                  QbeGen.SetRange(sq, qe, q2,
- 3863                                                    lo, span)
- 3864                                                ELSIF SymTab.ConstInt(qe,
- 3865                                                        v)
- 3866   AND ((v < lo)
- 3867                                                      OR (v >= lo +
- 3868                                                         VAL(INTEGER,
- 3869                                                           span))) THEN
- 3870                                                  SemError(222)
- 3871                                                ELSE QbeGen.SetBit(sq, qe,
- 3872                                                  lo, span)
- 3873                                               END
- 3874                                             END; .)
- 3875                                          (. AST.SetChild(node,
- 3876                                               AST.NChild(node), astEl); .) .
- 3877    GetIdent<VAR n: SymTab.Name>
- 3878      = ident                             (. LexName(n); .) .
- 3879  
- 3880  END M2.
+ 3746      =                                   (. hasR := FALSE; hasB := FALSE;
+ 3747                                             reps := 1; .)
+ 3748        Expr<et, qe> (. astEl := astCur; .)
+ 3749        [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
+ 3750                                               AST.NkSubrange, 0, astEl, astCur);
+ 3751                                             hasR := TRUE; .) ]
+ 3752        [ "BY" Expr<et2, q2>              (. hasB := TRUE; .) ]
+ 3753                                          (. IF braceCls = SymTab.ClSet THEN
+ 3754                                               IF hasB THEN SemError(230) END;
+ 3755                                               lo := SymTab.SetBaseLo(vt);
+ 3756                                               span := SymTab.SetCount(vt);
+ 3757                                               IF (et = SymTab.InvalidType)
+ 3758                                                  OR (hasR AND (et2 =
+ 3759                                                     SymTab.InvalidType)) THEN
+ 3760                                               ELSE cl :=
+ 3761                                                      SymTab.ClassOf(et);
+ 3762                                                 IF hasR THEN
+ 3763                                                   cl2 :=
+ 3764                                                     SymTab.ClassOf(et2)
+ 3765                                                 ELSE cl2 := SymTab.ClInt
+ 3766                                                 END;
+ 3767                                                 IF NOT SymTab.SetElemClassOk(cl)
+ 3768                                                    OR (hasR AND NOT
+ 3769                                                       SymTab.SetElemClassOk(cl2))
+ 3770                                                 THEN
+ 3771                                                   SemError(222)
+ 3772                                                 ELSIF hasR
+ 3773   AND SymTab.ConstInt(qe, v)
+ 3774   AND SymTab.ConstInt(q2,
+ 3775                                                       v2)
+ 3776   AND ((v < lo)
+ 3777                                                       OR (v2 < lo)
+ 3778                                                       OR (v >= lo +
+ 3779                                                          VAL(INTEGER, span))
+ 3780                                                       OR (v2 >= lo +
+ 3781                                                          VAL(INTEGER, span))
+ 3782                                                       OR (v > v2)) THEN
+ 3783                                                   SemError(222)
+ 3784                                                  ELSIF hasR THEN
+ 3785                                                    QbeGen.SetRange(sq, qe, q2,
+ 3786                                                      lo, span)
+ 3787                                                  ELSIF SymTab.ConstInt(qe,
+ 3788                                                          v)
+ 3789   AND ((v < lo)
+ 3790                                                        OR (v >= lo +
+ 3791                                                           VAL(INTEGER,
+ 3792                                                             span))) THEN
+ 3793                                                    SemError(222)
+ 3794                                                  ELSE QbeGen.SetBit(sq, qe,
+ 3795                                                    lo, span)
+ 3796                                                 END
+ 3797                                               END
+ 3798                                             ELSIF (braceCls = SymTab.ClArray)
+ 3799                                                OR (braceCls =
+ 3800                                                   SymTab.ClRecord)
+ 3801                                                OR (braceCls =
+ 3802                                                   SymTab.ClClass) THEN
+ 3803                                               IF hasR THEN SemError(230) END;
+ 3804                                               reps := 1;
+ 3805                                               IF hasB THEN
+ 3806                                                 IF SymTab.ConstInt(q2, v2)
+ 3807   AND (v2 >= 1) THEN
+ 3808                                                   reps := v2
+ 3809                                                 ELSE SemError(230)
+ 3810                                                 END
+ 3811                                               END;
+ 3812                                               k := 0;
+ 3813                                               WHILE k < reps DO
+ 3814                                                 QbeGen.CtorElem(qe);
+ 3815                                                 INC(k)
+ 3816                                               END
+ 3817                                             END; .)
+ 3818                                          (. (* the BY form repeats the
+ 3819                                               element; keep the AST in
+ 3820                                               step with CtorElem *)
+ 3821                                             k := 0;
+ 3822                                             WHILE k < reps DO
+ 3823                                               AstAppend(AST.NkBlock,
+ 3824                                                 node, tail, astEl);
+ 3825                                               INC(k)
+ 3826                                             END; .) .
+ 3827    SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node>         (. VAR et, et2: SymTab.TypeIndex;
+ 3828                                               qe, q2: QbeGen.QVal;
+ 3829                                               v, v2: INTEGER;
+ 3830                                               lo: INTEGER;
+ 3831                                               span: CARDINAL;
+ 3832                                               cl, cl2: INTEGER;
+ 3833                                               hasR: BOOLEAN;
+ 3834                                               astEl: AST.Node; .)
+ 3835      =                                   (. hasR := FALSE; .)
+ 3836        Expr<et, qe> (. astEl := astCur; .)
+ 3837        [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
+ 3838                                               AST.NkSubrange, 0, astEl, astCur);
+ 3839                                             hasR := TRUE; .) ]
+ 3840                                          (. lo := SymTab.SetBaseLo(st);
+ 3841                                             span := SymTab.SetCount(st);
+ 3842                                             IF (et = SymTab.InvalidType)
+ 3843                                                OR (hasR AND (et2 =
+ 3844                                                   SymTab.InvalidType)) THEN
+ 3845                                             ELSE cl :=
+ 3846                                                    SymTab.ClassOf(et);
+ 3847                                               IF hasR THEN
+ 3848                                                 cl2 :=
+ 3849                                                   SymTab.ClassOf(et2)
+ 3850                                               ELSE cl2 := SymTab.ClInt
+ 3851                                               END;
+ 3852                                               IF NOT SymTab.SetElemClassOk(cl)
+ 3853                                                  OR (hasR AND NOT
+ 3854                                                     SymTab.SetElemClassOk(cl2))
+ 3855                                               THEN
+ 3856                                                 SemError(222)
+ 3857                                               ELSIF hasR
+ 3858   AND SymTab.ConstInt(qe, v)
+ 3859   AND SymTab.ConstInt(q2,
+ 3860                                                     v2)
+ 3861   AND ((v < lo)
+ 3862                                                     OR (v2 < lo)
+ 3863                                                     OR (v >= lo +
+ 3864                                                        VAL(INTEGER, span))
+ 3865                                                     OR (v2 >= lo +
+ 3866                                                        VAL(INTEGER, span))
+ 3867                                                     OR (v > v2)) THEN
+ 3868                                                 SemError(222)
+ 3869                                                ELSIF hasR THEN
+ 3870                                                  QbeGen.SetRange(sq, qe, q2,
+ 3871                                                    lo, span)
+ 3872                                                ELSIF SymTab.ConstInt(qe,
+ 3873                                                        v)
+ 3874   AND ((v < lo)
+ 3875                                                      OR (v >= lo +
+ 3876                                                         VAL(INTEGER,
+ 3877                                                           span))) THEN
+ 3878                                                  SemError(222)
+ 3879                                                ELSE QbeGen.SetBit(sq, qe,
+ 3880                                                  lo, span)
+ 3881                                               END
+ 3882                                             END; .)
+ 3883                                          (. AST.SetChild(node,
+ 3884                                               AST.NChild(node), astEl); .) .
+ 3885    GetIdent<VAR n: SymTab.Name>
+ 3886      = ident                             (. LexName(n); .) .
+ 3887  
+ 3888  END M2.
 
     0 errors