diff options
17 files changed, 351 insertions, 228 deletions
diff --git a/chapter03/src/main/java/com/seaofnodes/simple/Parser.java b/chapter03/src/main/java/com/seaofnodes/simple/Parser.java index 90fcbd27..fa1a852c 100644 --- a/chapter03/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter03/src/main/java/com/seaofnodes/simple/Parser.java @@ -93,6 +93,7 @@ public class Parser { else if (matchx("int")) return parseDecl(); else if (match ("{" )) return require(parseBlock(),"}"); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";")) return null; // Empty statement else return parseExpressionStatement(); } diff --git a/chapter04/src/main/java/com/seaofnodes/simple/Parser.java b/chapter04/src/main/java/com/seaofnodes/simple/Parser.java index e75567a5..ff2c0504 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/Parser.java @@ -114,6 +114,7 @@ public class Parser { else if (matchx("int")) return parseDecl(); else if (match ("{" )) return require(parseBlock(),"}"); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";")) return null; // Empty statement else return parseExpressionStatement(); } diff --git a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java index 0fd52788..80674d59 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java @@ -135,6 +135,7 @@ public class Parser { else if (match ("{" )) return require(parseBlock(),"}"); else if (matchx("if" )) return parseIf(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";")) return null; // Empty statement else return parseExpressionStatement(); } diff --git a/chapter06/src/main/java/com/seaofnodes/simple/Parser.java b/chapter06/src/main/java/com/seaofnodes/simple/Parser.java index 5a844f0e..1a15efa3 100644 --- a/chapter06/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter06/src/main/java/com/seaofnodes/simple/Parser.java @@ -135,6 +135,7 @@ public class Parser { else if (match ("{" )) return require(parseBlock(),"}"); else if (matchx("if" )) return parseIf(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";")) return null; // Empty statement else return parseExpressionStatement(); } diff --git a/chapter07/src/main/java/com/seaofnodes/simple/Parser.java b/chapter07/src/main/java/com/seaofnodes/simple/Parser.java index ecca0618..cfb4deb4 100644 --- a/chapter07/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter07/src/main/java/com/seaofnodes/simple/Parser.java @@ -137,6 +137,7 @@ public class Parser { else if (matchx("if" )) return parseIf(); else if (matchx("while")) return parseWhile(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";")) return null; // Empty statement else return parseExpressionStatement(); } diff --git a/chapter08/Makefile b/chapter08/Makefile index 56f69e12..3c271042 100644 --- a/chapter08/Makefile +++ b/chapter08/Makefile @@ -36,7 +36,7 @@ main_javas := $(wildcard $(SRC)/$(SIMPLE)/*java $(SRC)/$(SIMPLE)/*/*java) test_javas := $(wildcard $(TST)/$(SIMPLE)/*java $(TST)/$(SIMPLE)/*/*java) main_classes := $(patsubst $(SRC)/%java,$(CLZDIR)/main/%class,$(main_javas)) test_classes := $(patsubst $(TST)/%java,$(CLZDIR)/test/%class,$(test_javas)) -test_cp := $(patsubst $(TST)/$(SIMPLE)/%.java,com.seaofnodes.simple.%,$(test_javas)) +test_cp := $(patsubst $(TST)/$(SIMPLE)/%.java,com.seaofnodes.simple.%,$(wildcard $(TST)/$(SIMPLE)/*Test.java)) classes = $(main_classes) $(test_classes) # All the libraries libs = $(wildcard lib/*jar) diff --git a/chapter08/src/main/java/com/seaofnodes/simple/Parser.java b/chapter08/src/main/java/com/seaofnodes/simple/Parser.java index 47e7c2c4..69796828 100644 --- a/chapter08/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter08/src/main/java/com/seaofnodes/simple/Parser.java @@ -145,6 +145,7 @@ public class Parser { else if (matchx("break")) return parseBreak(); else if (matchx("continue")) return parseContinue(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";")) return null; // Empty statement else return parseExpressionStatement(); } diff --git a/chapter09/src/main/java/com/seaofnodes/simple/Parser.java b/chapter09/src/main/java/com/seaofnodes/simple/Parser.java index 1827bae2..aabdf63a 100644 --- a/chapter09/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter09/src/main/java/com/seaofnodes/simple/Parser.java @@ -145,6 +145,7 @@ public class Parser { else if (matchx("break")) return parseBreak(); else if (matchx("continue")) return parseContinue(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";")) return null; // Empty statement else return parseExpressionStatement(); } diff --git a/chapter10/src/main/java/com/seaofnodes/simple/Parser.java b/chapter10/src/main/java/com/seaofnodes/simple/Parser.java index dbb2d172..fc84c9d9 100644 --- a/chapter10/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter10/src/main/java/com/seaofnodes/simple/Parser.java @@ -154,6 +154,7 @@ public class Parser { else if (matchx("continue")) return parseContinue(); else if (matchx("struct") ) return parseStruct(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";") ) return null; // Empty statement // declarations of vars with struct type are handled in parseExpressionStatement due // to ambiguity else return parseExpressionStatement(); diff --git a/chapter11/src/main/java/com/seaofnodes/simple/Parser.java b/chapter11/src/main/java/com/seaofnodes/simple/Parser.java index 7e957d9d..e614d463 100644 --- a/chapter11/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter11/src/main/java/com/seaofnodes/simple/Parser.java @@ -165,6 +165,7 @@ public class Parser { else if (matchx("continue")) return parseContinue(); else if (matchx("struct") ) return parseStruct(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";") ) return null; // Empty statement // declarations of vars with struct type are handled in parseExpressionStatement due // to ambiguity else return parseExpressionStatement(); diff --git a/chapter12/src/main/java/com/seaofnodes/simple/Parser.java b/chapter12/src/main/java/com/seaofnodes/simple/Parser.java index 9182a74c..e919449f 100644 --- a/chapter12/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter12/src/main/java/com/seaofnodes/simple/Parser.java @@ -167,6 +167,7 @@ public class Parser { else if (matchx("continue")) return parseContinue(); else if (matchx("struct") ) return parseStruct(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";") ) return null; // Empty statement // declarations of vars with struct type are handled in parseExpressionStatement due // to ambiguity else return parseExpressionStatement(); diff --git a/chapter13/src/main/java/com/seaofnodes/simple/Parser.java b/chapter13/src/main/java/com/seaofnodes/simple/Parser.java index fee5215e..f04bf5c3 100644 --- a/chapter13/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter13/src/main/java/com/seaofnodes/simple/Parser.java @@ -167,6 +167,7 @@ public class Parser { else if (matchx("continue")) return parseContinue(); else if (matchx("struct") ) return parseStruct(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";") ) return null; // Empty statement // declarations of vars with struct type are handled in parseExpressionStatement due // to ambiguity else return parseExpressionStatement(); @@ -190,7 +191,7 @@ public class Parser { * Only allowed in top level scope. * Structs cannot be redefined. * - * @return The statement following the struct + * @return null */ private Node parseStruct() { if (_xScopes.size() > 1) throw errorSyntax("struct declarations can only appear in top level scope"); @@ -209,7 +210,7 @@ public class Parser { TypeStruct ts = TypeStruct.make(typeName, fields); TYPES.put(typeName, ts); START.addMemProj(ts, _scope); // Insert memory edges - return parseStatement(); + return null; } /** @@ -579,7 +580,8 @@ public class Parser { if( matchx("new") ) { String structName = requireId(); Type t = TYPES.get(structName); - if( t == null || !(t instanceof TypeStruct obj) ) throw errorSyntax("Unknown struct type '" + structName + "'"); + if( !(t instanceof TypeStruct obj) || obj._fields==null ) + throw error("Unknown struct type '" + structName + "'"); return newStruct(obj); } String name = _lexer.matchId(); diff --git a/chapter13/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/chapter13/src/test/java/com/seaofnodes/simple/Chapter12Test.java index 8eceb0fa..f711607b 100644 --- a/chapter13/src/test/java/com/seaofnodes/simple/Chapter12Test.java +++ b/chapter13/src/test/java/com/seaofnodes/simple/Chapter12Test.java @@ -60,115 +60,4 @@ return x+1==x; assertEquals(0L, Evaluator.evaluate(stop, 1)); } - - @Test - public void testLinkedList0() { - Parser parser = new Parser( -""" -struct LLI { LLI? next; int i; } -LLI? head = null; -while( arg ) { - LLI x = new LLI; - x.next = head; - x.i = arg; - head = x; - arg = arg-1; -} -return head.next.i; -"""); - try { parser.parse(true).iterate(true); fail(); } - catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); } - } - - @Test - public void testLinkedList1() { - Parser parser = new Parser( -""" -struct LLI { LLI? next; int i; } -LLI? head = null; -while( arg ) { - LLI x = new LLI; - x.next = head; - x.i = arg; - head = x; - arg = arg-1; -} -if( !head ) return 0; -LLI? next = head.next; -if( next==null ) return 1; -return next.i; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("Stop[ return 0; return 1; return .i; ]", stop.toString()); - assertEquals(2L, Evaluator.evaluate(stop, 3)); - } - - @Test - public void testCoRecur() { - Parser parser = new Parser( -""" -struct int0 { int i; flt0? f; } -struct flt0 { flt f; int0? i; } -int0 i0 = new int0; -i0.i = 17; -flt0 f0 = new flt0; -f0.f = 3.14; -i0.f = f0; -f0.i = i0; -return f0.i.f.i.i; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return 17;", stop.toString()); - } - - @Test - public void testNullRef0() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -return n.next; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return null;", stop.toString()); - } - - @Test - public void testNullRef1() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -n.next = new N; -return n.next; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return new N;", stop.toString()); - } - - @Test - public void testNullRef2() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -n.next = null; -return n.next; -"""); - try { parser.parse(true).iterate(true); fail(); } - catch( Exception e ) { assertEquals("Cannot store null into field *N next",e.getMessage()); } - } - - @Test - public void testNullRef3() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -n.i = 3.14; -return n.i; -"""); - try { parser.parse(true).iterate(true); fail(); } - catch( Exception e ) { assertEquals("Cannot store 3.14 into field IntBot i",e.getMessage()); } - } } diff --git a/chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java new file mode 100644 index 00000000..f7d4d5a8 --- /dev/null +++ b/chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java @@ -0,0 +1,166 @@ +package com.seaofnodes.simple; + +import com.seaofnodes.simple.evaluator.Evaluator; +import com.seaofnodes.simple.node.StopNode; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class Chapter13Test { + @Test + public void testJig() { + Parser parser = new Parser( +""" +return 3.14; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return 3.14;", stop.toString()); + assertEquals(3.14, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testLinkedList0() { + Parser parser = new Parser( +""" +struct LLI { LLI? next; int i; } +LLI? head = null; +while( arg ) { + LLI x = new LLI; + x.next = head; + x.i = arg; + head = x; + arg = arg-1; +} +return head.next.i; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); } + } + + @Test + public void testLinkedList1() { + Parser parser = new Parser( +""" +struct LLI { LLI? next; int i; } +LLI? head = null; +while( arg ) { + LLI x = new LLI; + x.next = head; + x.i = arg; + head = x; + arg = arg-1; +} +if( !head ) return 0; +LLI? next = head.next; +if( next==null ) return 1; +return next.i; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("Stop[ return 0; return 1; return .i; ]", stop.toString()); + assertEquals(2L, Evaluator.evaluate(stop, 3)); + } + + @Test + public void testCoRecur() { + Parser parser = new Parser( +""" +struct int0 { int i; flt0? f; } +struct flt0 { flt f; int0? i; } +int0 i0 = new int0; +i0.i = 17; +flt0 f0 = new flt0; +f0.f = 3.14; +i0.f = f0; +f0.i = i0; +return f0.i.f.i.i; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return 17;", stop.toString()); + } + + @Test + public void testNullRef0() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +return n.next; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return null;", stop.toString()); + } + + @Test + public void testNullRef1() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +n.next = new N; +return n.next; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return new N;", stop.toString()); + } + + @Test + public void testNullRef2() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +n.next = null; +return n.next; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Cannot store null into field *N next",e.getMessage()); } + } + + @Test + public void testNullRef3() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +n.i = 3.14; +return n.i; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Cannot store 3.14 into field IntBot i",e.getMessage()); } + } + + @Test + public void testEmpty() { + Parser parser = new Parser( +""" +struct S{}; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return 0;", stop.toString()); + assertEquals(0L, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testForwardRef0() { + Parser parser = new Parser( +""" +struct S1 { S2 s; } +return new S2; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Unknown struct type 'S2'",e.getMessage()); } + } + + @Test + public void testForwardRef1() { + Parser parser = new Parser( +""" +struct S1 { S2? s; } +struct S2 { int x; } +return new S1.s=new S2; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return new S1;", stop.toString()); + } +} diff --git a/chapter14/src/main/java/com/seaofnodes/simple/Parser.java b/chapter14/src/main/java/com/seaofnodes/simple/Parser.java index 5720ff8b..b249b0a4 100644 --- a/chapter14/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter14/src/main/java/com/seaofnodes/simple/Parser.java @@ -181,6 +181,7 @@ public class Parser { else if (matchx("continue")) return parseContinue(); else if (matchx("struct") ) return parseStruct(); else if (matchx("#showGraph")) return require(showGraph(),";"); + else if (matchx(";") ) return null; // Empty statement // declarations of vars with struct type are handled in parseExpressionStatement due // to ambiguity else return parseExpressionStatement(); @@ -637,7 +638,8 @@ public class Parser { if( matchx("new") ) { String structName = requireId(); Type t = TYPES.get(structName); - if( t == null || !(t instanceof TypeStruct obj) ) throw errorSyntax("Unknown struct type '" + structName + "'"); + if( !(t instanceof TypeStruct obj) || obj._fields==null ) + throw error("Unknown struct type '" + structName + "'"); return newStruct(obj); } String name = _lexer.matchId(); diff --git a/chapter14/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/chapter14/src/test/java/com/seaofnodes/simple/Chapter12Test.java index 99c08f16..63951a37 100644 --- a/chapter14/src/test/java/com/seaofnodes/simple/Chapter12Test.java +++ b/chapter14/src/test/java/com/seaofnodes/simple/Chapter12Test.java @@ -59,116 +59,4 @@ return x+1==x; assertEquals("return ((flt)arg==(ToFloat+1.0));", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 1)); } - - - @Test - public void testLinkedList0() { - Parser parser = new Parser( -""" -struct LLI { LLI? next; int i; } -LLI? head = null; -while( arg ) { - LLI x = new LLI; - x.next = head; - x.i = arg; - head = x; - arg = arg-1; -} -return head.next.i; -"""); - try { parser.parse(true).iterate(true); fail(); } - catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); } - } - - @Test - public void testLinkedList1() { - Parser parser = new Parser( -""" -struct LLI { LLI? next; int i; } -LLI? head = null; -while( arg ) { - LLI x = new LLI; - x.next = head; - x.i = arg; - head = x; - arg = arg-1; -} -if( !head ) return 0; -LLI? next = head.next; -if( next==null ) return 1; -return next.i; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("Stop[ return 0; return 1; return .i; ]", stop.toString()); - assertEquals(2L, Evaluator.evaluate(stop, 3)); - } - - @Test - public void testCoRecur() { - Parser parser = new Parser( -""" -struct int0 { int i; flt0? f; } -struct flt0 { flt f; int0? i; } -int0 i0 = new int0; -i0.i = 17; -flt0 f0 = new flt0; -f0.f = 3.14; -i0.f = f0; -f0.i = i0; -return f0.i.f.i.i; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return 17;", stop.toString()); - } - - @Test - public void testNullRef0() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -return n.next; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return null;", stop.toString()); - } - - @Test - public void testNullRef1() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -n.next = new N; -return n.next; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return new N;", stop.toString()); - } - - @Test - public void testNullRef2() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -n.next = null; -return n.next; -"""); - try { parser.parse(true).iterate(true); fail(); } - catch( Exception e ) { assertEquals("Cannot store null into field *N next",e.getMessage()); } - } - - @Test - public void testNullRef3() { - Parser parser = new Parser( -""" -struct N { N next; int i; } -N n = new N; -n.i = 3.14; -return n.i; -"""); - try { parser.parse(true).iterate(true); fail(); } - catch( Exception e ) { assertEquals("Cannot store 3.14 into field int i",e.getMessage()); } - } } diff --git a/chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java new file mode 100644 index 00000000..f9aa3016 --- /dev/null +++ b/chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java @@ -0,0 +1,166 @@ +package com.seaofnodes.simple; + +import com.seaofnodes.simple.evaluator.Evaluator; +import com.seaofnodes.simple.node.StopNode; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class Chapter13Test { + @Test + public void testJig() { + Parser parser = new Parser( +""" +return 3.14; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return 3.14;", stop.toString()); + assertEquals(3.14, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testLinkedList0() { + Parser parser = new Parser( +""" +struct LLI { LLI? next; int i; } +LLI? head = null; +while( arg ) { + LLI x = new LLI; + x.next = head; + x.i = arg; + head = x; + arg = arg-1; +} +return head.next.i; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); } + } + + @Test + public void testLinkedList1() { + Parser parser = new Parser( +""" +struct LLI { LLI? next; int i; } +LLI? head = null; +while( arg ) { + LLI x = new LLI; + x.next = head; + x.i = arg; + head = x; + arg = arg-1; +} +if( !head ) return 0; +LLI? next = head.next; +if( next==null ) return 1; +return next.i; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("Stop[ return 0; return 1; return .i; ]", stop.toString()); + assertEquals(2L, Evaluator.evaluate(stop, 3)); + } + + @Test + public void testCoRecur() { + Parser parser = new Parser( +""" +struct int0 { int i; flt0? f; } +struct flt0 { flt f; int0? i; } +int0 i0 = new int0; +i0.i = 17; +flt0 f0 = new flt0; +f0.f = 3.14; +i0.f = f0; +f0.i = i0; +return f0.i.f.i.i; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return 17;", stop.toString()); + } + + @Test + public void testNullRef0() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +return n.next; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return null;", stop.toString()); + } + + @Test + public void testNullRef1() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +n.next = new N; +return n.next; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return new N;", stop.toString()); + } + + @Test + public void testNullRef2() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +n.next = null; +return n.next; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Cannot store null into field *N next",e.getMessage()); } + } + + @Test + public void testNullRef3() { + Parser parser = new Parser( +""" +struct N { N next; int i; } +N n = new N; +n.i = 3.14; +return n.i; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Cannot store 3.14 into field int i",e.getMessage()); } + } + + @Test + public void testEmpty() { + Parser parser = new Parser( +""" +struct S{}; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return 0;", stop.toString()); + assertEquals(0L, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testForwardRef0() { + Parser parser = new Parser( +""" +struct S1 { S2 s; } +return new S2; +"""); + try { parser.parse(true).iterate(true); fail(); } + catch( Exception e ) { assertEquals("Unknown struct type 'S2'",e.getMessage()); } + } + + @Test + public void testForwardRef1() { + Parser parser = new Parser( +""" +struct S1 { S2? s; } +struct S2 { int x; } +return new S1.s=new S2; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return new S1;", stop.toString()); + } +} |
