summaryrefslogtreecommitdiff
path: root/chapter28b/src/main/java/com/seaofnodes
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-27 15:47:43 -0700
committerCliff Click <cliffc@acm.org>2026-10-27 15:47:43 -0700
commit0bf3ce826ca0546b08f9d7a513930017fcf63f89 (patch)
tree4d93a5ab433a487908f2fa711714e627e86e98f8 /chapter28b/src/main/java/com/seaofnodes
parent615eb0cf4545d354dc0889d76ec60b6b18ef9e7a (diff)
downloadSimple-0bf3ce826ca0546b08f9d7a513930017fcf63f89.tar.gz
Simple-0bf3ce826ca0546b08f9d7a513930017fcf63f89.zip
Gather types during loading instead another walk
Diffstat (limited to 'chapter28b/src/main/java/com/seaofnodes')
-rw-r--r--chapter28b/src/main/java/com/seaofnodes/simple/Parser.java6
-rw-r--r--chapter28b/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java8
-rw-r--r--chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java10
3 files changed, 9 insertions, 15 deletions
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<FRefNode> _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<String> _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<String> 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 )