summaryrefslogtreecommitdiff
path: root/chapter24a/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter24a/src/test/java')
-rw-r--r--chapter24a/src/test/java/com/seaofnodes/simple/ChainedComparisonTest.java37
-rw-r--r--chapter24a/src/test/java/com/seaofnodes/simple/Chapter18Test.java13
-rw-r--r--chapter24a/src/test/java/com/seaofnodes/simple/Chapter24Test.java12
3 files changed, 48 insertions, 14 deletions
diff --git a/chapter24a/src/test/java/com/seaofnodes/simple/ChainedComparisonTest.java b/chapter24a/src/test/java/com/seaofnodes/simple/ChainedComparisonTest.java
new file mode 100644
index 00000000..99f18e62
--- /dev/null
+++ b/chapter24a/src/test/java/com/seaofnodes/simple/ChainedComparisonTest.java
@@ -0,0 +1,37 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.type.TypeInteger;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class ChainedComparisonTest {
+ @Test public void testAdjacentOperandsAndOperators() {
+ String[] expressions = {"10 < arg < 20", "0 < arg <= 3", "3 >= arg > 0",
+ "0 <= arg < 3", "0 < arg <= 3 < 4"};
+ String[][] expected = {{"0","0","1","0"}, {"0","1","0","0"},
+ {"0","1","0","0"}, {"1","0","0","0"},
+ {"0","1","0","0"}};
+ int[] args = {0,3,15,30};
+ for(int i=0;i<expressions.length;i++) {
+ CodeGen code = new CodeGen("return "+expressions[i]+";").driver(CodeGen.Phase.TypeCheck);
+ for(int j=0;j<args.length;j++) assertEquals(expressions[i],expected[i][j],Eval2.eval(code,args[j]));
+ }
+ }
+
+ @Test public void testSingleEvaluationAndShortCircuit() {
+ for(int seed:new int[]{2,13,123}) {
+ CodeGen code = new CodeGen("int x=arg; int y=0; val b=0 < x++ <= (y+=3) < (y+=1); return x*100+y*10+b;",TypeInteger.BOT,seed,true)
+ .driver(CodeGen.Phase.TypeCheck);
+ assertEquals("100",Eval2.eval(code,0));
+ assertEquals("441",Eval2.eval(code,3));
+ assertEquals("530",Eval2.eval(code,4));
+ }
+ try {
+ new CodeGen("return 0 < arg > 1;").parse();
+ fail("mixed directions");
+ } catch(RuntimeException e) {
+ assertEquals("Mixing relational directions in a chained relational test",e.getMessage());
+ }
+ }
+}
diff --git a/chapter24a/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter24a/src/test/java/com/seaofnodes/simple/Chapter18Test.java
index e26edb7e..e5dd259b 100644
--- a/chapter24a/src/test/java/com/seaofnodes/simple/Chapter18Test.java
+++ b/chapter24a/src/test/java/com/seaofnodes/simple/Chapter18Test.java
@@ -406,8 +406,9 @@ return g();
}
- // Mutual recursion. Fails without SCCP to lift the recursive return types.
- @Ignore @Test
+ // Local SCCP cannot infer this recursive return type. The next chapter
+ // solves across calls and checks the same program's execution results.
+ @Test
public void testFcnMutRec() {
CodeGen code = new CodeGen(
"""
@@ -415,12 +416,8 @@ val is_even = { int x -> x ? is_odd (x-1) : true ; };
val is_odd = { int x -> x ? is_even(x-1) : false; };
return is_even(arg);
""");
- code.driver(CodeGen.Phase.FinalizeIR);
- assertEquals("Stop[ return is_even( arg); return Phi(Region,Phi(Region,is_even( ((Parm_x(is_even,int,arg,Sub)-1)-1)),0),1); ]", code._stop.toString());
- assertEquals("1", Eval2.eval(code, 0));
- assertEquals("0", Eval2.eval(code, 1));
- assertEquals("1", Eval2.eval(code, 2));
- assertEquals("0", Eval2.eval(code, 3));
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
+ catch( Parser.ParseException e ) { assertEquals("No defined return type",e.getMessage()); }
}
// Forward ref to 'x' means that
diff --git a/chapter24a/src/test/java/com/seaofnodes/simple/Chapter24Test.java b/chapter24a/src/test/java/com/seaofnodes/simple/Chapter24Test.java
index 8cd300c2..4eb1324d 100644
--- a/chapter24a/src/test/java/com/seaofnodes/simple/Chapter24Test.java
+++ b/chapter24a/src/test/java/com/seaofnodes/simple/Chapter24Test.java
@@ -359,17 +359,17 @@ sys.io.p(str);
return 0;
""";
- TestC.runSF("stacked_r_3", src, null, "In Range", 5);
+ TestC.runSF("stacked_r_3", src, null, "In Range", 3);
// Evaluate on RISC5 emulator
- EvalRisc5 R5 = TestRisc5.build("stacked_r_3", src, 0, 5, false);
+ EvalRisc5 R5 = TestRisc5.build("stacked_r_3", src, 0, 3, false);
int trap = R5.step(100);
assertEquals(0,trap);
assertEquals(0,R5.regs[riscv.A0]);
assertEquals("In Range",R5._stdout.toString());
// Evaluate on ARM emulator
- EvalArm64 arm = TestArm64.build("stacked_r_3", src, 0, 5, false);
+ EvalArm64 arm = TestArm64.build("stacked_r_3", src, 0, 3, false);
int trap_1 = arm.step(100);
assertEquals(0,trap_1);
assertEquals(0,arm.regs[0]);
@@ -425,17 +425,17 @@ sys.io.p("Out of range");
return 0;
""";
- TestC.runSF("stacked_r_5", src, null, "In Range", 5);
+ TestC.runSF("stacked_r_5", src, null, "In Range", 3);
// Evaluate on RISC5 emulator
- EvalRisc5 R5 = TestRisc5.build("stacked_r_5", src, 0, 7, false);
+ EvalRisc5 R5 = TestRisc5.build("stacked_r_5", src, 0, 5, false);
int trap = R5.step(100);
assertEquals(0,trap);
assertEquals(0,R5.regs[riscv.A0]);
assertEquals("In Range",R5._stdout.toString());
// Evaluate on ARM emulator
- EvalArm64 arm = TestArm64.build("stacked_r_5", src, 0, 7, false);
+ EvalArm64 arm = TestArm64.build("stacked_r_5", src, 0, 5, false);
trap = arm.step(100);
assertEquals(0,trap);
assertEquals(0,arm.regs[0]);