From 0bf3ce826ca0546b08f9d7a513930017fcf63f89 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Tue, 27 Oct 2026 15:47:43 -0700 Subject: Gather types during loading instead another walk --- chapter28b/src/main/java/com/seaofnodes/simple/Parser.java | 6 ++++++ .../src/main/java/com/seaofnodes/simple/codegen/CodeGen.java | 8 -------- .../src/main/java/com/seaofnodes/simple/codegen/ParseAll.java | 10 +++------- 3 files changed, 9 insertions(+), 15 deletions(-) (limited to 'chapter28b/src/main/java') diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java b/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java index b9cd9658..8410bf5c 100644 --- a/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java @@ -101,6 +101,9 @@ public class Parser { ScopeNode _continueScope; // Merge all the while-continues here ScopeNode _returnScope; // Merge all the function exits here Ary _frefs; // Forward refs created during this parse + // Layouts needed by field accesses in this source file. Resolve after + // parsing, since a later local struct declaration can satisfy the use. + public final LinkedHashSet _requiredTypes = new LinkedHashSet<>(); TypeStruct _ctorOpenStruct; // Open struct being initialized by an allocation constructor block. // Constructor exit types survive scope teardown until all fields are known. // A null entry denotes a constructor with no returning path. @@ -171,6 +174,7 @@ public class Parser { assert _frefs == null; _lexer = new Lexer(ref); _frefs = new Ary<>(FRefNode.class); + _requiredTypes.clear(); // Starting Scope has control, memory, initial arguments _scope = new ScopeNode(); _scope.define(ScopeNode.CTRL, Type.CONTROL , false, null, _lexer); @@ -2751,6 +2755,8 @@ public class Parser { } // Field offset for an unknown type public Node fldoff( Node n, String name ) { + if( n._type instanceof TypeMemPtr ptr && ptr._obj._fref ) + _requiredTypes.add(ptr._obj._name); return new FldOffNode(n,name,loc()).peephole(); } public Node peep( Node n ) { diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java index c2cd657f..561fdece 100644 --- a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java +++ b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java @@ -625,14 +625,6 @@ public class CodeGen { // Last check for bad programs public CodeGen typeCheck() { return phase(Phase.TypeCheck, _phase==Phase.FinalizeIR, () -> TypeCheck.run(this)); } - public static TypeStruct requiredStruct(Node n) { - // CNC: remove? cleanup? - if( n instanceof NewNode alloc ) return alloc._ts; - if( n instanceof ConFldOffNode off ) return off._ts; - if( n instanceof FldOffNode off && off.in(0)._type instanceof TypeMemPtr ptr ) return ptr._obj; - return null; - } - // --------------------------- // TypeCheck queued surviving CLInits during its existing error walk. public CodeGen lower() { diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java index 10b8fd9b..1d9731fc 100644 --- a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java +++ b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java @@ -198,13 +198,9 @@ public abstract class ParseAll { } private static void addRequiredTypes(CodeGen code, CompUnit cunit) { - LinkedHashSet required = new LinkedHashSet<>(); - code._stop.walk(n -> { - TypeStruct ts = CodeGen.requiredStruct(n); - if( ts!=null && ts._fref ) required.add(ts._name); - return null; - }); - for( String typeName : required ) { + for( String typeName : code.P._requiredTypes ) { + // A forward use can have been resolved later in this source file. + if( Parser.TYPES.get(typeName) instanceof TypeStruct ts && !ts._fref ) continue; try { CompUnit xcunit = findRequiredType(code,cunit,typeName); if( xcunit != null ) -- cgit v1.2.3