summaryrefslogtreecommitdiff
path: root/chapter18/src/test/java/com
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-01-07 15:31:54 -0800
committerCliff Click <cliffc@acm.org>2025-01-15 15:07:30 -0800
commite0d7b4f8ef0e886f8efae62b77402007e6b2476c (patch)
tree042c6df4fc96b6f3bd128f03f1cfda4c1f66704e /chapter18/src/test/java/com
parentc2169787d92da57aa0e11cd026e398b3d5fcda12 (diff)
downloadSimple-e0d7b4f8ef0e886f8efae62b77402007e6b2476c.tar.gz
Simple-e0d7b4f8ef0e886f8efae62b77402007e6b2476c.zip
Forward Ref type to Bottom
So FRefs can strictly lift when defined. Parser can support forward refs in more cases, by upcasting now and proving the cast is correct later. Monotonic for some float ops.
Diffstat (limited to 'chapter18/src/test/java/com')
-rw-r--r--chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java62
-rw-r--r--chapter18/src/test/java/com/seaofnodes/simple/Eval2.java2
2 files changed, 57 insertions, 7 deletions
diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java
index 8f8d15a1..9e74ce6d 100644
--- a/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java
+++ b/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java
@@ -11,14 +11,29 @@ public class Chapter18Test {
public void testJig() {
CodeGen code = new CodeGen(
"""
-if( arg ? f : g ) return 1;
-val f = {->1};
-val g = {->2};
-return 2;
+return 0;
+""");
+ code.parse().opto().typeCheck().GCM();
+ assertEquals("return 0;", code._stop.toString());
+ assertEquals("0", Eval2.eval(code, 0));
+ }
+
+ @Test
+ public void testJig2() {
+ CodeGen code = new CodeGen(
+"""
+struct S { S? next; };
+val f = { int dep, S s ->
+ if (dep-- == 0) return s;
+ S? v = f(dep, s);
+ return v ? v.next : null;
+};
+return f(1, new S);
""");
code.parse().opto().typeCheck().GCM();
- assertEquals("return 0.0f;", code._stop.toString());
- assertEquals("0.0", Eval2.eval(code, 0));
+ assertEquals("Stop[ return f( 1,S); return Phi(Region,Parm_s(f,*S {*S? !next; },S,s),Phi(Region,.next,null)); ]", code._stop.toString());
+ assertEquals("null", Eval2.eval(code, 0));
+ assertEquals("null", Eval2.eval(code, 1));
}
@Test
@@ -149,6 +164,22 @@ return newS(1).i;
assertEquals("1", Eval2.eval(code, 0));
}
+ // Double forward reference
+ @Test
+ public void testFcn7() {
+ CodeGen code = new CodeGen(
+"""
+if( arg ? f : g ) return 1;
+val f = {->1;};
+val g = {->2;};
+return 2;
+""");
+ code.parse().opto().typeCheck().GCM();
+ assertEquals("Stop[ return 1; return 1; return 2; ]", code._stop.toString());
+ assertEquals("1", Eval2.eval(code, 0));
+ }
+
+
// Function break
@Test
public void testErr1() {
@@ -211,4 +242,23 @@ return is_even(arg);
assertEquals("0", Eval2.eval(code, 3));
}
+ // Forward ref to 'x' means that
+ @Ignore @Test
+ public void testForwardRef1() {
+ CodeGen code = new CodeGen(
+"""
+struct S {
+ { int } f = { -> return x(); };
+};
+val x = { -> return 1; };
+S? s = null;
+for(;;) {
+ if (s) return s.f;
+}
+""");
+ code.parse().opto().typeCheck().GCM();
+ assertEquals("return 0;", code._stop.toString());
+ assertEquals("0", Eval2.eval(code, 0));
+ }
+
}
diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java
index e68c8fd3..006034e9 100644
--- a/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java
+++ b/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java
@@ -224,7 +224,7 @@ public abstract class Eval2 {
F.dec(); // Lower ref count
// Install replacement Frame; set return result over the CallEnd
F = cont._frame;
- F.put(cont._cc,rez); // Set return value into CallEnd
+ F.put0(cont._cc,rez); // Set return value into CallEnd
return cont._cc; // Return CallEnd as the new control
}