Sfoglia il codice sorgente

two-phase slice 9: brace and set literal AST

SetLit/SetElem build NkSetLit (ranges as NkSubrange); TypedBraceLit/
BraceElem build NkBraceLit.  The enclosing node is passed to the element
productions; Fact keeps the brace node via astBrace.  Nodes are inert.

Deferred: ResultComp, imports/CLASS/nested modules, Lower.

Gates: suite 178/178; fixpoint OK (stage2 == stage3, 3024098 bytes).

See docs/summary_two-phase-slice9.md.
Eric Streit 1 settimana fa
parent
commit
a9cb6b354d
4 ha cambiato i file con 825 aggiunte e 752 eliminazioni
  1. 37 19
      compiler/src/M2.atg
  2. 748 730
      compiler/src/M2.lst
  3. 4 3
      docs/plan-two-phase.md
  4. 36 0
      docs/summary_two-phase-slice9.md

+ 37 - 19
compiler/src/M2.atg

@@ -2873,7 +2873,8 @@ PRODUCTIONS
                                               astCall: BOOLEAN;
                                               astCall: BOOLEAN;
                                               astNode, astNot: AST.Node;
                                               astNode, astNot: AST.Node;
                                               j: CARDINAL;
                                               j: CARDINAL;
-                                              astArg2: AST.Node; .)
+                                              astArg2: AST.Node;
+                                              astBrace: AST.Node; .)
     = (. astIsLit := FALSE; .)
     = (. astIsLit := FALSE; .)
     ( integer                           (. LexString(s);
     ( integer                           (. LexString(s);
                                            QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
                                            QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
@@ -2928,7 +2929,8 @@ PRODUCTIONS
                                              t := SymTab.NewUStr();
                                              t := SymTab.NewUStr();
                                              QbeGen.NoteAddr(q, q)
                                              QbeGen.NoteAddr(q, q)
                                            END; .)
                                            END; .)
-    | Design<dt, dk, qd, qn, sfx>       (. astD := astCur; astCall := FALSE; astNArgs := 0; called := FALSE;
+    | Design<dt, dk, qd, qn, sfx>       (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
+                                           astNArgs := 0; called := FALSE;
                                            t := dt;
                                            t := dt;
                                            IF sfx THEN
                                            IF sfx THEN
                                              IF dt =
                                              IF dt =
@@ -2969,7 +2971,8 @@ PRODUCTIONS
                                                      SymTab.ClRecord)) THEN
                                                      SymTab.ClRecord)) THEN
                                              QbeGen.NoteAddr(qd, qd)
                                              QbeGen.NoteAddr(qd, qd)
                                            END; .)
                                            END; .)
-      [ TypedBraceLit<dt, q>            (. t := dt; astCall := TRUE; .) ]
+      [ TypedBraceLit<dt, q>            (. t := dt; astCall := TRUE;
+                                             astBrace := astCur; .) ]
       [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
       [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
                                         (. astCall := TRUE; t := ct2;
                                         (. astCall := TRUE; t := ct2;
                                            QbeGen.CopyOp(q2, q);
                                            QbeGen.CopyOp(q2, q);
@@ -3000,7 +3003,7 @@ PRODUCTIONS
                                              END;
                                              END;
                                              astCur := astNode
                                              astCur := astNode
                                            ELSIF astCall THEN
                                            ELSIF astCall THEN
-                                             astCur := AST.NoNode
+                                             astCur := astBrace
                                            ELSE astCur := astD
                                            ELSE astCur := astD
                                            END;
                                            END;
                                             astIsLit := TRUE;
                                             astIsLit := TRUE;
@@ -3405,7 +3408,7 @@ PRODUCTIONS
                                              END
                                              END
                                            END; .)
                                            END; .)
     | "(" Expr<et, q> ")"               (. t := et; astIsLit := TRUE; .)
     | "(" Expr<et, q> ")"               (. t := et; astIsLit := TRUE; .)
-    | SetLit<st, sq>                    (. t := st;
+    | SetLit<st, sq>                    (. astIsLit := TRUE; t := st;
                                            QbeGen.CopyOp(sq, q); .)
                                            QbeGen.CopyOp(sq, q); .)
     | ( "NOT" | "~" ) Fact<t2, q2>      (. astNot := astCur;
     | ( "NOT" | "~" ) Fact<t2, q2>      (. astNot := astCur;
                                            IF SymTab.BoolCheck(t2) THEN
                                            IF SymTab.BoolCheck(t2) THEN
@@ -3425,19 +3428,23 @@ PRODUCTIONS
      0..255 statically when foldable (222 otherwise), runtime trap
      0..255 statically when foldable (222 otherwise), runtime trap
      for computed elements. Ranges always lower via SetRange. *)
      for computed elements. Ranges always lower via SetRange. *)
   SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
   SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
+                                        (. VAR astNode: AST.Node; .)
     = "{"                               (. t := SymTab.NewSet(
     = "{"                               (. t := SymTab.NewSet(
                                              SymTab.NewSubR(0, 255));
                                              SymTab.NewSubR(0, 255));
+                                           astNode := AST.MakeNode(AST.NkSetLit);
                                            QbeGen.NewSetTemp(8, q);
                                            QbeGen.NewSetTemp(8, q);
                                            QbeGen.SetZero(q, 8); .)
                                            QbeGen.SetZero(q, 8); .)
-      [ SetElem<t, q> { "," SetElem<t, q> } ]
-      "}" .
+      [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
+      "}"                               (. astCur := astNode; .) .
   (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
   (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
      or ArrayName{...} (an array constructor, GNU Modula-2).  The
      or ArrayName{...} (an array constructor, GNU Modula-2).  The
      declared type sets the width (set) or element type (array). *)
      declared type sets the width (set) or element type (array). *)
   TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
   TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
                                         (. VAR nw: CARDINAL;
                                         (. VAR nw: CARDINAL;
+                                             astNode: AST.Node;
                                              savedCls: INTEGER; .)
                                              savedCls: INTEGER; .)
     = "{"                               (. savedCls := braceCls;
     = "{"                               (. savedCls := braceCls;
+                                           astNode := AST.MakeNode(AST.NkBraceLit);
                                            IF vt = SymTab.InvalidType THEN
                                            IF vt = SymTab.InvalidType THEN
                                              braceCls := -1
                                              braceCls := -1
                                            ELSE braceCls :=
                                            ELSE braceCls :=
@@ -3463,7 +3470,7 @@ PRODUCTIONS
                                                SemError(230) END;
                                                SemError(230) END;
                                              braceCls := -1
                                              braceCls := -1
                                            END; .)
                                            END; .)
-      [ BraceElem<vt, q> { "," BraceElem<vt, q> } ]
+      [ BraceElem<vt, q, astNode> { "," BraceElem<vt, q, astNode> } ]
       "}"                               (. IF (braceCls = SymTab.ClArray)
       "}"                               (. IF (braceCls = SymTab.ClArray)
                                               OR (braceCls =
                                               OR (braceCls =
                                                  SymTab.ClRecord)
                                                  SymTab.ClRecord)
@@ -3473,8 +3480,9 @@ PRODUCTIONS
                                            ELSIF braceCls # SymTab.ClSet THEN
                                            ELSIF braceCls # SymTab.ClSet THEN
                                              QbeGen.CopyOp("0", q)
                                              QbeGen.CopyOp("0", q)
                                            END;
                                            END;
-                                           braceCls := savedCls; .) .
-  BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal>
+                                           braceCls := savedCls; .)
+                                        (. astCur := astNode; .) .
+  BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal; node: AST.Node>
                                         (. VAR et, et2: SymTab.TypeIndex;
                                         (. VAR et, et2: SymTab.TypeIndex;
                                              qe, q2: QbeGen.QVal;
                                              qe, q2: QbeGen.QVal;
                                              v, v2, reps, k: INTEGER;
                                              v, v2, reps, k: INTEGER;
@@ -3482,10 +3490,13 @@ PRODUCTIONS
                                              lo: INTEGER;
                                              lo: INTEGER;
                                              span: CARDINAL;
                                              span: CARDINAL;
                                              cl, cl2: INTEGER;
                                              cl, cl2: INTEGER;
-                                             hasR, hasB: BOOLEAN; .)
+                                             hasR, hasB: BOOLEAN;
+                                             astEl: AST.Node; .)
     =                                   (. hasR := FALSE; hasB := FALSE; .)
     =                                   (. hasR := FALSE; hasB := FALSE; .)
-      Expr<et, qe>
-      [ ".." Expr<et2, q2>              (. hasR := TRUE; .) ]
+      Expr<et, qe> (. astEl := astCur; .)
+      [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
+                                             AST.NkSubrange, 0, astEl, astCur);
+                                           hasR := TRUE; .) ]
       [ "BY" Expr<et2, q2>              (. hasB := TRUE; .) ]
       [ "BY" Expr<et2, q2>              (. hasB := TRUE; .) ]
                                         (. IF braceCls = SymTab.ClSet THEN
                                         (. IF braceCls = SymTab.ClSet THEN
                                              IF hasB THEN SemError(230) END;
                                              IF hasB THEN SemError(230) END;
@@ -3551,17 +3562,22 @@ PRODUCTIONS
                                                QbeGen.CtorElem(qe);
                                                QbeGen.CtorElem(qe);
                                                INC(k)
                                                INC(k)
                                              END
                                              END
-                                           END; .) .
-  SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal>         (. VAR et, et2: SymTab.TypeIndex;
+                                           END; .)
+                                        (. AST.SetChild(node,
+                                             AST.NChild(node), astEl); .) .
+  SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node>         (. VAR et, et2: SymTab.TypeIndex;
                                              qe, q2: QbeGen.QVal;
                                              qe, q2: QbeGen.QVal;
                                              v, v2: INTEGER;
                                              v, v2: INTEGER;
                                              lo: INTEGER;
                                              lo: INTEGER;
                                              span: CARDINAL;
                                              span: CARDINAL;
                                              cl, cl2: INTEGER;
                                              cl, cl2: INTEGER;
-                                             hasR: BOOLEAN; .)
+                                             hasR: BOOLEAN;
+                                             astEl: AST.Node; .)
     =                                   (. hasR := FALSE; .)
     =                                   (. hasR := FALSE; .)
-      Expr<et, qe>
-      [ ".." Expr<et2, q2>              (. hasR := TRUE; .) ]
+      Expr<et, qe> (. astEl := astCur; .)
+      [ ".." Expr<et2, q2>              (. astEl := AST.MakeBin(
+                                             AST.NkSubrange, 0, astEl, astCur);
+                                           hasR := TRUE; .) ]
                                         (. lo := SymTab.SetBaseLo(st);
                                         (. lo := SymTab.SetBaseLo(st);
                                            span := SymTab.SetCount(st);
                                            span := SymTab.SetCount(st);
                                            IF (et = SymTab.InvalidType)
                                            IF (et = SymTab.InvalidType)
@@ -3604,7 +3620,9 @@ PRODUCTIONS
                                               ELSE QbeGen.SetBit(sq, qe,
                                               ELSE QbeGen.SetBit(sq, qe,
                                                 lo, span)
                                                 lo, span)
                                              END
                                              END
-                                           END; .) .
+                                           END; .)
+                                        (. AST.SetChild(node,
+                                             AST.NChild(node), astEl); .) .
   GetIdent<VAR n: SymTab.Name>
   GetIdent<VAR n: SymTab.Name>
     = ident                             (. LexName(n); .) .
     = ident                             (. LexName(n); .) .
 
 

File diff suppressed because it is too large
+ 748 - 730
compiler/src/M2.lst


+ 4 - 3
docs/plan-two-phase.md

@@ -92,9 +92,10 @@ Suggested slices, each ending in `build.sh` + `run_tests.sh` +
    `NkConstDecl`/`NkTypeDecl`/`NkVarDecl`/`NkProcDecl` (types referenced
    `NkConstDecl`/`NkTypeDecl`/`NkVarDecl`/`NkProcDecl` (types referenced
    by the node `ty` index); `astUnit` holds `NkUnit(name, decls, body)`
    by the node `ty` index); `astUnit` holds `NkUnit(name, decls, body)`
    for all three unit kinds; builtin statements build `NkCall`s.
    for all three unit kinds; builtin statements build `NkCall`s.
-   Deferred: imports, `CLASS`, nested modules in the unit AST; brace/set
-   literals and `ResultComp`; `Lower`.  Also
-   `docs/summary_two-phase-slice8.md` (`CASE`/`WITH`).
+   Deferred: imports, `CLASS`, nested modules in the unit AST;
+   `ResultComp`; `Lower`.  Also `docs/summary_two-phase-slice8.md`
+   (`CASE`/`WITH`) and `docs/summary_two-phase-slice9.md` (brace/set
+   literals).
 5. **Flip**: bodies lower from the AST; delete `FwdPatchAll` /
 5. **Flip**: bodies lower from the AST; delete `FwdPatchAll` /
    `FixLoadClass` / `FixStoreClass`, the `Design` forward-variable
    `FixLoadClass` / `FixStoreClass`, the `Design` forward-variable
    placeholder, and `pendVar*` if superseded.
    placeholder, and `pendVar*` if superseded.

+ 36 - 0
docs/summary_two-phase-slice9.md

@@ -0,0 +1,36 @@
+# Two-phase refactor — slice 9 (brace / set literals)
+
+Branch `ast-stage-c`.  Suite **178/178**; self-hosting fixpoint **OK**
+(**3,024,098 bytes**; slice 8 was 3,021,285).
+
+## What landed
+
+| Literal | AST |
+| --- | --- |
+| `{e, a..b}` | `NkSetLit(elements…)`, ranges as `NkSubrange` |
+| `T{e, …}` | `NkBraceLit(elements…)` |
+
+`SetLit`/`TypedBraceLit` create the node before their elements and pass
+it to `SetElem`/`BraceElem`, which append each element's node (a range
+becomes `NkSubrange`; a `BY` repeat keeps the value node).  `Fact` now
+keeps the brace node (`astBrace`) instead of discarding it, marking
+`astIsLit` so it survives the `Fact` reset; set literals likewise.
+
+## Verified (temporary `AST.Dump` of `astUnit`, then removed)
+
+```modula2
+b := {1, 3..5};
+b := BITSET{0, 2}
+```
+
+gave `NkSetLit(1, NkSubrange(3,5))` and `NkBraceLit(0, 2)`.
+
+## Deliberately deferred
+
+- `ResultComp` call-result suffixes (`F()[i]`, `F().f`, `F()^`).
+- Imports, `CLASS`, nested modules in the unit AST.
+- `Lower` + `.ssa` byte-compare.
+
+## Next
+
+`ResultComp`, then imports/`CLASS`/nested modules, then `Lower`.

Some files were not shown because too many files changed in this diff