From 741d78b6e840c88b7b183010c812ad982b342da1 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Mon, 10 Aug 2026 11:11:18 -0700 Subject: Chapter 28a: Modules and Lazy Class Initialization Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: fuhsnn <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: Symious <14933944+symious@users.noreply.github.com> Co-authored-by: Jun Kawasaki Co-authored-by: Claude Opus 5 --- .../java/com/seaofnodes/simple/Chapter15Test.java | 85 ++++++++++------------ 1 file changed, 40 insertions(+), 45 deletions(-) (limited to 'src/test/java/com/seaofnodes/simple/Chapter15Test.java') diff --git a/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/src/test/java/com/seaofnodes/simple/Chapter15Test.java index 9aaafc28..c2071cb6 100644 --- a/src/test/java/com/seaofnodes/simple/Chapter15Test.java +++ b/src/test/java/com/seaofnodes/simple/Chapter15Test.java @@ -21,9 +21,7 @@ public class Chapter15Test { """; var code = new CodeGen(src).parse(); var stop = code._stop; - var main = code.link(code._main); - var load = stop.walk(n -> n instanceof com.seaofnodes.simple.node.LoadNode ld && ld._name.equals("[]") && - ld.in(0)!=null && ld.cfg0().fun()==main ? ld : null); + var load = stop.walk(n -> n instanceof com.seaofnodes.simple.node.LoadNode ld && ld._name.equals("[]") ? ld : null); org.junit.Assert.assertNotNull(load); // The parser uses current control as a placeholder for a range check. // Model an explicit check already performed before the inner diamond: @@ -34,8 +32,7 @@ public class Chapter15Test { load.setDef(0,checked); code.driver(CodeGen.Phase.TypeCheck); org.junit.Assert.assertTrue("Common dominating control permits Phi splitting",load.isDead()); - var split = stop.walk(n -> n instanceof com.seaofnodes.simple.node.LoadNode ld && ld._name.equals("[]") && - ld.in(0)!=null && ld.cfg0().fun()==main ? ld : null); + var split = stop.walk(n -> n instanceof com.seaofnodes.simple.node.LoadNode ld && ld._name.equals("[]") ? ld : null); org.junit.Assert.assertNotNull(split); org.junit.Assert.assertSame("The surviving read retains the earlier check",checked,split.in(0)); code.driver(CodeGen.Phase.LocalSched); @@ -57,9 +54,7 @@ public class Chapter15Test { """; var code = new CodeGen(src).parse(); var stop = code._stop; - var main = code.link(code._main); - var load = stop.walk(n -> n instanceof com.seaofnodes.simple.node.LoadNode ld && ld._name.equals("[]") && - ld.in(0)!=null && ld.cfg0().fun()==main ? ld : null); + var load = stop.walk(n -> n instanceof com.seaofnodes.simple.node.LoadNode ld && ld._name.equals("[]") ? ld : null); org.junit.Assert.assertNotNull(load); org.junit.Assert.assertNotNull("Element loads carry their range-check control",load.in(0)); code.driver(CodeGen.Phase.LocalSched); @@ -84,14 +79,14 @@ return 3.14; public void testCyclic() { CodeGen code = new CodeGen( """ -struct C { !C? !l; }; -!C !c = new C; +struct _C { !_C? !l; }; +!_C !c = new _C; c.l = c; return c; """); code.driver(CodeGen.Phase.FinalizeIR); - assertEquals("return C;", code.print()); - assertEquals("C{l=$cyclic}", Eval2.eval(code, 0)); + assertEquals("return Test._C;", code.print()); + assertEquals("Test._C{l=$cyclic}", Eval2.eval(code, 0)); } @Test @@ -156,34 +151,34 @@ return a[0]; public void testBasic4() { CodeGen code = new CodeGen( """ -struct A { int i; }; -!A?[] !a = new !A?[2]; +struct _A { int i; }; +!_A?[] !a = new !_A?[2]; return a; """); code.driver(CodeGen.Phase.FinalizeIR); - assertEquals("return []*A?;", code.print()); - assertEquals("*A {i64 !i; }?[ null,null]", Eval2.eval(code, 0)); + assertEquals("return []*Test._A?;", code.print()); + assertEquals("*Test._A {i64 !i; }?[ null,null]", Eval2.eval(code, 0)); } @Test public void testBasic5() { CodeGen code = new CodeGen( """ -struct S { int x; flt y; }; -// A new S -!S !s = new S; s.x=99; s.y = 3.14; +struct _S { int x; flt y; }; +// A new _S +!_S !s = new _S; s.x=99; s.y = 3.14; -// Double-d array of Ss. Fill in one row. -!S?[]?[] !iss = new !S?[]?[2]; -iss[0] = new !S?[7]; +// Double-d array of _Ss. Fill in one row. +!_S?[]?[] !iss = new !_S?[]?[2]; +iss[0] = new !_S?[7]; iss[0][2] = s; // Now pull out the filled-in value, with null checks flt rez; -!S?[]? is = iss[arg]; +!_S?[]? is = iss[arg]; if( !is ) rez = 1.2; else { - S? i = is[2]; + _S? i = is[2]; if( !i ) rez = 2.3; else rez = i.y; } @@ -199,13 +194,13 @@ return rez; public void testBasic6() { CodeGen code = new CodeGen( """ -struct S { int x; flt y; }; -// A new S -!S !s = new S; s.x=99; s.y = 3.14; +struct _S { int x; flt y; }; +// A new _S +!_S !s = new _S; s.x=99; s.y = 3.14; -// Double-d array of Ss. Fill in one row. -!S?[]?[] !iss = new !S?[]?[2]; -iss[0] = new !S?[7]; +// Double-d array of _Ss. Fill in one row. +!_S?[]?[] !iss = new !_S?[]?[2]; +iss[0] = new !_S?[7]; iss[0][2] = s; // Now pull out the filled-in value, with null checks @@ -226,22 +221,22 @@ return rez;"""); CodeGen code = new CodeGen( """ // Can we define a forward-reference array? -struct Tree { !Tree?[]? !_kids; }; -!Tree !root = new Tree; -root._kids = new !Tree?[2]; // NO BANG SO ARRAY IS OF IMMUTABLE TREES???? -root._kids[0] = new Tree; +struct _Tree { !_Tree?[]? !_kids; }; +!_Tree !root = new _Tree; +root._kids = new !_Tree?[2]; // NO BANG SO ARRAY IS OF IMMUTABLE TREES???? +root._kids[0] = new _Tree; return root; """); - code.driver(CodeGen.Phase.FinalizeIR); - assertEquals("return Tree;", code.print()); - assertEquals("Tree{_kids=*Tree {*[]*Tree?? !_kids; }?[ Tree{_kids=null},null]}", Eval2.eval(code, 0)); + code.driver(CodeGen.Phase.TypeCheck); + assertEquals("return Test._Tree;", code.print()); + assertEquals("Test._Tree{_kids=*Test._Tree {*[]*Test._Tree?[mutable]? !_kids; }?[ Test._Tree{_kids=null},null]}", Eval2.eval(code, 0)); } @Test public void testNestedStructAddMemProj() { CodeGen code = new CodeGen( """ -struct S { int a; int[] !b; }; +struct _S { int a; int[] !b; new _S = { int[] ary -> b=ary; }; }; return 0; """); code.driver(CodeGen.Phase.FinalizeIR); @@ -267,7 +262,7 @@ while( i < ary# - 1 ) { } return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6 """); - code.driver(CodeGen.Phase.FinalizeIR); + code.driver(CodeGen.Phase.TypeCheck); assertEquals("return (.[]+(.[]*1000));", code.print()); assertEquals("1006", Eval2.eval(code, 4)); } @@ -285,12 +280,12 @@ return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6 public void testNewNodeInit() { CodeGen code = new CodeGen( """ -struct S {int i; flt f;}; -!S !s1 = new S; -!S !s2 = new S; +struct _S {int i; flt f;}; +!_S !s1 = new _S; +!_S !s2 = new _S; s2.i = 3; s2.f = 2.0; -if (arg) s1 = new S; +if (arg) s1 = new _S; return s1.i + s1.f; """); code.driver(CodeGen.Phase.FinalizeIR); @@ -327,8 +322,8 @@ return is; int[] is = new int[3.14]; return is[1]; """); - try { code.driver(CodeGen.Phase.FinalizeIR); fail(); } - catch( Exception e ) { assertEquals("Cannot allocate an array with length 3.14",e.getMessage()); } + try { code.driver(CodeGen.Phase.TypeCheck); fail(); } + catch( Exception e ) { assertEquals("Cannot '<<' 3.14",e.getMessage()); } } @Test -- cgit v1.2.3