summaryrefslogtreecommitdiff
path: root/chapter17/src
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-11-15 14:53:39 -0800
committerCliff Click <cliffc@acm.org>2024-11-23 09:03:20 -0800
commite24a4246190fc8e5785f36427c79100575139e3c (patch)
tree3d3945e96faba041ceb5e05f6f8700aff8039334 /chapter17/src
parent73d293a89d8f8b5188ee2406ce24a1fef96f062f (diff)
downloadSimple-e24a4246190fc8e5785f36427c79100575139e3c.tar.gz
Simple-e24a4246190fc8e5785f36427c79100575139e3c.zip
Straighten out nested forward ref type errors
Diffstat (limited to 'chapter17/src')
-rw-r--r--chapter17/src/main/java/com/seaofnodes/simple/Parser.java27
-rw-r--r--chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java23
2 files changed, 33 insertions, 17 deletions
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
index c144b1d7..2e707096 100644
--- a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
@@ -666,24 +666,22 @@ public class Parser {
return posT(old1);
Type t1 = t0 == null ? TypeMemPtr.make(TypeStruct.makeFRef(tname)) : t0; // Null: assume a forward ref type
// Nest arrays and '?' as needed
+ Type t2 = t1;
while( true ) {
- assert !(t1 instanceof TypeStruct);
+ assert !(t2 instanceof TypeStruct);
if( match("?") ) {
- if( !(t1 instanceof TypeMemPtr tmp) )
+ if( !(t2 instanceof TypeMemPtr tmp) )
throw error("Type "+t0+" cannot be null");
- if( tmp._nil ) throw error("Type "+t1+" already allows null");
- t1 = TypeMemPtr.make(tmp._obj,true);
- continue;
- }
- if( match("[]") ) {
- t1 = typeAry(t1);
- continue;
- }
- break;
+ if( tmp._nil ) throw error("Type "+t2+" already allows null");
+ t2 = TypeMemPtr.make(tmp._obj,true);
+ } else if( match("[]") ) {
+ t2 = typeAry(t2);
+ } else
+ break;
}
// Check no forward ref
- if( t0 != null ) return t1;
+ if( t0 != null ) return t2;
// Check valid forward ref, after parsing all the type extra bits.
// Cannot check earlier, because cannot find required 'id' until after "[]?" syntax
int old2 = pos();
@@ -692,9 +690,8 @@ public class Parser {
if( id==null )
return posT(old1); // Reset lexer to reparse
// Yes a forward ref, so declare it
- Type t2 = t1 instanceof TypeMemPtr tmp ? tmp.makeFrom(false): t1;
- TYPES.put(tname,t2);
- return t1;
+ TYPES.put(tname,t1);
+ return t2;
}
// Make an array type of t
diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java
index 516da849..44538965 100644
--- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java
+++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java
@@ -12,7 +12,12 @@ public class Chapter17Test {
@Test
public void testJig() {
Parser parser = new Parser("""
-return 3.14;
+struct A { int i; };
+A! a = new A;
+a.i=a;
+a.i=2;
+return a;
+ //return 3.14;
""");
StopNode stop = parser.parse().iterate();
assertEquals("return 3.14;", stop.toString());
@@ -369,7 +374,7 @@ for(;;arg++;) {}
// ---------------------------------------------------------------
@Test
- public void testForward() {
+ public void testForward0() {
Parser parser = new Parser("""
struct A{
B? f1;
@@ -382,6 +387,20 @@ return new A;
assertEquals("Obj<A>{f1=null,f2=null}", Evaluator.evaluate(stop).toString());
}
+ @Test
+ public void testForward1() {
+ Parser parser = new Parser("""
+struct A{
+ B?[]? nil_array_of_b;
+ B?[] not_array_of_b = new B?[0];
+};
+return new A.not_array_of_b;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return (const)[*B?];", stop.toString());
+ assertEquals("Obj<[*B?]>{#=0,[]=[]}", Evaluator.evaluate(stop).toString());
+ }
+
// ---------------------------------------------------------------
@Test
public void testLinkedList2() {