summaryrefslogtreecommitdiff
path: root/chapter18/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter18/src/test/java')
-rw-r--r--chapter18/src/test/java/com/seaofnodes/simple/Chapter17Test.java15
-rw-r--r--chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java43
-rw-r--r--chapter18/src/test/java/com/seaofnodes/simple/Eval2.java3
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;