summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-11-15 13:36:11 -0800
committerCliff Click <cliffc@acm.org>2024-11-23 09:03:20 -0800
commitc19c4a27f29bbc5a4befb4f0931da74c9138c808 (patch)
tree1557448987d35b534166d7e32538ae81b685bd0f
parentb8d64b4c4c7b83794b5317a3d1135be38cd88ac8 (diff)
downloadSimple-c19c4a27f29bbc5a4befb4f0931da74c9138c808.tar.gz
Simple-c19c4a27f29bbc5a4befb4f0931da74c9138c808.zip
Fix 2 small bugs
-rw-r--r--chapter17/src/main/java/com/seaofnodes/simple/Parser.java6
-rw-r--r--chapter17/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java1
-rw-r--r--chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java24
3 files changed, 29 insertions, 2 deletions
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
index 47e7c3bb..dae3cd54 100644
--- a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java
@@ -335,7 +335,8 @@ public class Parser {
int old = pos(nextPos);
if( !peek(')') )
parseAsgn(null,false);
- assert pos() == nextEnd;
+ if( pos() != nextEnd )
+ throw errorSyntax( "Unexpected code after expression" );
pos(old);
}
@@ -691,7 +692,8 @@ public class Parser {
if( id==null )
return posT(old1); // Reset lexer to reparse
// Yes a forward ref, so declare it
- TYPES.put(tname,t1);
+ Type t2 = t1 instanceof TypeMemPtr tmp ? tmp.makeFrom(false): t1;
+ TYPES.put(tname,t2);
return t1;
}
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java b/chapter17/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java
index 08e7db1c..786a7be5 100644
--- a/chapter17/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java
+++ b/chapter17/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java
@@ -34,6 +34,7 @@ public class TypeMemPtr extends Type {
public static TypeMemPtr make(TypeStruct obj, boolean nil) { return new TypeMemPtr(obj, nil).intern(); }
public static TypeMemPtr make(TypeStruct obj) { return make(obj, false); }
public TypeMemPtr makeFrom(TypeStruct obj) { return obj==_obj ? this : make(obj, _nil); }
+ public TypeMemPtr makeFrom(boolean nil) { return nil==_nil ? this : make(_obj, nil); }
@Override public TypeMemPtr makeRO() { return makeFrom(_obj.makeRO()); }
@Override public boolean isFinal() { return _obj.isFinal(); }
diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java
index 176a9236..516da849 100644
--- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java
+++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java
@@ -356,7 +356,31 @@ return i;
try { parser.parse().iterate(); fail(); }
catch( Exception e ) { assertEquals("Undefined name 'i'",e.getMessage()); }
}
+ @Test
+ public void testFor5() {
+ Parser parser = new Parser("""
+for(;;arg++;) {}
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Syntax error, expected Unexpected code after expression: ;",e.getMessage()); }
+ }
+
+
+ // ---------------------------------------------------------------
+ @Test
+ public void testForward() {
+ Parser parser = new Parser("""
+struct A{
+ B? f1;
+ B? f2;
+};
+return new A;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return A;", stop.toString());
+ assertEquals("Obj<A>{f1=null,f2=null}", Evaluator.evaluate(stop).toString());
+ }
// ---------------------------------------------------------------
@Test