Преглед изворни кода

lower L5 (literals): char/real/string/set literals, IN, typed relations

- Literals: NkCharLit (NormLit), NkRealLit (NormReal), NkStrLit (1-char
  -> IntStr, else DeclStr + NoteAddr), NkSetLit (NewSetTemp/SetZero +
  SetBit/SetRange).
- Relations now dispatch on type: IN -> InSet; pointer -> CmpL; set ->
  CmpSet; string -> StrEq; long -> CmpLong (with WidenLong); else Cmp.

t_lower5lit (string assign, real/set literals, IN) byte-matches.
Suite 189/189; FIXPOINT OK (stage2 == stage3, 3,292,658 bytes).
Eric Streit пре 1 недеља
родитељ
комит
5e23bfee5e
3 измењених фајлова са 90 додато и 7 уклоњено
  1. 1 0
      compiler/run_tests.sh
  2. 71 7
      compiler/src/Lower.mod
  3. 18 0
      compiler/tests/t_lower5lit.mod

+ 1 - 0
compiler/run_tests.sh

@@ -473,6 +473,7 @@ lower_ok t_lower4.mod
 lower_ok t_lower4case.mod
 lower_ok t_lower4with.mod
 lower_ok t_lower5.mod
+lower_ok t_lower5lit.mod
 
 # --- step 7 gate: compiler sources free of gm2-only imports.
 #     FileIO is the last module to port (see docs/summary_step7.md);

+ 71 - 7
compiler/src/Lower.mod

@@ -217,7 +217,7 @@ PROCEDURE IsArith (op: INTEGER): BOOLEAN;
 
 PROCEDURE IsRel (op: INTEGER): BOOLEAN;
   BEGIN
-    RETURN (op >= AST.OpEq) AND (op <= AST.OpGe)
+    RETURN ((op >= AST.OpEq) AND (op <= AST.OpGe)) OR (op = AST.OpIn)
   END IsRel;
 
 PROCEDURE RelSym (a: INTEGER; VAR s: INTEGER): BOOLEAN;
@@ -408,10 +408,25 @@ PROCEDURE CanCaseLabel (lab: AST.Node): BOOLEAN;
   END CanCaseLabel;
 
 PROCEDURE CanExpr (n: AST.Node): BOOLEAN;
-  VAR op: INTEGER; nm: SymTab.Name;
+  VAR op: INTEGER; nm: SymTab.Name; i: CARDINAL;
   BEGIN
     IF n = AST.NoNode THEN RETURN FALSE END;
     IF AST.Kind(n) = AST.NkIntLit THEN RETURN TRUE END;
+    IF AST.Kind(n) = AST.NkCharLit THEN RETURN TRUE END;
+    IF AST.Kind(n) = AST.NkRealLit THEN RETURN TRUE END;
+    IF AST.Kind(n) = AST.NkStrLit THEN RETURN TRUE END;
+    IF AST.Kind(n) = AST.NkSetLit THEN
+      i := 0;
+      WHILE i < AST.NChild(n) DO
+        IF AST.Kind(AST.Child(n, i)) = AST.NkSubrange THEN
+          IF NOT CanExpr(AST.Child(AST.Child(n, i), 0)) THEN RETURN FALSE END;
+          IF NOT CanExpr(AST.Child(AST.Child(n, i), 1)) THEN RETURN FALSE END
+        ELSIF NOT CanExpr(AST.Child(n, i)) THEN RETURN FALSE
+        END;
+        INC(i)
+      END;
+      RETURN TRUE
+    END;
     IF AST.Kind(n) = AST.NkDesignator THEN RETURN CanDesign(n) END;
     IF AST.Kind(n) = AST.NkCall THEN
       CalleeName(n, nm);
@@ -956,7 +971,8 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
   VAR t2: SymTab.TypeIndex; q2, qt, qf, qs, qr: QbeGen.QVal;
       lNext, lFalse, lTrue, lDone: QbeGen.QVal;
       kind, op, rop: INTEGER;
-      folded, isR: BOOLEAN;
+      folded, isR, isCh: BOOLEAN;
+      i: CARDINAL; el: AST.Node;
   BEGIN
     IF AST.Kind(n) = AST.NkDesignator THEN
       LowerDesign(n, t, k, q, qn, sfx);
@@ -966,6 +982,33 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
     k := -1; qn[0] := CHR(0); sfx := FALSE;
     IF AST.Kind(n) = AST.NkIntLit THEN
       Name(n, qn); QbeGen.NormInt(qn, q); t := SymTab.IntType()
+    ELSIF AST.Kind(n) = AST.NkCharLit THEN
+      Name(n, qn); QbeGen.NormLit(qn, q, isCh); t := SymTab.CharType()
+    ELSIF AST.Kind(n) = AST.NkRealLit THEN
+      Name(n, qn); QbeGen.NormReal(qn, q); t := SymTab.RealType()
+    ELSIF AST.Kind(n) = AST.NkStrLit THEN
+      Name(n, qn);
+      IF SymTab.StrLen(qn) = 3 THEN
+        t := SymTab.CharType(); QbeGen.IntStr(QbeGen.CharVal(qn), q)
+      ELSE
+        t := SymTab.NewStr(); QbeGen.DeclStr(qn, q); QbeGen.NoteAddr(q, q)
+      END
+    ELSIF AST.Kind(n) = AST.NkSetLit THEN
+      t := SymTab.NewSet(SymTab.NewSubR(0, 255));
+      QbeGen.NewSetTemp(8, q); QbeGen.SetZero(q, 8);
+      i := 0;
+      WHILE i < AST.NChild(n) DO
+        el := AST.Child(n, i);
+        IF AST.Kind(el) = AST.NkSubrange THEN
+          LowerExpr(AST.Child(el, 0), t2, q2);
+          LowerExpr(AST.Child(el, 1), t2, qt);
+          QbeGen.SetRange(q, q2, qt, SymTab.SetBaseLo(t), SymTab.SetCount(t))
+        ELSE
+          LowerExpr(el, t2, q2);
+          QbeGen.SetBit(q, q2, SymTab.SetBaseLo(t), SymTab.SetCount(t))
+        END;
+        INC(i)
+      END
     ELSIF AST.Kind(n) = AST.NkDesignator THEN
       LowerDesign(n, t, k, q, qn, sfx)
     ELSIF AST.Kind(n) = AST.NkCall THEN
@@ -988,10 +1031,31 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
         LowerExpr(AST.Child(n, 0), t, q);
         LowerExpr(AST.Child(n, 1), t2, q2);
         rop := SymTab.OpEq; folded := RelSym(op, rop);
-        isR := (t # SymTab.InvalidType) AND (SymTab.ClassOf(t) = SymTab.ClReal);
-        t := SymTab.BoolType();
-        QbeGen.Cmp(rop, q, q2, qt, isR);
-        QbeGen.CopyOp(qt, q)
+        IF op = AST.OpIn THEN
+          QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2), SymTab.SetCount(t2), qt);
+          t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
+        ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
+           OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
+          QbeGen.CmpL(rop, q, q2, qt);
+          t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
+        ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
+           OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
+          QbeGen.CmpSet(rop, q, q2, SymTab.SetWords(t), SymTab.SetWords(t2), qt);
+          t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
+        ELSIF SymTab.StrCompat(t, t2) THEN
+          QbeGen.StrEq(rop, q, q2, qt);
+          t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
+        ELSIF SymTab.IsLongFamily(t) OR SymTab.IsLongFamily(t2) THEN
+          IF SymTab.IsIntFamily(t) THEN QbeGen.WidenLong(q, qf); QbeGen.CopyOp(qf, q) END;
+          IF SymTab.IsIntFamily(t2) THEN QbeGen.WidenLong(q2, qf); QbeGen.CopyOp(qf, q2) END;
+          QbeGen.CmpLong(rop, q, q2, qt);
+          t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
+        ELSE
+          isR := (t # SymTab.InvalidType) AND (SymTab.ClassOf(t) = SymTab.ClReal);
+          t := SymTab.BoolType();
+          QbeGen.Cmp(rop, q, q2, qt, isR);
+          QbeGen.CopyOp(qt, q)
+        END
       ELSIF op = AST.OpAnd THEN
         LowerExpr(AST.Child(n, 0), t, q);
         QbeGen.DelayBegin;

+ 18 - 0
compiler/tests/t_lower5lit.mod

@@ -0,0 +1,18 @@
+MODULE TLower5Lit;
+(* Lower slice L5: char/real/string/set literals and IN.  Exit 42. *)
+TYPE
+  Vec = ARRAY [0..7] OF CHAR;
+VAR
+  s : Vec;
+  r : REAL;
+  b : BOOLEAN;
+  st : SET OF [0..7];
+  i, ExitCode : INTEGER;
+BEGIN
+  s := "hello";
+  r := 2.5;
+  st := {1, 3, 5};
+  b := 3 IN st;
+  i := ORD(s[1]);
+  IF b THEN ExitCode := i - 59 ELSE ExitCode := 0 END
+END TLower5Lit.