From e0d7b4f8ef0e886f8efae62b77402007e6b2476c Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Tue, 7 Jan 2025 15:31:54 -0800 Subject: 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. --- .../java/com/seaofnodes/simple/Chapter18Test.java | 62 +++++++++++++++++++--- .../src/test/java/com/seaofnodes/simple/Eval2.java | 2 +- 2 files changed, 57 insertions(+), 7 deletions(-) (limited to 'chapter18/src/test') 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 } -- cgit v1.2.3