فهرست منبع

two-phase slice 11: import AST nodes

Import builds NkImport (FROM module + names, or IMPORT module list);
ImpList/ImpName/ImpModList append to it.  Units store their imports as
NkUnit child 3 via the module-level astImp accumulator.  AST.IsLeafKind
drops NkImport so walks recurse into its NkIdent children.  Nodes are
inert.

Deferred: CLASS/nested modules, Lower.

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

See docs/summary_two-phase-slice11.md.
Eric Streit 1 هفته پیش
والد
کامیت
5610c57dd1
5فایلهای تغییر یافته به همراه1649 افزوده شده و 1586 حذف شده
  1. 0 1
      compiler/src/AST.mod
  2. 43 17
      compiler/src/M2.atg
  3. 1565 1565
      compiler/src/M2.lst
  4. 4 3
      docs/plan-two-phase.md
  5. 37 0
      docs/summary_two-phase-slice11.md

+ 0 - 1
compiler/src/AST.mod

@@ -246,7 +246,6 @@ PROCEDURE IsLeafKind (k : INTEGER) : BOOLEAN;
   BEGIN
   BEGIN
     RETURN (k = NkIdent) OR (k = NkIntLit) OR (k = NkRealLit)
     RETURN (k = NkIdent) OR (k = NkIntLit) OR (k = NkRealLit)
         OR (k = NkStrLit) OR (k = NkCharLit) OR (k = NkTypeIdent)
         OR (k = NkStrLit) OR (k = NkCharLit) OR (k = NkTypeIdent)
-        OR (k = NkImport)
   END IsLeafKind;
   END IsLeafKind;
 
 
 PROCEDURE Dump (n : Node; depth : CARDINAL);
 PROCEDURE Dump (n : Node; depth : CARDINAL);

+ 43 - 17
compiler/src/M2.atg

@@ -84,6 +84,10 @@ VAR
   (* Unit-AST root (slice 7): NkUnit(name, decls, body). *)
   (* Unit-AST root (slice 7): NkUnit(name, decls, body). *)
   astUnit: AST.Node;
   astUnit: AST.Node;
 
 
+  (* Import accumulator (slice 11): `{ Import }` appends NkImport
+     nodes here; each unit stores them as NkUnit child[3]. *)
+  astImp, astImpTail: AST.Node;
+
   (* Class of the method named by the last `obj.Method` designator
   (* Class of the method named by the last `obj.Method` designator
      (InvalidType when the callee is an ordinary procedure). Set by
      (InvalidType when the callee is an ordinary procedure). Set by
      Design, consumed by the following ArgList. *)
      Design, consumed by the following ArgList. *)
@@ -212,7 +216,9 @@ TOKENS
 
 
 PRODUCTIONS
 PRODUCTIONS
   M2
   M2
-    = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; astStmt := AST.NoNode; astDecl := AST.NoNode; .)
+    = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; astStmt := AST.NoNode; astDecl := AST.NoNode; astImp := AST.NoNode; astImpTail := AST.NoNode;
+                                           astImp := AST.NoNode;
+                                           astImpTail := AST.NoNode; .)
       Unit "." .
       Unit "." .
   (* Units: program modules compile fully; DEFINITION and
   (* Units: program modules compile fully; DEFINITION and
      IMPLEMENTATION modules parse + check now but lower in step 4
      IMPLEMENTATION modules parse + check now but lower in step 4
@@ -230,7 +236,8 @@ PRODUCTIONS
                                              SemError(200) END;
                                              SemError(200) END;
                                            QbeGen.SetModule(m1); .)
                                            QbeGen.SetModule(m1); .)
       ";"
       ";"
-      { Import }
+      { Import                        (. AstAppend(AST.NkDeclSeq,
+                                             astImp, astImpTail, astDecl); .) }
       [ "EXPORT" [ "QUALIFIED" ]        (. (* definition-module export
       [ "EXPORT" [ "QUALIFIED" ]        (. (* definition-module export
                                               list: parsed, and the
                                               list: parsed, and the
                                               names are already exported
                                               names are already exported
@@ -243,6 +250,8 @@ PRODUCTIONS
                                         (. astUnit := AST.MakeNode(AST.NkUnit);
                                         (. astUnit := AST.MakeNode(AST.NkUnit);
                                            AST.SetChild(astUnit, 0,
                                            AST.SetChild(astUnit, 0,
                                              AST.MakeLeaf(AST.NkIdent, m1));
                                              AST.MakeLeaf(AST.NkIdent, m1));
+                                           AST.SetChild(astUnit, 1, astDecl);
+                                           AST.SetChild(astUnit, 3, astImp);
                                            astDecl := AST.NoNode;
                                            astDecl := AST.NoNode;
                                            astStmt := AST.NoNode; .)
                                            astStmt := AST.NoNode; .)
       "END"
       "END"
@@ -259,10 +268,13 @@ PRODUCTIONS
                                              SemError(201) END;
                                              SemError(201) END;
                                            astStmt := AST.NoNode;
                                            astStmt := AST.NoNode;
                                            astDecl := AST.NoNode;
                                            astDecl := AST.NoNode;
+                                           astImp := AST.NoNode;
+                                           astImpTail := AST.NoNode;
                                            nPendVar := 0;
                                            nPendVar := 0;
                                            QbeGen.SetModule(m1); .)
                                            QbeGen.SetModule(m1); .)
       ";"
       ";"
-      { Import }
+      { Import                        (. AstAppend(AST.NkDeclSeq,
+                                             astImp, astImpTail, astDecl); .) }
       DeclSeq
       DeclSeq
       [ "BEGIN"                         (. FlushPend;
       [ "BEGIN"                         (. FlushPend;
                                            k := 0;
                                            k := 0;
@@ -290,6 +302,7 @@ PRODUCTIONS
                                              AST.MakeLeaf(AST.NkIdent, m1));
                                              AST.MakeLeaf(AST.NkIdent, m1));
                                            AST.SetChild(astNode, 1, astDecl);
                                            AST.SetChild(astNode, 1, astDecl);
                                            AST.SetChild(astNode, 2, astStmt);
                                            AST.SetChild(astNode, 2, astStmt);
+                                           AST.SetChild(astNode, 3, astImp);
                                            astUnit := astNode;
                                            astUnit := astNode;
                                            IF NOT SymTab.Equal(m1, m2) THEN
                                            IF NOT SymTab.Equal(m1, m2) THEN
                                              SemError(202) END;
                                              SemError(202) END;
@@ -304,11 +317,14 @@ PRODUCTIONS
                                              SemError(200) END;
                                              SemError(200) END;
                                            astStmt := AST.NoNode;
                                            astStmt := AST.NoNode;
                                            astDecl := AST.NoNode;
                                            astDecl := AST.NoNode;
+                                           astImp := AST.NoNode;
+                                           astImpTail := AST.NoNode;
                                            nPendVar := 0;
                                            nPendVar := 0;
                                            QbeGen.SetModule(m1); .)
                                            QbeGen.SetModule(m1); .)
       [ Priority ]
       [ Priority ]
       ";"
       ";"
-      { Import }
+      { Import                        (. AstAppend(AST.NkDeclSeq,
+                                             astImp, astImpTail, astDecl); .) }
       DeclSeq
       DeclSeq
       [ "BEGIN"                         (. FlushPend;
       [ "BEGIN"                         (. FlushPend;
                                            k := 0;
                                            k := 0;
@@ -338,6 +354,7 @@ PRODUCTIONS
                                              AST.MakeLeaf(AST.NkIdent, m1));
                                              AST.MakeLeaf(AST.NkIdent, m1));
                                            AST.SetChild(astNode, 1, astDecl);
                                            AST.SetChild(astNode, 1, astDecl);
                                            AST.SetChild(astNode, 2, astStmt);
                                            AST.SetChild(astNode, 2, astStmt);
+                                           AST.SetChild(astNode, 3, astImp);
                                            astUnit := astNode;
                                            astUnit := astNode;
                                            QbeGen.EndModule(m1);
                                            QbeGen.EndModule(m1);
                                            SymTab.EndUnit; .) .
                                            SymTab.EndUnit; .) .
@@ -391,20 +408,27 @@ PRODUCTIONS
   (* Unknown modules stay unchecked stubs (legacy, so hand-written
   (* Unknown modules stay unchecked stubs (legacy, so hand-written
      import lines don't fail); a known module's missing export is
      import lines don't fail); a known module's missing export is
      201. *)
      201. *)
-  Import                                (. VAR n: SymTab.Name; .)
+  Import                                (. VAR n: SymTab.Name;
+                                             astImport: AST.Node; .)
     = "FROM"
     = "FROM"
-      GetIdent<n>
+      GetIdent<n>                       (. astImport := AST.MakeNode(AST.NkImport);
+                                           AST.SetChild(astImport, 0,
+                                             AST.MakeLeaf(AST.NkIdent, n)); .)
       "IMPORT"
       "IMPORT"
-      ImpList<n> ";"
-    | "IMPORT"
-      ImpModList ";" .
-  ImpList<mod: SymTab.Name>             (. VAR n: SymTab.Name; .)
-    = ImpName<mod>
-      { "," ImpName<mod> } .
+      ImpList<n, astImport> ";"         (. astDecl := astImport; .)
+    | "IMPORT"                          (. astImport := AST.MakeNode(AST.NkImport); .)
+      ImpModList<astImport> ";"         (. astDecl := astImport; .) .
+  ImpList<mod: SymTab.Name; node: AST.Node>
+                                        (. VAR n: SymTab.Name; .)
+    = ImpName<mod, node>
+      { "," ImpName<mod, node> } .
   (* Pervasive built-ins imported from SYSTEM (e.g. TSIZE) are
   (* Pervasive built-ins imported from SYSTEM (e.g. TSIZE) are
      accepted and ignored: the built-in applies regardless. *)
      accepted and ignored: the built-in applies regardless. *)
-  ImpName<mod: SymTab.Name>             (. VAR n: SymTab.Name; .)
-    = GetIdent<n>                       (. IF SymTab.Equal(mod, "libc") THEN
+  ImpName<mod: SymTab.Name; node: AST.Node>
+                                        (. VAR n: SymTab.Name; .)
+    = GetIdent<n> (. AST.SetChild(node, AST.NChild(node),
+                                             AST.MakeLeaf(AST.NkIdent, n));
+                                           IF SymTab.Equal(mod, "libc") THEN
                                              (* intrinsic C library:
                                              (* intrinsic C library:
                                                 permissive external *)
                                                 permissive external *)
                                              IF NOT SymTab.DeclareCProc(n) THEN
                                              IF NOT SymTab.DeclareCProc(n) THEN
@@ -416,9 +440,11 @@ PRODUCTIONS
       | "CHR" | "ORD" | "ORDL" | "VAL" | "ABS" | "CAP"
       | "CHR" | "ORD" | "ORDL" | "VAL" | "ABS" | "CAP"
       | "UCHR" | "CHR8" | "UORD"
       | "UCHR" | "CHR8" | "UORD"
       | "INC" | "DEC" ) .
       | "INC" | "DEC" ) .
-  ImpModList                            (. VAR n: SymTab.Name; .)
-    = GetIdent<n>
-      { "," GetIdent<n> } .
+  ImpModList<node: AST.Node>            (. VAR n: SymTab.Name; .)
+    = GetIdent<n>                       (. AST.SetChild(node, AST.NChild(node),
+                                             AST.MakeLeaf(AST.NkIdent, n)); .)
+      { "," GetIdent<n>                 (. AST.SetChild(node, AST.NChild(node),
+                                             AST.MakeLeaf(AST.NkIdent, n)); .) } .
   (* Opaque TYPE declarations (definition modules). The targetless
   (* Opaque TYPE declarations (definition modules). The targetless
      alias resolves to InvalidType until step 4 completes it. *)
      alias resolves to InvalidType until step 4 completes it. *)
   (* Scalar-phase TYPEs: named types, integer subranges, enumerations.
   (* Scalar-phase TYPEs: named types, integer subranges, enumerations.

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1565 - 1565
compiler/src/M2.lst


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

@@ -92,11 +92,12 @@ 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; `Lower`.
+   Deferred: `CLASS`, nested modules in the unit AST; `Lower`.
    Also `docs/summary_two-phase-slice8.md` (`CASE`/`WITH`),
    Also `docs/summary_two-phase-slice8.md` (`CASE`/`WITH`),
-   `docs/summary_two-phase-slice9.md` (brace/set literals) and
+   `docs/summary_two-phase-slice9.md` (brace/set literals),
    `docs/summary_two-phase-slice10.md` (`ResultComp` + unbounded
    `docs/summary_two-phase-slice10.md` (`ResultComp` + unbounded
-   `NkBlock`/`NkDeclSeq`).
+   `NkBlock`/`NkDeclSeq`) and `docs/summary_two-phase-slice11.md`
+   (imports).
 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.

+ 37 - 0
docs/summary_two-phase-slice11.md

@@ -0,0 +1,37 @@
+# Two-phase refactor — slice 11 (imports)
+
+Branch `ast-stage-c`.  Suite **178/178**; self-hosting fixpoint **OK**
+(**3,032,308 bytes**; slice 10 was 3,027,925).
+
+## What landed
+
+`NkImport` nodes.  `Import` builds a node whose child 0 is the
+`FROM` module (`NkIdent`) and whose following children are the imported
+names; a plain `IMPORT` collects the module names as children.
+`ImpList`/`ImpName`/`ImpModList` take the node as a parameter and append
+to it.  The module-level `astImp`/`astImpTail` accumulator collects the
+imports of a unit; each `NkUnit` stores them as **child 3**.
+
+`AST.IsLeafKind` no longer lists `NkImport`, so a tree walk recurses into
+its `NkIdent` children instead of mis-reading child 0 as a text index.
+
+## Verified (temporary `AST.Dump`, then removed)
+
+```modula2
+FROM TestIO IMPORT WriteString, WriteLn;
+```
+
+gave `NkUnit(impdump, decls, body, imports=NkDeclSeq[
+  NkImport(NkIdent TestIO, NkIdent WriteString, NkIdent WriteLn) ])`.
+
+## Deliberately deferred
+
+- `CLASS` / `CLASS IMPLEMENTATION` items and nested modules in the unit
+  AST.
+- `Lower` + `.ssa` byte-compare.
+- The `MaxChild` cap still applies to `CASE` arms, `WITH` designators and
+  call actuals.
+
+## Next
+
+`CLASS`/nested modules (or move to `Lower`).

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است