diff options
| author | Cliff Click <cliffc@acm.org> | 2025-01-07 11:15:10 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-01-15 15:07:30 -0800 |
| commit | c2169787d92da57aa0e11cd026e398b3d5fcda12 (patch) | |
| tree | 8c6284802136f8e24b506815fa386cf39583ae8e /chapter18/src/test | |
| parent | a3db7b9938d01f7995398df9f07553074e15905e (diff) | |
| download | Simple-c2169787d92da57aa0e11cd026e398b3d5fcda12.tar.gz Simple-c2169787d92da57aa0e11cd026e398b3d5fcda12.zip | |
Fix a series of small bugs
Various kinds of missing checks, over-aggressive asserts, and a few odds and ends
Diffstat (limited to 'chapter18/src/test')
3 files changed, 52 insertions, 9 deletions
diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Chapter17Test.java b/chapter18/src/test/java/com/seaofnodes/simple/Chapter17Test.java index 5247f122..98c30721 100644 --- a/chapter18/src/test/java/com/seaofnodes/simple/Chapter17Test.java +++ b/chapter18/src/test/java/com/seaofnodes/simple/Chapter17Test.java @@ -279,6 +279,21 @@ return new A { catch( Exception e ) { assertEquals("'A' is not fully initialized, field 'b' needs to be set in a constructor",e.getMessage()); } } + @Test + public void testVar16() { + CodeGen code = new CodeGen( +""" +struct S{}; +val x = 1; +val s = new S{x = 2;}; +return x; +""" +); + try { code.parse().opto().typeCheck(); fail(); } + catch( Exception e ) { assertEquals("Cannot reassign final 'x'",e.getMessage()); } + } + + // --------------------------------------------------------------- @Test public void testTrinary0() { diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java index 545bb546..8f8d15a1 100644 --- a/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java +++ b/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java @@ -11,13 +11,14 @@ public class Chapter18Test { public void testJig() { CodeGen code = new CodeGen( """ -struct S { int i; }; -val newS = { int x -> return new S { i=x; }; }; -return newS(1).i; +if( arg ? f : g ) return 1; +val f = {->1}; +val g = {->2}; +return 2; """); - code.parse(false).opto().typeCheck().GCM(); - assertEquals("return 0;", code._stop.toString()); - assertEquals("0", Eval2.eval(code, 0)); + code.parse().opto().typeCheck().GCM(); + assertEquals("return 0.0f;", code._stop.toString()); + assertEquals("0.0", Eval2.eval(code, 0)); } @Test @@ -143,8 +144,8 @@ struct S { int i; }; val newS = { int x -> return new S { i=x; }; }; return newS(1).i; """); - code.parse(false).opto().typeCheck().GCM(); - assertEquals("Stop[ return .i; return S; ]", code._stop.toString()); + code.parse().opto().typeCheck().GCM(); + assertEquals("return 1;", code._stop.toString()); assertEquals("1", Eval2.eval(code, 0)); } @@ -166,6 +167,32 @@ return 1; catch( Exception e ) { assertEquals("No active loop for a break or continue",e.getMessage()); } } + // Calling and inlining a null function + @Test + public void testErr2() { + CodeGen code = new CodeGen( +""" +{int -> int}? i2i = { int i -> return i; }; +for(;;) { + if (i2i(2) == arg) break; + i2i = null; +} +"""); + try { code.parse().opto().typeCheck(); fail(); } + catch( Exception e ) { assertEquals("Might be null calling { int -> int #1}?",e.getMessage()); } + } + + + @Test + public void testErr3() { + CodeGen code = new CodeGen( +""" +val f = { int i, int j -> return i+j; }; +return f(); +"""); + try { code.parse().opto().typeCheck(); fail(); } + catch( Exception e ) { assertEquals("Expecting 2 arguments, but found 0",e.getMessage()); } + } // Mutual recursion. Fails without SCCP to lift the recursive return types. @Ignore @Test diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java index 66b5c28b..e68c8fd3 100644 --- a/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java +++ b/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java @@ -263,6 +263,7 @@ public abstract class Eval2 { case LoadNode ld -> load(ld); case MinusFNode mnf -> - d(mnf.in(1)); case MinusNode sub -> - x(sub.in(1)); + case MulFNode mlf -> d(mlf.in(1)) * d(mlf.in(2)); case MulNode mul -> x(mul.in(1)) * x(mul.in(2)); case NewNode alloc-> alloc(alloc); case NotNode not -> x(not.in(1)) == 0 ? 1L : 0L; @@ -297,7 +298,7 @@ public abstract class Eval2 { return switch ( t ) { case TypeInteger i -> i.isConstant() ? (Long )i.value() : "INT"; case TypeFloat f -> f.isConstant() ? (Double)f.value() : "FLT"; - case TypeMemPtr tmp -> throw Utils.TODO(); + case TypeMemPtr tmp -> tmp; case TypeFunPtr tfp -> tfp; case TypeMem mem -> "MEM"; default -> null; |
