diff options
| author | Cliff Click <cliffc@acm.org> | 2024-09-12 11:13:31 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-08-10 11:11:18 -0700 |
| commit | 1e40ff455b2732616d4fe8951c53c0230df6728c (patch) | |
| tree | 7a445e4348df55af15922667044d9ed6024f4923 /src/test/java | |
| parent | c920fc35d7c7600a5c7fbe898572ae0a7b2aa4cc (diff) | |
| download | Simple-1e40ff455b2732616d4fe8951c53c0230df6728c.tar.gz Simple-1e40ff455b2732616d4fe8951c53c0230df6728c.zip | |
Chapter 15: Arrays
Co-authored-by: XmiliaH <xmilia.hermit@gmail.com>
Co-authored-by: Thalia Archibald <thalia@archibald.dev>
Co-authored-by: Tamás Hadházy <85063808+Hels15@users.noreply.github.com>
Co-authored-by: tannal <tannal2409@gmail.com>
Co-authored-by: hadha <helsgithub15@gmail.com>
Co-authored-by: RobertObkircher <robert.obkircher@gmail.com>
Co-authored-by: Robert Obkircher <robert.obkircher@gmail.com>
Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com>
Diffstat (limited to 'src/test/java')
12 files changed, 692 insertions, 240 deletions
diff --git a/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/src/test/java/com/seaofnodes/simple/BrainFuckTest.java new file mode 100644 index 00000000..d5ffe835 --- /dev/null +++ b/src/test/java/com/seaofnodes/simple/BrainFuckTest.java @@ -0,0 +1,80 @@ +package com.seaofnodes.simple; + +import com.seaofnodes.simple.evaluator.Evaluator; +import com.seaofnodes.simple.node.StopNode; +import org.junit.Test; +import org.junit.Ignore; + +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class BrainFuckTest { + + @Test + public void testBrainfuck() { + var program = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.".getBytes(StandardCharsets.UTF_8); + var encoded = new StringBuilder("u8[] program = new u8[").append(program.length).append("];"); + for (int i = 0; i < program.length; i++) { + int value = program[i] & 0xFF; + encoded.append("program[").append(i).append("] = ").append(value).append(";"); + } + + Parser parser = new Parser( + encoded + """ +int pc = 0; +int d = 0; +u8[] data = new u8[100]; +u8[] output = new u8[0]; + +while (pc < program#) { + int command = program[pc]; + if (command == 62) { + d = d + 1; + } else if (command == 60) { + d = d - 1; + } else if (command == 43) { + data[d] = data[d] + 1; + } else if (command == 45) { + data[d] = data[d] - 1; + } else if (command == 46) { + u8[] old = output; + output = new u8[output# + 1]; + int i = 0; + while (i < old#) { + output[i] = old[i]; + i = i + 1; + } + output[i] = data[d]; + } else if (command == 44) { + data[d] = 42; + } else if (command == 91) { + if (data[d] == 0) { + int d = 1; + while (d > 0) { + pc = pc + 1; + command = program[pc]; + if (command == 91) d = d + 1; + if (command == 93) d = d - 1; + } + } + } else if (command == 93) { + if (data[d] != 0) { + int d = 1; + while (d > 0) { + pc = pc - 1; + command = program[pc]; + if (command == 93) d = d + 1; + if (command == 91) d = d - 1; + } + } + } + pc = pc + 1; +} +return output; + """); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("Hello World!\n", Evaluator.evaluate(stop, 0, 10000).toString()); + } +} diff --git a/src/test/java/com/seaofnodes/simple/Chapter06Test.java b/src/test/java/com/seaofnodes/simple/Chapter06Test.java index 99ce8fa5..ae37a867 100644 --- a/src/test/java/com/seaofnodes/simple/Chapter06Test.java +++ b/src/test/java/com/seaofnodes/simple/Chapter06Test.java @@ -65,7 +65,7 @@ else b=5; return b;""", TypeInteger.BOT); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region34,42,5);", stop.toString()); + assertEquals("return Phi(Region39,42,5);", stop.toString()); } @Test diff --git a/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/src/test/java/com/seaofnodes/simple/Chapter10Test.java index fb324fd9..def9aaa6 100644 --- a/src/test/java/com/seaofnodes/simple/Chapter10Test.java +++ b/src/test/java/com/seaofnodes/simple/Chapter10Test.java @@ -64,8 +64,8 @@ else v.y = 3; return v; """); - StopNode stop = parser.parse().iterate(); - assertEquals("return new Vector2D;", stop.toString()); + StopNode stop = parser.parse(false).iterate(); + assertEquals("return Vector2D;", stop.toString()); } @Test @@ -103,7 +103,7 @@ while (arg) { return bar.a; """); StopNode stop = parser.parse(false).iterate(); - assertEquals("return Phi(Loop12,0,(Phi_a+2));", stop.toString()); + assertEquals("return Phi(Loop13,0,(Phi_a+2));", stop.toString()); } @Test @@ -155,7 +155,7 @@ if( bar ) bar.a = 1; return bar; """); StopNode stop = parser.parse(false).iterate(); - assertEquals("return Phi(Region31,(*void)Phi(Region19,null,new Bar),null);", stop.toString()); + assertEquals("return Phi(Region33,(*void)Phi(Region20,null,Bar),null);", stop.toString()); } @Test @@ -171,7 +171,7 @@ else bar.a = 1; return rez; """); StopNode stop = parser.parse(false).iterate(); - assertEquals("return Phi(Region37,4,3);", stop.toString()); + assertEquals("return Phi(Region39,4,3);", stop.toString()); } @Test @@ -225,7 +225,7 @@ while( i.x < i.len ) { return sum; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop17,0,(Phi(Loop,0,(Phi_x+1))+Phi_sum));", stop.toString()); + assertEquals("return Phi(Loop18,0,(Phi(Loop,0,(Phi_x+1))+Phi_sum));", stop.toString()); } @@ -246,7 +246,7 @@ while(arg) { return ret; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop12,new s0,Phi(Region34,new s0,Phi_ret));", stop.toString()); + assertEquals("return Phi(Loop13,s0,Phi(Region37,s0,Phi_ret));", stop.toString()); } @Test @@ -264,7 +264,7 @@ while(arg) { return ret; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop15,new s0,Phi(Region35,new s0,Phi_ret));", stop.toString()); + assertEquals("return Phi(Loop17,s0,Phi(Region38,s0,Phi_ret));", stop.toString()); } @@ -281,7 +281,7 @@ while(arg < 10) { return ret; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop12,new s0,Phi(Region33,new s0,Phi_ret));", stop.toString()); + assertEquals("return Phi(Loop13,s0,Phi(Region35,s0,Phi_ret));", stop.toString()); } @Test @@ -325,7 +325,7 @@ else return new s0; if(new s0.f0) return 0; """); StopNode stop = parser.parse().iterate(); - assertEquals("return new s0;", stop.toString()); + assertEquals("return s0;", stop.toString()); } @Test @@ -353,7 +353,7 @@ s0 v1 = v0; return v1; """); StopNode stop = parser.parse().iterate(); - assertEquals("return new s0;", stop.toString()); + assertEquals("return s0;", stop.toString()); } diff --git a/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/src/test/java/com/seaofnodes/simple/Chapter11Test.java index 63cd511a..5f9f9cac 100644 --- a/src/test/java/com/seaofnodes/simple/Chapter11Test.java +++ b/src/test/java/com/seaofnodes/simple/Chapter11Test.java @@ -291,7 +291,7 @@ else { } } """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("Stop[ return 9; return 0; return 0; return 0; ]", stop.toString()); } @@ -346,7 +346,9 @@ if (arg) v.f=1; return i; """); StopNode stop = parser.parse().iterate(); - assertEquals("return .f;", stop.toString()); + assertEquals("return 2;", stop.toString()); + assertEquals(2L, Evaluator.evaluate(stop, 0)); + assertEquals(2L, Evaluator.evaluate(stop, 1)); } @Test @@ -355,6 +357,7 @@ return i; """ struct S { int f; } S v = new S; +v.f = arg; S t = new S; int i = 0; if (arg) { @@ -366,7 +369,7 @@ if (arg) { return i; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region34,.f,0);", stop.toString()); + assertEquals("return Phi(Region40,.f,0);", stop.toString()); } @Test @@ -385,7 +388,7 @@ if (v1) { return v0; """); StopNode stop = parser.parse().iterate(); - assertEquals("return new S;", stop.toString()); + assertEquals("return S;", stop.toString()); } @@ -395,6 +398,7 @@ return v0; """ struct S { int f; } S v = new S; +v.f = arg; S t = new S; int i = v.f; if (arg+1) arg= 0; @@ -402,7 +406,7 @@ while (arg) v.f = 2; return i; """); StopNode stop = parser.parse().iterate(); - assertEquals("return .f;", stop.toString()); + assertEquals("return arg;", stop.toString()); } @Test @@ -419,7 +423,7 @@ while(1) { return v; """); StopNode stop = parser.parse().iterate(); - assertEquals("return new S;", stop.toString()); + assertEquals("return S;", stop.toString()); } @Test @@ -451,8 +455,8 @@ while (arg) { } return i; """); - StopNode stop = parser.parse().iterate(false); - assertEquals("return .f;", stop.toString()); + StopNode stop = parser.parse().iterate(); + assertEquals("return 0;", stop.toString()); } @Test @@ -471,8 +475,8 @@ while(arg) { } return arg; """); - StopNode stop = parser.parse().iterate(false); - assertEquals("return Phi(Loop15,arg,Phi(Region37,.f,0));", stop.toString()); + StopNode stop = parser.parse().iterate(); + assertEquals("return Phi(Loop17,arg,Phi(Region42,.f,0));", stop.toString()); } @Test @@ -489,8 +493,8 @@ if (arg) { } return v; """); - StopNode stop = parser.parse().iterate(false); - assertEquals("return new S;", stop.toString()); + StopNode stop = parser.parse().iterate(); + assertEquals("return S;", stop.toString()); } @Test @@ -511,21 +515,4 @@ return v; StopNode stop = parser.parse().iterate(); //assertEquals("return new S;", stop.toString()); } - - @Test - public void testSplit() { - Parser parser = new Parser( - """ -struct S { int f; } -S s = new S; -if( arg==0 ) s.f = 1; -else if (arg == 1) s.f = 1; -return s.f; -"""); - StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region37,1,Phi(Region35,1,0));", stop.toString()); - assertEquals(1L, Evaluator.evaluate(stop, 0)); - assertEquals(1L, Evaluator.evaluate(stop, 1)); - assertEquals(0L, Evaluator.evaluate(stop, 2)); - } } diff --git a/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/src/test/java/com/seaofnodes/simple/Chapter12Test.java index 972118be..2a637ce6 100644 --- a/src/test/java/com/seaofnodes/simple/Chapter12Test.java +++ b/src/test/java/com/seaofnodes/simple/Chapter12Test.java @@ -14,7 +14,7 @@ public class Chapter12Test { """ return 3.14; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 3.14;", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); } @@ -25,7 +25,7 @@ return 3.14; """ return 3.14; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 3.14;", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); } @@ -42,7 +42,7 @@ while( 1 ) { } return guess; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return Phi(Loop9,(flt)arg,(((ToFloat/Phi_guess)+Phi_guess)/2.0));", stop.toString()); assertEquals(3.0, Evaluator.evaluate(stop, 9)); assertEquals(1.414213562373095, Evaluator.evaluate(stop, 2)); @@ -55,7 +55,7 @@ return guess; flt x = arg; return x+1==x; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return ((flt)arg==(ToFloat+1.0));", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 1)); } diff --git a/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/src/test/java/com/seaofnodes/simple/Chapter13Test.java index 807badd5..ab8ea902 100644 --- a/src/test/java/com/seaofnodes/simple/Chapter13Test.java +++ b/src/test/java/com/seaofnodes/simple/Chapter13Test.java @@ -14,7 +14,7 @@ public class Chapter13Test { """ return 3.14; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 3.14;", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); } @@ -56,7 +56,7 @@ LLI? next = head.next; if( next==null ) return 1; return next.i; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("Stop[ return 0; return 1; return .i; ]", stop.toString()); assertEquals(2L, Evaluator.evaluate(stop, 3)); } @@ -75,7 +75,7 @@ i0.f = f0; f0.i = i0; return f0.i.f.i.i; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 17;", stop.toString()); } @@ -87,7 +87,7 @@ struct N { N next; int i; } N n = new N; return n.next; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return null;", stop.toString()); } @@ -100,8 +100,8 @@ N n = new N; n.next = new N; return n.next; """); - StopNode stop = parser.parse().iterate(false); - assertEquals("return new N;", stop.toString()); + StopNode stop = parser.parse().iterate(); + assertEquals("return N;", stop.toString()); } @Test @@ -149,7 +149,7 @@ return n.i; """ struct S{}; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 0;", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 0)); } @@ -173,8 +173,8 @@ struct S1 { S2? s; } struct S2 { int x; } return new S1.s=new S2; """); - StopNode stop = parser.parse().iterate(false); - assertEquals("return new S1;", stop.toString()); + StopNode stop = parser.parse().iterate(); + assertEquals("return S2;", stop.toString()); } @Test diff --git a/src/test/java/com/seaofnodes/simple/Chapter14Test.java b/src/test/java/com/seaofnodes/simple/Chapter14Test.java index fcb7fa24..048cb93a 100644 --- a/src/test/java/com/seaofnodes/simple/Chapter14Test.java +++ b/src/test/java/com/seaofnodes/simple/Chapter14Test.java @@ -15,7 +15,7 @@ public class Chapter14Test { """ return 3.14; """); - StopNode stop = parser.parse(false).iterate(); + StopNode stop = parser.parse().iterate(); assertEquals("return 3.14;", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); } @@ -31,7 +31,7 @@ if( b < 0 ) c = -1; if( b > 2 ) c = 1; return c; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 99;", stop.toString()); assertEquals(99L, Evaluator.evaluate(stop, 0)); } @@ -44,7 +44,7 @@ u8 b = 123; b = b + 456;// Truncate return b; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 67;", stop.toString()); assertEquals(67L, Evaluator.evaluate(stop, 0)); } @@ -58,7 +58,7 @@ u8 b = 123; while( b ) b = b + 456;// Truncate return b; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return Phi(Loop9,123,((Phi_b+456)&255));", stop.toString()); } @@ -71,7 +71,7 @@ b = b + 456;// Truncate u1 c = b; // No more truncate needed return c; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 1;", stop.toString()); assertEquals(1L, Evaluator.evaluate(stop, 0)); } @@ -84,7 +84,7 @@ int b = 123; b = b+456 & 31; // Precedence return b; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 3;", stop.toString()); assertEquals(3L, Evaluator.evaluate(stop, 0)); } @@ -98,7 +98,7 @@ Foo f = new Foo; f.b = 123; return f.b; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 1;", stop.toString()); assertEquals(1L, Evaluator.evaluate(stop, 0)); } @@ -110,7 +110,7 @@ return f.b; i8 b = 255; // Chopped return b; // Sign extend """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return -1;", stop.toString()); assertEquals(-1L, Evaluator.evaluate(stop, 0)); } @@ -123,9 +123,10 @@ i8 b = arg; b = b + 1;// Truncate return b; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return (((((arg<<56)>>56)+1)<<56)>>56);", stop.toString()); - assertEquals(1L, Evaluator.evaluate(stop, 0)); + assertEquals(1L, Evaluator.evaluate(stop, 0)); + assertEquals(-128L, Evaluator.evaluate(stop, 127)); } @Test @@ -136,47 +137,18 @@ u16 mask = (1<<16)-1; // AND mask int c = 123456789 & mask; return c; // """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 52501;", stop.toString()); assertEquals(52501L, Evaluator.evaluate(stop, 0)); } @Test - public void testWrapMinus() { - Parser parser = new Parser( -""" -int MAX = 9223372036854775807; //0x7FFFFFFFFFFFFFFF; -int i = (arg&MAX) + -MAX + -1; // Basically (e0) + Long.MIN_VALUE -int j = -i; // Negating Long.MIN_VALUE wraps, cannot constant fold -if (arg) j = 1; -return j; -"""); - StopNode stop = parser.parse(false).iterate(); - assertEquals("return Phi(Region28,1,(-((arg&9223372036854775807)+-9223372036854775808)));", stop.toString()); - assertEquals(-9223372036854775808L, Evaluator.evaluate(stop, 0)); - assertEquals(1L, Evaluator.evaluate(stop, 1)); - } - - @Test - public void testWrapShr() { - Parser parser = new Parser( -""" -return (arg >>> 1)==0; -"""); - StopNode stop = parser.parse(false).iterate(); - assertEquals("return (!(arg>>>1));", stop.toString()); - assertEquals(1L, Evaluator.evaluate(stop, 0)); - assertEquals(1L, Evaluator.evaluate(stop, 1)); - assertEquals(0L, Evaluator.evaluate(stop, 2)); - } - - @Test public void testOr() { Parser parser = new Parser( """ return (arg | 123 ^ 456) >>> 1; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return (((arg|123)^456)>>>1);", stop.toString()); assertEquals(217L, Evaluator.evaluate(stop, 0)); } @@ -194,101 +166,6 @@ return arg; } @Test - public void testLoadBug() { - Parser parser = new Parser( -""" -struct A { int i; } -struct B { int i; } -A a = new A; -A t1 = new A; -B b = new B; -B t2 = new B; -int i; -if (arg) i = a.i; -else i = b.i; -return i; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return Phi(Region31,.i,.i);", stop.toString()); - assertEquals(0L, Evaluator.evaluate(stop, 0)); - } - - @Test - public void testBug2() { - Parser parser = new Parser( -""" -int z = 0; -while (1) { - int j; - if (arg&3) { - j = arg >> 2; - } else { - j = (arg >> 3)+z; - } - return j+1; -} -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return ((arg>>Phi(Region32,2,3))+1);", stop.toString()); - assertEquals(1L, Evaluator.evaluate(stop, 0)); - assertEquals(1L, Evaluator.evaluate(stop, 1)); - assertEquals(2L, Evaluator.evaluate(stop, 7)); - assertEquals(2L, Evaluator.evaluate(stop, 8)); - } - - @Test - public void testBug3() { - Parser parser = new Parser( -""" -flt f = arg; -bool b; -if (arg&3) b = f == 1.0; -else b = f == 2.0; -if (arg&5) b = arg == 1; -return b; -"""); - StopNode stop = parser.parse(false).iterate(false); - assertEquals("return Phi(Region37,(arg==1),((flt)arg==Phi(Region23,1.0,2.0)));", stop.toString()); - assertEquals(1L, Evaluator.evaluate(stop, 1)); - assertEquals(0L, Evaluator.evaluate(stop, 2)); - assertEquals(0L, Evaluator.evaluate(stop, 3)); - } - - @Test - public void testBug4() { - Parser parser = new Parser( -""" -int i; -if (arg&7) i=3; -else i=2; -return (arg == i) == 1; -"""); - StopNode stop = parser.parse(false).iterate(); - assertEquals("return (arg==Phi(Region18,3,2));", stop.toString()); - assertEquals(0L, Evaluator.evaluate(stop, 0)); - assertEquals(0L, Evaluator.evaluate(stop, 1)); - assertEquals(0L, Evaluator.evaluate(stop, 2)); - assertEquals(1L, Evaluator.evaluate(stop, 3)); - } - - @Test - public void testBug5() { - Parser parser = new Parser( -""" -int d = -1; -while (1) { - int i = (arg & 7) + (9223372036854775807 - 7); - if (arg & 1) i = ((arg&3) + (9223372036854775807 - 3)) & d; - return i + -1; -} -"""); - StopNode stop = parser.parse(false).iterate(); - assertEquals("return (Phi(Region43,((arg&3)+9223372036854775804),((arg&7)+9223372036854775800))+-1);", stop.toString()); - assertEquals(0x7FFFFFFFFFFFFFF7L, Evaluator.evaluate(stop, 0)); - assertEquals(0x7FFFFFFFFFFFFFFCL, Evaluator.evaluate(stop, 1)); - } - - @Test public void testTypes() { Parser parser = new Parser( """ @@ -309,7 +186,7 @@ f32 ff32 = 3.141592653589793; if( ff32 != 3.1415927410125732) return 5; return 0; """); - StopNode stop = parser.parse().iterate(false); + StopNode stop = parser.parse().iterate(); assertEquals("return 0;", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 0)); } diff --git a/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/src/test/java/com/seaofnodes/simple/Chapter15Test.java new file mode 100644 index 00000000..6ec7cc1a --- /dev/null +++ b/src/test/java/com/seaofnodes/simple/Chapter15Test.java @@ -0,0 +1,351 @@ +package com.seaofnodes.simple; + +import com.seaofnodes.simple.evaluator.Evaluator; +import com.seaofnodes.simple.node.StopNode; +import org.junit.Test; +import org.junit.Ignore; + +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class Chapter15Test { + + @Test + public void testJig() { + Parser parser = new Parser(""" +return 3.14; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return 3.14;", stop.toString()); + assertEquals(3.14, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testLifetime() { + Parser parser = new Parser(""" +u8[] b = new u8[5]; +if (arg) { + b[0] = b[0] + 1; +} else { + b[1] = b[1] * 2; +} +return b[0] + b[1]; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return Phi(Region69,1,0);", stop.toString()); + assertEquals(0L, Evaluator.evaluate(stop, 0)); + assertEquals(1L, Evaluator.evaluate(stop, 1)); + } + + @Test + public void testCyclic() { + Parser parser = new Parser( +""" +struct C { + C? l; +} +C c = new C; +c.l = c; +return c; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return C;", stop.toString()); + assertEquals("Obj<C>@1{l=obj@1}", Evaluator.evaluate(stop, 0).toString()); + } + + @Test + public void testSafetyCheck() { + Parser parser = new Parser( +""" +u8[] old = new u8[0]; +u8[] output = new u8[1]; +int i = 0; +while (i < old#) { + output[i] = old[i]; + i = i + 1; +} +output[i] = 1; +return output; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return u8[];", stop.toString()); + assertEquals("\u0001", Evaluator.evaluate(stop, 0).toString()); + } + + @Test + public void testBasic1() { + Parser parser = new Parser( +""" +int[] is = new int[2]; +return is[1]; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return 0;", stop.toString()); + assertEquals(0L, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testBasic2() { + Parser parser = new Parser( +""" +int[] is = new int[2]; +int[] is2 = new int[2]; +return is[1]; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return 0;", stop.toString()); + assertEquals(0L, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testBasic3() { + Parser parser = new Parser( +""" +int[] a = new int[2]; +a[0] = 1; +a[1] = 2; +return a[0]; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return 1;", stop.toString()); + assertEquals(1L, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testBasic4() { + Parser parser = new Parser( +""" +struct A { int i; } +A?[] a = new A?[2]; +return a; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return *A?[];", stop.toString()); + assertEquals("Obj<*A?[]>{#=2,[]=[null,null]}", Evaluator.evaluate(stop, 0).toString()); + } + + @Test + public void testBasic5() { + Parser parser = new Parser( +""" +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]; +iss[0][2] = s; + +// Now pull out the filled-in value, with null checks +flt rez; +S?[]? is = iss[arg]; +if( !is ) rez = 1.2; +else { + S? i = is[2]; + if( !i ) rez = 2.3; + else rez = i.y; +} +return rez; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return Phi(Region118,1.2,Phi(Region115,2.3,.y));", stop.toString()); + assertEquals(3.14, Evaluator.evaluate(stop, 0)); + } + + @Ignore + @Test + public void testBasic6() { + Parser parser = new Parser( +""" +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]; +iss[0][2] = s; + +// Now pull out the filled-in value, with null checks +flt rez = 1.2; +if( iss[arg] ) + if( iss[arg][2] ) + rez = iss[arg][2].y; +return rez; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return Phi(Region122,Phi(Region118,.y,1.2),1.2);", stop.toString()); + assertEquals(3.14, Evaluator.evaluate(stop, 0)); + } + + @Test + public void testTree() { + Parser parser = new Parser( +""" +// Can we define a forward-reference array? +struct Tree { Tree?[] _kids; } +Tree root = new Tree; +root._kids = new Tree?[2]; +root._kids[0] = new Tree; +return root; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return Tree;", stop.toString()); + assertEquals("Obj<Tree>{_kids=Obj<*Tree?[]>{#=2,[]=[Obj<Tree>{_kids=null},null]}}", Evaluator.evaluate(stop, 0).toString()); + } + + @Test + public void testNestedStructAddMemProj() { + Parser parser = new Parser( +""" +struct S { + int a; + int[] b; +} +return 0; +"""); + StopNode stop = parser.parse(); + assertEquals("return 0;", stop.toString()); + } + + @Test + public void testRollingSum() { + Parser parser = new Parser( +""" +int[] ary = new int[arg]; +// Fill [0,1,2,3,4,...] +int i=0; +while( i < ary# ) { + ary[i] = i; + i = i+1; +} +// Fill [0,1,3,6,10,...] +i=0; +while( i < ary# - 1 ) { + ary[i+1] = ary[i+1] + ary[i]; + i = i+1; +} +return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6 +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return (.[]+(.[]*1000));", stop.toString()); + assertEquals(1006L, Evaluator.evaluate(stop, 4)); + } + + @Test + public void sieveOEratosthenes() { + Parser parser = new Parser( +""" +int[] ary = new int[arg]; +int[] primes = new int[arg]; +int nprimes = 0; +// Find primes +int j=2; +while( j*j < arg ) { + while( ary[j]==1 ) j = j + 1; + // j is now a prime + primes[nprimes] = j; nprimes = nprimes + 1; + // Mark out the rest non-primes + int i = j + j; + while( i < ary# ) { + ary[i] = 1; + i = i + j; + } + j = j + 1; +} +// Now just collect the remaining primes +while( j < arg ) { + if( ary[j] == 0 ) { + primes[nprimes] = j; nprimes = nprimes + 1; + } + j = j + 1; +} +// Shrink the result array to size +int[] rez = new int[nprimes]; +j = 0; +while( j < nprimes ) { + rez[j] = primes[j]; + j = j + 1; +} + +return rez; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return int[];", stop.toString()); + Evaluator.Obj obj = (Evaluator.Obj)Evaluator.evaluate(stop, 20); + assertEquals("int[] {\n # :int;\n [] :int;\n}",obj.struct().toString()); + long nprimes = (Long)obj.fields()[0]; + long[] primes = new long[]{2,3,5,7,11,13,17,19}; + for( int i=0; i<nprimes; i++ ) + assertEquals(primes[i],(long)(Long)obj.fields()[i+1]); + } + + @Test + public void testNewNodeInit() { + Parser parser = new Parser( +""" +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; +return s1.i + s1.f; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return ((flt).i+.f);", stop.toString()); + assertEquals(0.0, Evaluator.evaluate(stop, 0)); + } + + + @Test + public void testBad0() { + Parser parser = new Parser( +""" +return new flt; +"""); + try { parser.parse().iterate(); fail(); } + catch( Exception e ) { assertEquals("Cannot allocate a flt",e.getMessage()); } + } + + @Test + public void testBad1() { + Parser parser = new Parser( +""" +int is = new int[2]; +"""); + try { parser.parse().iterate(); fail(); } + catch( Exception e ) { assertEquals("Type *int[] is not of declared type int",e.getMessage()); } + } + + @Test + public void testBad2() { + Parser parser = new Parser( +""" +int[] is = new int[3.14]; +return is[1]; +"""); + try { parser.parse().iterate(); fail(); } + catch( Exception e ) { assertEquals("Cannot allocate an array with length 3.14",e.getMessage()); } + } + + @Test + public void testBad3() { + Parser parser = new Parser( +""" +int[] is = new int[arg]; +return is[1]; +"""); + StopNode stop = parser.parse().iterate(); + assertEquals("return 0;", stop.toString()); + assertEquals(0L, Evaluator.evaluate(stop, 4)); + try { Evaluator.evaluate(stop,0); } + catch( ArrayIndexOutOfBoundsException e ) { assertEquals("Array index 1 out of bounds for array length 0",e.getMessage()); } + try { Evaluator.evaluate(stop,-1); } + catch( NegativeArraySizeException e ) { assertEquals("-1",e.getMessage()); } + } + +} diff --git a/src/test/java/com/seaofnodes/simple/TypeTest.java b/src/test/java/com/seaofnodes/simple/TypeTest.java index 9e8a1418..cb45a0d7 100644 --- a/src/test/java/com/seaofnodes/simple/TypeTest.java +++ b/src/test/java/com/seaofnodes/simple/TypeTest.java @@ -13,32 +13,32 @@ public class TypeTest { @Test public void testTypeAdHoc() { TypeStruct s1 = TypeStruct.make("s1", new Field[]{ - Field.make("a", TypeInteger.BOT), - Field.make("b", TypeInteger.BOT) }); + Field.make("a",-1, TypeInteger.BOT), + Field.make("b",-2, TypeInteger.BOT) }); TypeStruct s2 = TypeStruct.make("s2", new Field[]{ - Field.make("a", TypeInteger.BOT), - Field.make("b", TypeInteger.BOT) }); + Field.make("a",-3, TypeInteger.BOT), + Field.make("b",-4, TypeInteger.BOT) }); Assert.assertEquals(s1, s1.glb()); Assert.assertNotEquals(s1, s1.dual()); Assert.assertEquals(s1, s1.dual().glb()); - TypeMem m1 = TypeMem.make(1); - TypeMem m2 = TypeMem.make(2); - TypeMem m3 = TypeMem.make(3); - TypeMem m4 = TypeMem.make(4); + TypeMem m1 = TypeMem.make(1,TypeInteger.ZERO); + TypeMem m2 = TypeMem.make(2,TypeInteger.U16); + TypeMem m3 = TypeMem.make(3,TypeFloat.BOT); + TypeMem m4 = TypeMem.make(4,TypeInteger.BOT); Assert.assertNotEquals(m1, m2); Assert.assertNotEquals(m2, m3); Assert.assertNotEquals(m3, m4); Assert.assertEquals(TypeStruct.BOT, s1.meet(s2)); - Assert.assertEquals(TypeMem .BOT, m1.meet(m2)); + Assert.assertEquals(TypeMem.make(-1,TypeInteger.U16), m1.meet(m2)); Assert.assertEquals(TypeMem .BOT, m2.meet(m3)); Assert.assertEquals(TypeMem .BOT, m3.meet(m4)); - Assert.assertEquals(m1, m1.glb()); - Assert.assertEquals(TypeMem.make(1), m1.dual()); - Assert.assertEquals(m1.dual(), m1.glb().dual()); + Assert.assertEquals(TypeMem.make(1,TypeInteger.BOT), m1.glb()); + Assert.assertEquals(TypeMem.make(1,TypeInteger.ZERO), m1.dual()); + Assert.assertEquals(m4.dual(), m4.glb().dual()); TypeMemPtr ptr1 = TypeMemPtr.make(s1); Assert.assertEquals(s1, ptr1._obj); @@ -58,12 +58,12 @@ public class TypeTest { Assert.assertEquals(ptr1, ptr1.dual().dual()); Assert.assertEquals(ptr1.glb(), ptr1.dual().glb()); - Assert.assertEquals(TypeMemPtr.BOT, ptr1.meet(ptr2nil)); + Assert.assertEquals(TypeMemPtr.make(TypeStruct.BOT,true), ptr1.meet(ptr2nil)); Assert.assertEquals(ptr1.glb(), ptr1.meet(TypeMemPtr.NULLPTR)); TypeMemPtr TOP = TypeMemPtr.TOP; - TypeMemPtr BOT = TypeMemPtr.BOT; - TypeMemPtr PTR = TypeMemPtr.VOIDPTR; + TypeMemPtr BOT = TypeMemPtr.make(TypeStruct.BOT,true ); + TypeMemPtr PTR = TypeMemPtr.make(TypeStruct.BOT,false); TypeMemPtr NULL = TypeMemPtr.NULLPTR; Type PTR_meet_NULL = NULL.meet(PTR); Assert.assertEquals(BOT, PTR_meet_NULL); diff --git a/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java b/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java index 31a14c05..34921b94 100644 --- a/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java +++ b/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java @@ -6,27 +6,119 @@ import com.seaofnodes.simple.type.*; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Objects; +import java.util.*; public class Evaluator { private static final Object MEMORY = new Object(); public record Obj(TypeStruct struct, Object[] fields) { + private void init(IdentityHashMap<Obj, Integer> objs) { + var oid = objs.get(this); + if (oid != null) { + if (oid != 0) objs.put(this, 0); + return; + } + objs.put(this, -1); + for (var obj : fields) { + if (obj instanceof Obj o) o.init(objs); + } + } + private static int p(StringBuilder sb, IdentityHashMap<Obj, Integer> objs, int id, String indentation, String step, String sep, Object obj) { + if (obj instanceof Obj o) return o.p(sb, objs, id, indentation, step, sep); + sb.append(obj); + return id; + } + private int p(StringBuilder sb, IdentityHashMap<Obj, Integer> objs, int id, String indentation, String step, String sep) { + var cid = objs.get(this); + assert cid != null; + if (cid > 0) { + sb.append("obj@").append(cid); + return id; + } + if (struct._name.equals("u8[]")) { + sb.append('"'); + for (int i=struct._fields.length-1; i<fields.length; i++) { + var v = fields[i]; + if (v == null) v = 0; + assert v instanceof Number; + var n = ((Number)v).byteValue() & 0xFF; + if (n >= 0x20 && n < 0x80) { + if (n == 0x22 || n == 0x5C) sb.append("\\"); + sb.append((char)n); + } else { + sb.append("\\x").append("0123456789abcdef".charAt(n >> 4)).append("0123456789abcdef".charAt(n & 0xF)); + } + } + sb.append('"'); + return id; + } + sb.append("Obj<").append(struct._name).append(">"); + if (cid == 0) { + cid = id++; + objs.put(this, cid); + sb.append("@").append(cid); + } + sb.append("{"); + if (struct._fields.length == 0) { + assert !struct.isAry(); + sb.append("}"); + return id; + } + String nextIndent = indentation + step; + int e = struct._fields.length - 1; + for(int i=0; i<e; i++) { + sb.append(nextIndent).append(struct._fields[i]._fname).append("="); + id = p(sb, objs, id, nextIndent, step, sep, fields[i]); + sb.append(sep); + } + sb.append(nextIndent).append(struct._fields[e]._fname).append("="); + if (struct.isAry()) { + sb.append("["); + if (fields.length > e) { + String innerIndent = nextIndent + step; + sb.append(innerIndent); + id = p(sb, objs, id, nextIndent, step, sep, fields[e]); + for (int i = e+1; i < fields.length; i++) { + sb.append(sep).append(innerIndent); + id = p(sb, objs, id, nextIndent, step, sep, fields[i]); + } + sb.append(nextIndent); + } + sb.append("]"); + } else { + id = p(sb, objs, id, nextIndent, step, sep, fields[e]); + } + sb.append(indentation).append("}"); + return id; + } + private StringBuilder p(StringBuilder sb, String indentation, String step, String sep) { + var objs = new IdentityHashMap<Obj, Integer>(); + init(objs); + p(sb, objs, 1, indentation, step, sep); + return sb; + } @Override public String toString() { - var sb = new StringBuilder(); - sb.append("Obj<").append(struct._name).append("> {"); - for(int i=0; i<struct._fields.length; i++) { - sb.append("\n ").append(struct._fields[i]._fname).append("=").append(fields[i]); + if (struct._name.equals("u8[]")) { + var sb = new StringBuilder(); + for (int i=struct._fields.length-1; i<fields.length; i++) { + var v = fields[i]; + if (v == null) v = 0; + assert v instanceof Number; + var n = ((Number)v).byteValue() & 0xFF; + sb.append((char)n); + } + return sb.toString(); } - return sb.append("\n}").toString(); + return p(new StringBuilder(), "", "", ",").toString(); + } + public String pretty() { + return p(new StringBuilder(), "\n", " ", "").toString(); } } - private static int getFieldIndex(TypeStruct struct, MemOpNode memop) { + private static int getFieldIndex(TypeStruct struct, MemOpNode memop, long off) { int idx = struct.find(memop._name); if( idx >= 0 ) return idx; throw new AssertionError("Field "+memop._name+" not found in struct " + struct._name); @@ -82,22 +174,82 @@ public class Evaluator { return in2 == 0 ? 0 : vald(div.in(1)) / in2; } + private static long offToIdx(long off, TypeStruct t) { + off -= t.aryBase(); + int scale = t.aryScale(); + long mask = (1L << scale)-1; + assert (off & mask) == 0; + return off>>scale; + } + private Object alloc(NewNode alloc) { - var type = ((TypeMemPtr)alloc.compute())._obj; - return new Obj(type, new Object[type._fields.length]); + TypeStruct type = alloc._ptr._obj; + Object[] body=null; + int num; + if( type.isAry() ) { + long sz = (Long)val(alloc.in(1)); + long n = offToIdx(sz, type); + if( n < 0 ) + throw new NegativeArraySizeException(""+n); + body = new Object[(int)n+1]; // Array body + var c = type._fields[type._fields.length-1]._type; + if (c instanceof TypeInteger) { + for (int i=0; i<n; i++) body[i+type._fields.length-1] = 0L; + } else if (c instanceof TypeFloat) { + for (int i = 0; i < n; i++) body[i+type._fields.length-1] = 0D; + } else { + assert c instanceof TypeMemPtr; + } + num = type._fields.length-1; + } else { + body = new Object[type._fields.length]; + num = type._fields.length; + } + for (int i=0; i<num; i++) { + var c = type._fields[i]._type; + if (c instanceof TypeInteger) { + body[i] = 0L; + } else if (c instanceof TypeFloat) { + body[i] = 0D; + } else { + assert c instanceof TypeMemPtr; + } + } + Object[] mems = new Object[type._fields.length+2]; + // mems[0] is control + mems[1] = new Obj(type,body); // the ref + // mems[2+...] are memory aliases + return mems; } private Object load(LoadNode load) { - var from = (Obj)val(load.in(2)); - var idx = getFieldIndex(from.struct, load); - return from.fields[idx]; + var from = (Obj)val(load.ptr()); + var off = vall(load.off()); + var idx = getFieldIndex(from.struct, load, (Long)off); + if( idx==from.struct._fields.length-1 && from.struct.isAry() ) { + long len = from.fields.length - from.struct._fields.length + 1; + long i = offToIdx(off, from.struct); + if( i < 0 || i >= len ) + throw new ArrayIndexOutOfBoundsException("Array index out of bounds " + i + " < " + len); + return from.fields[(int)i+from.struct._fields.length-1]; + + } else + return from.fields[idx]; } private Object store(StoreNode store) { - var to = (Obj)val(store.in(2)); - var val = val(store.in(3)); - var idx = getFieldIndex(to.struct, store); - to.fields[idx] = val; + var to = (Obj)val(store.ptr()); + var off = vall(store.off()); + var val = val(store.val()); + var idx = getFieldIndex(to.struct, store, (Long)off); + if( idx==to.struct._fields.length-1 && to.struct.isAry() ) { + long len = to.fields.length - to.struct._fields.length + 1; + long i = offToIdx(off, to.struct); + if( i < 0 || i >= len ) + throw new RuntimeException("Array index out of bounds " + off + " <= " + len); + to.fields[(int)i+to.struct._fields.length-1] = val; + } else + to.fields[idx] = val; return null; } diff --git a/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java b/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java index 8b86d67a..59c15d3f 100644 --- a/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java +++ b/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java @@ -155,7 +155,10 @@ public class Scheduler { * @return true if all placed inputs are before this node. */ private boolean isValid(NodeData data) { - return data.node._inputs.stream().map(i->i==null?null:d(i)).map(d->d==null||d.users>0?null:d.block).allMatch(d->d==null||dom(d, data.block)==d); + return data.node._inputs.stream() + .map(i->i==null?null:d(i)) + .map(d->d==null||d.users>0?null:d.block) + .allMatch(d->d==null||dom(d, data.block)==d); } /** @@ -204,7 +207,7 @@ public class Scheduler { * @return true if node is placed during the control flow graph build. */ private static boolean isPinnedNode(NodeData data) { - return data.node.isCFG() || data.node instanceof PhiNode; + return data.node instanceof CFGNode || data.node instanceof PhiNode; } /** @@ -359,7 +362,7 @@ public class Scheduler { while (!queue.isEmpty()) { var data = queue.pop(); var node = data.node; - assert node.isCFG(); + assert node instanceof CFGNode; BasicBlock block; switch (node) { case StartNode s: @@ -399,7 +402,9 @@ public class Scheduler { } } if (!(node instanceof ReturnNode)) - for (Node n:node._outputs) if (n!=null && n.isCFG() && isCFGNodeReady(n) && d(n).block == null) queue.push(d(n)); + for (Node n : node._outputs) + if(n instanceof CFGNode && isCFGNodeReady(n) && d(n).block == null) + queue.push(d(n)); var b = block; for(var in:data.node._inputs) od(in).ifPresent(d->update(d, b)); } @@ -421,7 +426,7 @@ public class Scheduler { if (nd.users>0) nd.users++; return; } - assert node.isCFG() == cfg; + assert node instanceof CFGNode == cfg; assert isNotXCtrl(node); nd = new NodeData(node); if (cfg) nd.users=0; @@ -443,24 +448,24 @@ public class Scheduler { while (!cfgQueue.isEmpty()) { var data = cfgQueue.pop(); node = data.node; - assert node.isCFG(); + assert node instanceof CFGNode; if (!(node instanceof ReturnNode)) { - for (var out : node._outputs) if (out!=null && out.isCFG() && isNotXCtrl(out)) markAlive(cfgQueue, out, true); + for (var out : node._outputs) if (out!=null && out instanceof CFGNode && isNotXCtrl(out)) markAlive(cfgQueue, out, true); } - for (var in : node._inputs) if(in!=null && !in.isCFG() && isNotXCtrl(in)) markAlive(dataQueue, in, false); + for (var in : node._inputs) if(in!=null && !(in instanceof CFGNode) && isNotXCtrl(in)) markAlive(dataQueue, in, false); } // Mark all other nodes. while (!dataQueue.isEmpty()) { var data = dataQueue.pop(); node = data.node; - assert !node.isCFG(); + assert !(node instanceof CFGNode); if (node instanceof PhiNode phi) { var r = phi.in(0); for (int i=1; i<phi.nIns(); i++) { if (od(r.in(i)).isPresent()) markAlive(dataQueue, phi.in(i), false); } } else { - for (var in : node._inputs) if (in != null && !in.isCFG()) markAlive(dataQueue, in, false); + for (var in : node._inputs) if (in != null && !(in instanceof CFGNode)) markAlive(dataQueue, in, false); } if (node instanceof StoreNode) mem.push(data); } @@ -501,8 +506,8 @@ public class Scheduler { for(var n:node._outputs) if (n instanceof CProjNode p && p._idx==0) return p; return null; } - assert node._outputs.stream().filter(Node::isCFG).limit(2).count()<=1; - for(var n:node._outputs) if(n.isCFG()) return n; + assert node._outputs.stream().filter(x -> x instanceof CFGNode).limit(2).count()<=1; + for(var n:node._outputs) if(n instanceof CFGNode) return n; return null; } @@ -546,7 +551,7 @@ public class Scheduler { } if (last instanceof ReturnNode) break; if (last instanceof IfNode if_) { - for(var out:if_._outputs) if (out.isCFG() && blocks.get(out) == null) queue.push(d(out)); + for(var out:if_._outputs) if (out instanceof CFGNode && blocks.get(out) == null) queue.push(d(out)); break; } data = d(last); diff --git a/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java b/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java index ec6e7816..7cd854bf 100644 --- a/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java +++ b/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java @@ -25,7 +25,7 @@ public class ScriptGenerator { private static final int MAX_BLOCK_DEPTH = 4; private static final int MAX_EXPRESSION_DEPTH = 10; private static final int MAX_SUFFIX_RECURSIVE_DEPTH = 10; - + /** * Number of spaces per indentation */ @@ -109,8 +109,8 @@ public class ScriptGenerator { static { new Parser("", TypeInteger.BOT); - for(var e:Parser.TYPES.entrySet()) { - if (e.getValue() instanceof TypeInteger) { + for( var e : Parser.TYPES.entrySet() ) { + if( e.getValue() instanceof TypeInteger ) { INTTYPES.add(new TypeInt(e.getKey())); } } |
