summaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-10-21 09:25:15 -0700
committerCliff Click <cliffc@acm.org>2025-04-24 14:38:36 -0700
commit9a0a1ed86d9cd988218bc3fe603675d62979b814 (patch)
tree2c31bea8c269b0431b70d496a8a54bdf8ccc8cb5 /src/test/java
parentdce83f82262cd339e40c69f9545f3729f535e965 (diff)
downloadSimple-9a0a1ed86d9cd988218bc3fe603675d62979b814.tar.gz
Simple-9a0a1ed86d9cd988218bc3fe603675d62979b814.zip
Chapter 17: Syntax Sugar
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>
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/com/seaofnodes/simple/BrainFuckTest.java54
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter01Test.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter03Test.java4
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter04Test.java4
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter05Test.java19
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter06Test.java10
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter07Test.java38
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter08Test.java18
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter09Test.java10
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter10Test.java46
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter11Test.java40
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter12Test.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter13Test.java26
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter14Test.java6
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter15Test.java74
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter16Test.java99
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter17Test.java500
-rw-r--r--src/test/java/com/seaofnodes/simple/SchedulerTest.java6
-rw-r--r--src/test/java/com/seaofnodes/simple/TypeTest.java6
-rw-r--r--src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java3
20 files changed, 758 insertions, 209 deletions
diff --git a/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
index d5ffe835..88d79215 100644
--- a/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
+++ b/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
@@ -15,7 +15,7 @@ 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("];");
+ 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(";");
@@ -23,54 +23,46 @@ public class BrainFuckTest {
Parser parser = new Parser(
encoded + """
-int pc = 0;
-int d = 0;
-u8[] data = new u8[100];
-u8[] output = new u8[0];
+var d = 0;
+u8[] !output = new u8[0];
+u8[] !data = new u8[100];
-while (pc < program#) {
- int command = program[pc];
+for( int pc = 0; pc < program#; pc++ ) {
+ var command = program[pc];
if (command == 62) {
- d = d + 1;
+ d++;
} else if (command == 60) {
- d = d - 1;
+ d--;
} else if (command == 43) {
- data[d] = data[d] + 1;
+ data[d]++;
} else if (command == 45) {
- data[d] = data[d] - 1;
+ data[d]--;
} else if (command == 46) {
- u8[] old = output;
+ // Output a byte; increase the output array size
+ var old = output;
output = new u8[output# + 1];
- int i = 0;
- while (i < old#) {
+ for( var i = 0; i < old#; i++ )
output[i] = old[i];
- i = i + 1;
- }
- output[i] = data[d];
+ output[old#] = data[d]; // Add the extra byte on the end
} 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;
+ for( var d = 1; d > 0; ) {
+ command = program[++pc];
+ if (command == 91) d++;
+ if (command == 93) d--;
}
}
} 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;
+ if (data[d]) {
+ for( var d = 1; d > 0; ) {
+ command = program[--pc];
+ if (command == 93) d++;
+ if (command == 91) d--;
}
}
}
- pc = pc + 1;
}
return output;
""");
diff --git a/src/test/java/com/seaofnodes/simple/Chapter01Test.java b/src/test/java/com/seaofnodes/simple/Chapter01Test.java
index c10dc510..f7524c17 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter01Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter01Test.java
@@ -58,7 +58,7 @@ public class Chapter01Test {
@Test
public void testNotBad3() {
// this test used to fail in chapter 1
- assertEquals("return 12;", new Parser("return --12;").parse().print());
+ assertEquals("return 12;", new Parser("return - -12;").parse().print());
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter03Test.java b/src/test/java/com/seaofnodes/simple/Chapter03Test.java
index 64ff153e..2de0b46e 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter03Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter03Test.java
@@ -31,7 +31,7 @@ public class Chapter03Test {
@Test
public void testVarScopeNoPeephole() {
- Parser parser = new Parser("int a=1; int b=2; int c=0; { int b=3; c=a+b; } return c; ");
+ Parser parser = new Parser("int a=1; int b=2; int !c=0; { int b=3; c=a+b; } return c; ");
Node._disablePeephole = true;
StopNode ret = parser.parse();
Node._disablePeephole = false;
@@ -68,7 +68,7 @@ public class Chapter03Test {
@Test
public void testBad1() {
try {
- new Parser("int a=1; int b=2; int c=0; { int b=3; c=a+b;").parse();
+ new Parser("int a=1; int b=2; int !c=0; { int b=3; c=a+b;").parse();
fail();
} catch( RuntimeException e ) {
assertEquals("Syntax error, expected }: ",e.getMessage());
diff --git a/src/test/java/com/seaofnodes/simple/Chapter04Test.java b/src/test/java/com/seaofnodes/simple/Chapter04Test.java
index 80cdb3f2..0db3afde 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter04Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter04Test.java
@@ -96,14 +96,14 @@ public class Chapter04Test {
@Test
public void testBug1() {
- Parser parser = new Parser("int a=arg+1; int b=a; b=1; return a+2; ");
+ Parser parser = new Parser("int a=arg+1; int !b=a; b=1; return a+2; ");
StopNode ret = parser.parse();
assertEquals("return (arg+3);", ret.print());
}
@Test
public void testBug2() {
- Parser parser = new Parser("int a=arg+1; a=a; return a; ");
+ Parser parser = new Parser("int !a=arg+1; a=a; return a; ");
StopNode ret = parser.parse();
assertEquals("return (arg+1);", ret.print());
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter05Test.java b/src/test/java/com/seaofnodes/simple/Chapter05Test.java
index b5920125..9afb8f28 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter05Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter05Test.java
@@ -17,12 +17,11 @@ if (arg == 1)
a = arg+2;
else {
a = arg-3;
-
}
-
-return a;""");
+return a;
+""");
StopNode ret = parser.parse().iterate();
- assertEquals("return Phi(Region23,(arg+2),(arg-3));", ret.toString());
+ assertEquals("return Phi(Region,(arg+2),(arg-3));", ret.toString());
}
@Test
@@ -37,7 +36,7 @@ if (arg == 1) {
}
return c;""", TypeInteger.BOT);
StopNode ret = parser.parse().iterate();
- assertEquals("return Phi(Region22,4,3);", ret.toString());
+ assertEquals("return Phi(Region,4,3);", ret.toString());
}
@Test
@@ -65,7 +64,7 @@ else
b=a+1;
return a+b;""");
StopNode ret = parser.parse().iterate();
- assertEquals("return ((arg*2)+Phi(Region26,2,3));", ret.toString());
+ assertEquals("return ((arg*2)+Phi(Region,2,3));", ret.toString());
}
@Test
@@ -80,7 +79,7 @@ else
a=b+1;
return a+b;""");
StopNode ret = parser.parse().iterate();
- assertEquals("return ((Phi(Region37,(arg*2),arg)+arg)+Phi(Region,4,5));", ret.toString());
+ assertEquals("return ((Phi(Region,(arg*2),arg)+arg)+Phi(Region,4,5));", ret.toString());
}
@Test
@@ -100,7 +99,7 @@ else
return a;
""", TypeInteger.BOT);
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region43,Phi(Region28,2,3),Phi(Region41,4,5));", stop.toString());
+ assertEquals("return Phi(Region,Phi(Region,2,3),Phi(Region,4,5));", stop.toString());
}
@Test
@@ -116,7 +115,7 @@ if( arg==0 )
return arg+a+b;
""", TypeInteger.BOT);
StopNode stop = parser.parse();
- assertEquals("return ((arg+Phi(Region20,1,0))+Phi(Region37,2,0));", stop.toString());
+ assertEquals("return ((arg+Phi(Region,1,0))+Phi(Region,2,0));", stop.toString());
}
@Test
@@ -130,7 +129,7 @@ if( arg==1 )
}
return a;""");
StopNode ret = parser.parse().iterate();
- assertEquals("return (arg==Phi(Region22,3,2));", ret.toString());
+ assertEquals("return (arg==Phi(Region,3,2));", ret.toString());
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter06Test.java b/src/test/java/com/seaofnodes/simple/Chapter06Test.java
index ff1f3251..50c0580d 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(Region43,42,5);", stop.toString());
+ assertEquals("return Phi(Region,42,5);", stop.toString());
}
@Test
@@ -84,7 +84,7 @@ else
b=5;
return b;""", TypeInteger.BOT);
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region38,2,5);", stop.toString());
+ assertEquals("return Phi(Region,2,5);", stop.toString());
}
@Test
@@ -144,7 +144,7 @@ else
return a;
""", TypeInteger.BOT);
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region48,3,Phi(Region46,4,5));", stop.toString());
+ assertEquals("return Phi(Region,3,Phi(Region,4,5));", stop.toString());
}
@Test
@@ -200,7 +200,7 @@ if( arg ) {
return a+b;
""");
StopNode ret = parser.parse().iterate();
- assertEquals("return Phi(Region35,4,1);", ret.toString());
+ assertEquals("return Phi(Region,4,1);", ret.toString());
}
@@ -251,7 +251,7 @@ if( arg ) {
return a+b+c;
""");
StopNode ret = parser.parse().iterate();
- assertEquals("return (Phi(Region48,Phi(Region29,2,3),0)+Phi(Region,3,1));", ret.toString());
+ assertEquals("return (Phi(Region,Phi(Region,2,3),0)+Phi(Region,3,1));", ret.toString());
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter07Test.java b/src/test/java/com/seaofnodes/simple/Chapter07Test.java
index b54c24a3..355bbba4 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter07Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter07Test.java
@@ -10,15 +10,15 @@ public class Chapter07Test {
@Test
public void testExample() {
Parser parser = new Parser(
- """
- while(arg < 10) {
- arg = arg + 1;
- }
- return arg;
- """);
+"""
+while(arg < 10) {
+ arg = arg + 1;
+}
+return arg;
+""");
Node._disablePeephole = true;
StopNode stop = parser.parse();
- assertEquals("return Phi(Loop10,arg,(Phi_arg+1));", stop.toString());
+ assertEquals("return Phi(Loop,arg,(Phi_arg+1));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
Node._disablePeephole = false;
}
@@ -36,7 +36,7 @@ if(arg){}else{
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region31,1,Phi(Loop18,1,(Phi_a+1)));", stop.toString());
+ assertEquals("return Phi(Region,1,Phi(Loop,1,(Phi_a+1)));", stop.toString());
}
@Test
@@ -56,7 +56,7 @@ while(i < arg) {
return sum;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop12,0,Phi(Loop26,Phi_sum,(Phi_sum+Phi(Loop,0,(Phi_j+1)))));", stop.toString());
+ assertEquals("return Phi(Loop,0,Phi(Loop,Phi_sum,(Phi_sum+Phi(Loop,0,(Phi_j+1)))));", stop.toString());
}
@Test
@@ -73,7 +73,7 @@ return b;
""");
Node._disablePeephole = true;
StopNode stop = parser.parse();
- assertEquals("return Phi(Loop12,2,Phi(Region34,Phi_b,4));", stop.toString());
+ assertEquals("return Phi(Loop,2,Phi(Region,Phi_b,4));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
Node._disablePeephole = false;
}
@@ -93,7 +93,7 @@ while(a < 10) {
return b;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop12,2,(Phi(Region34,Phi_b,4)+1));", stop.toString());
+ assertEquals("return Phi(Loop,2,(Phi(Region,Phi_b,4)+1));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
@@ -111,7 +111,7 @@ return a;
""");
Node._disablePeephole = true;
StopNode stop = parser.parse();
- assertEquals("return Phi(Loop11,1,((Phi_a+1)+2));", stop.toString());
+ assertEquals("return Phi(Loop,1,((Phi_a+1)+2));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
Node._disablePeephole = false;
}
@@ -128,7 +128,7 @@ while(a < 10) {
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop11,1,(Phi_a+3));", stop.toString());
+ assertEquals("return Phi(Loop,1,(Phi_a+3));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
@@ -142,7 +142,7 @@ return a;
""");
Node._disablePeephole = true;
StopNode stop = parser.parse();
- assertEquals("return Phi(Loop11,1,2);", stop.toString());
+ assertEquals("return Phi(Loop,1,2);", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
Node._disablePeephole = false;
}
@@ -156,7 +156,7 @@ while(arg) a = 2;
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop11,1,2);", stop.toString());
+ assertEquals("return Phi(Loop,1,2);", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
@@ -173,7 +173,7 @@ return a;
""");
Node._disablePeephole = true;
StopNode stop = parser.parse();
- assertEquals("return Phi(Loop11,1,((Phi_a+1)+2));", stop.toString());
+ assertEquals("return Phi(Loop,1,((Phi_a+1)+2));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
Node._disablePeephole = false;
}
@@ -190,7 +190,7 @@ while(a < 10) {
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop11,1,(Phi_a+3));", stop.toString());
+ assertEquals("return Phi(Loop,1,(Phi_a+3));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
@@ -208,7 +208,7 @@ return a;
""");
Node._disablePeephole = true;
StopNode stop = parser.parse();
- assertEquals("return Phi(Loop12,1,((Phi_a+1)+2));", stop.toString());
+ assertEquals("return Phi(Loop,1,((Phi_a+1)+2));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
Node._disablePeephole = false;
}
@@ -226,7 +226,7 @@ while(a < 10) {
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop12,1,(Phi_a+3));", stop.toString());
+ assertEquals("return Phi(Loop,1,(Phi_a+3));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter08Test.java b/src/test/java/com/seaofnodes/simple/Chapter08Test.java
index c199b78c..bb3bd674 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter08Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter08Test.java
@@ -23,7 +23,7 @@ while(arg < 10) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region45,Phi(Region32,Phi(Loop10,arg,(Phi_arg+1)),Add),Add);", stop.toString());
+ assertEquals("return Phi(Region,Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add),Add);", stop.toString());
assertTrue(stop.ret().ctrl() instanceof RegionNode);
Assert.assertEquals(5L, Evaluator.evaluate(stop, 1));
Assert.assertEquals(10L, Evaluator.evaluate(stop, 6));
@@ -46,7 +46,7 @@ while(arg < 10) {
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop11,1,Phi(Region52,Phi_a,(Phi_a+1)));", stop.toString());
+ assertEquals("return Phi(Loop,1,Phi(Region,Phi_a,(Phi_a+1)));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
@@ -65,7 +65,7 @@ while(arg < 10) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region43,Phi(Loop10,arg,(Phi_arg+1)),Add);", stop.toString());
+ assertEquals("return Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add);", stop.toString());
assertTrue(stop.ret().ctrl() instanceof RegionNode);
}
@@ -81,7 +81,7 @@ while(arg < 10) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region32,Phi(Loop10,arg,(Phi_arg+1)),Add);", stop.toString());
+ assertEquals("return Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add);", stop.toString());
assertTrue(stop.ret().ctrl() instanceof RegionNode);
}
@@ -100,7 +100,7 @@ while(arg < 10) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop10,arg,(Phi_arg+1));", stop.toString());
+ assertEquals("return Phi(Loop,arg,(Phi_arg+1));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
@@ -117,7 +117,7 @@ while(arg < 10) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop10,arg,(Phi_arg+1));", stop.toString());
+ assertEquals("return Phi(Loop,arg,(Phi_arg+1));", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode);
}
@@ -138,7 +138,7 @@ return arg;
@Test
public void testRegress2() {
- Parser parser = new Parser("if(1) return 0; else while(arg>--arg) arg=arg+1; return 0;");
+ Parser parser = new Parser("if(1) return 0; else while(arg>- -arg) arg=arg+1; return 0;");
StopNode stop = parser.parse().iterate();
assertEquals("return 0;", stop.toString());
}
@@ -185,7 +185,7 @@ while(arg < 10) {
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region35,Phi(Loop11,1,(Phi_a+1)),Add);", stop.toString());
+ assertEquals("return Phi(Region,Phi(Loop,1,(Phi_a+1)),Add);", stop.toString());
assertTrue(stop.ret().ctrl() instanceof RegionNode);
}
@@ -201,7 +201,7 @@ while(1) {
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return (Phi(Loop11,1,Add)+1);", stop.toString());
+ assertEquals("return (Phi(Loop,1,Add)+1);", stop.toString());
assertTrue(stop.ret().ctrl() instanceof CProjNode prj && prj._idx==1 );
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter09Test.java b/src/test/java/com/seaofnodes/simple/Chapter09Test.java
index b1d9d6e5..c31afcd6 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter09Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter09Test.java
@@ -69,7 +69,7 @@ while (arg < 10) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop11,arg,(Phi_arg+2));", stop.toString());
+ assertEquals("return Phi(Loop,arg,(Phi_arg+2));", stop.toString());
Assert.assertEquals(11L, Evaluator.evaluate(stop, 1));
}
@@ -86,7 +86,7 @@ while (arg < 10) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop12,arg,(Phi_arg+4));", stop.toString());
+ assertEquals("return Phi(Loop,arg,(Phi_arg+4));", stop.toString());
Assert.assertEquals(13L, Evaluator.evaluate(stop, 1));
}
@@ -115,7 +115,7 @@ while (arg) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop18,arg,(Phi_arg+1));", stop.toString());
+ assertEquals("return 0;", stop.toString());
}
@Test
@@ -185,7 +185,7 @@ while(arg) {
return a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop13,0,(-(Phi_a+3)));", stop.toString());
+ assertEquals("return Phi(Loop,0,(-(Phi_a+3)));", stop.toString());
}
@Test
@@ -283,7 +283,7 @@ return v1+v0;
public void testFuzz8() {
Parser parser = new Parser("while(arg) arg = arg - 1; return arg;");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop10,arg,(Phi_arg-1));", stop.toString());
+ assertEquals("return 0;", stop.toString());
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/src/test/java/com/seaofnodes/simple/Chapter10Test.java
index 2a33031d..d41c83d8 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter10Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter10Test.java
@@ -44,7 +44,7 @@ struct Foo {
int x;
};
Foo? foo = null;
-Bar bar = new Bar;
+Bar !bar = new Bar;
bar.a = 1;
bar.a = 2;
return bar.a;
@@ -57,7 +57,7 @@ return bar.a;
public void testExample() {
Parser parser = new Parser("""
struct Vector2D { int x; int y; };
-Vector2D v = new Vector2D;
+Vector2D !v = new Vector2D;
v.x = 1;
if (arg)
v.y = 2;
@@ -96,7 +96,7 @@ arg=0+new s0.0;
public void testLoop() {
Parser parser = new Parser("""
struct Bar { int a; };
-Bar bar = new Bar;
+Bar !bar = new Bar;
while (arg) {
bar.a = bar.a + 2;
arg = arg + 1;
@@ -104,14 +104,14 @@ while (arg) {
return bar.a;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop16,0,(Phi_a+2));", stop.toString());
+ assertEquals("return Phi(Loop,0,(Phi_a+2));", stop.toString());
}
@Test
public void testIf() {
Parser parser = new Parser("""
struct Bar { int a; };
-Bar bar = new Bar;
+Bar !bar = new Bar;
if (arg) bar = null;
bar.a = 1;
return bar.a;
@@ -124,7 +124,7 @@ return bar.a;
public void testIf2() {
Parser parser = new Parser("""
struct Bar { int a; };
-Bar? bar = null;
+Bar? !bar = null;
if (arg) bar = new Bar;
bar.a = 1;
return bar.a;
@@ -150,13 +150,13 @@ return bar.a;
public void testIfOrNull() {
Parser parser = new Parser("""
struct Bar { int a; };
-Bar? bar = new Bar;
+Bar? !bar = new Bar;
if (arg) bar = null;
if( bar ) bar.a = 1;
return bar;
""");
StopNode stop = parser.parse(false).iterate();
- assertEquals("return Phi(Region38,(*void)Phi(Region24,null,Bar),null);", stop.toString());
+ assertEquals("return Phi(Region,(*void)Phi(Region,null,Bar),null);", stop.toString());
}
@Test
@@ -164,7 +164,7 @@ return bar;
Parser parser = new Parser(
"""
struct Bar { int a; };
-Bar? bar = new Bar;
+Bar? !bar = new Bar;
if (arg) bar = null;
int rez = 3;
if( !bar ) rez=4;
@@ -172,14 +172,14 @@ else bar.a = 1;
return rez;
""");
StopNode stop = parser.parse(false).iterate();
- assertEquals("return Phi(Region44,4,3);", stop.toString());
+ assertEquals("return Phi(Region,4,3);", stop.toString());
}
@Test
public void testWhileWithNullInside() {
Parser parser = new Parser("""
struct s0 {int v0;};
-s0? v0 = new s0;
+s0? !v0 = new s0;
int ret = 0;
while(arg) {
ret = v0.v0;
@@ -216,7 +216,7 @@ struct Iter {
int x;
int len;
};
-Iter i = new Iter;
+Iter !i = new Iter;
i.len = arg;
int sum=0;
while( i.x < i.len ) {
@@ -226,7 +226,7 @@ while( i.x < i.len ) {
return sum;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop21,0,(Phi(Loop,0,(Phi_x+1))+Phi_sum));", stop.toString());
+ assertEquals("return Phi(Loop,0,(Phi(Loop,0,(Phi_x+1))+Phi_sum));", stop.toString());
}
@@ -234,9 +234,9 @@ return sum;
public void test1() {
Parser parser = new Parser("""
struct s0 {int v0;};
-s0 ret = new s0;
+s0 !ret = new s0;
while(arg) {
- s0 v0 = new s0;
+ s0 !v0 = new s0;
v0.v0 = arg;
arg = arg-1;
if (arg==5) ret=v0;
@@ -245,15 +245,15 @@ while(arg) {
return ret;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop16,s0,Phi(Region43,s0,Phi_ret));", stop.toString());
+ assertEquals("return Phi(Loop,s0,Phi(Region,s0,Phi_ret));", stop.toString());
}
@Test
public void test2() {
Parser parser = new Parser("""
struct s0 {int v0;};
-s0 ret = new s0;
-s0 v0 = new s0;
+s0 !ret = new s0;
+s0 !v0 = new s0;
while(arg) {
v0.v0 = arg;
arg = arg-1;
@@ -263,7 +263,7 @@ while(arg) {
return ret;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop20,s0,Phi(Region44,s0,Phi_ret));", stop.toString());
+ assertEquals("return Phi(Loop,s0,Phi(Region,s0,Phi_ret));", stop.toString());
}
@@ -271,16 +271,16 @@ return ret;
public void test3() {
Parser parser = new Parser("""
struct s0 {int v0;};
-s0 ret = new s0;
+s0 !ret = new s0;
while(arg < 10) {
- s0 v0 = new s0;
+ s0 !v0 = new s0;
if (arg == 5) ret=v0;
arg = arg + 1;
}
return ret;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop16,s0,Phi(Region41,s0,Phi_ret));", stop.toString());
+ assertEquals("return Phi(Loop,s0,Phi(Region,s0,Phi_ret));", stop.toString());
}
@Test
@@ -350,7 +350,7 @@ s0 v1 = v0;
return v1;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return s0;", stop.toString());
+ assertEquals("return (const)s0;", stop.toString());
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/src/test/java/com/seaofnodes/simple/Chapter11Test.java
index d6b7bb00..613b979b 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter11Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter11Test.java
@@ -14,7 +14,7 @@ public class Chapter11Test {
public void testFuzzer() {
Parser parser = new Parser(
"""
-while(-----arg) {
+while(---- -arg) {
while(-arg) {
while(-----arg*---0) {
int N=--false==false<--arg;
@@ -103,7 +103,7 @@ while(-----arg) {
int UX=arg;
while(UX<-3*arg) {
UX=UX+arg/-1;
- arg=-3--(-UX--47<arg==--arg==arg)/arg--UX>=-arg;
+ arg=-3--(-UX- -47<arg==--arg==arg)/arg- -UX>=-arg;
if(---12) while(-UX) break;
break;
}
@@ -224,9 +224,9 @@ if(arg!=62==arg) {
}
}
arg=-arg+arg;
- arg=--47+-arg<1>arg*(-arg==-arg--0>3);
+ arg=--47+-arg<1>arg*(-arg==-arg- -0>3);
arg=(----arg)!=arg+--59;
- arg=--4+arg==-(arg)-arg;
+ arg=- -4+arg==-(arg)-arg;
}
else {
while(--true-----true*-25+-18>arg>=-----(-arg)---13) {
@@ -292,7 +292,7 @@ else {
}
""");
StopNode stop = parser.parse().iterate();
- assertEquals("Stop[ return 9; return 0; return 0; ]", stop.toString());
+ assertEquals("Stop[ return 9; return 0; return 0; return 0; return 0; ]", stop.toString());
}
@@ -324,7 +324,7 @@ while( prime <= arg ) {
return primeCount;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("Stop[ return 0; return Phi(Loop23,1,Phi(Region100,Phi_primeCount,Phi(Region93,(Phi_primeCount+1),Phi_primeCount))); ]", stop.toString());
+ assertEquals("Stop[ return 0; return Phi(Loop,1,Phi(Region,Phi_primeCount,Phi(Region,(Phi_primeCount+1),Phi_primeCount))); ]", stop.toString());
assertEquals(0L, Evaluator.evaluate(stop, 1)); // No primes 1 or below
assertEquals(1L, Evaluator.evaluate(stop, 2)); // 2
assertEquals(2L, Evaluator.evaluate(stop, 3)); // 2, 3
@@ -338,7 +338,7 @@ return primeCount;
Parser parser = new Parser(
"""
struct S { int f; };
-S v=new S;
+S !v=new S;
v.f = 2;
int i=new S.f;
i=v.f;
@@ -356,9 +356,9 @@ return i;
Parser parser = new Parser(
"""
struct S { int f; };
-S v = new S;
+S !v = new S;
v.f = arg;
-S t = new S;
+S !t = new S;
int i = 0;
if (arg) {
if (arg+1) v = t;
@@ -369,7 +369,7 @@ if (arg) {
return i;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region45,.f,0);", stop.toString());
+ assertEquals("return Phi(Region,.f,0);", stop.toString());
}
@Test
@@ -377,7 +377,7 @@ return i;
Parser parser = new Parser(
"""
struct S { int f; };
-S v0 = new S;
+S !v0 = new S;
S? v1;
if (arg) v1 = new S;
if (v1) {
@@ -397,7 +397,7 @@ return v0;
Parser parser = new Parser(
"""
struct S { int f; };
-S v = new S;
+S !v = new S;
v.f = arg;
S t = new S;
int i = v.f;
@@ -414,7 +414,7 @@ return i;
Parser parser = new Parser(
"""
struct S { int f; };
-S v = new S;
+S !v = new S;
while(1) {
while(arg+1) { arg=arg-1; }
if (arg) break;
@@ -431,14 +431,14 @@ return v;
Parser parser = new Parser(
"""
struct s { int v; };
-s ptr=new s;
+s !ptr=new s;
while( -arg )
ptr = new s;
while(1)
arg = arg+ptr.v;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("Stop[ return 0; return 0; ]", stop.toString());
+ assertEquals("return 0;", stop.toString());
}
@Test
@@ -446,7 +446,7 @@ while(1)
Parser parser = new Parser(
"""
struct S { int f; };
-S v = new S;
+S !v = new S;
S t = new S;
int i = v.f;
while (arg) {
@@ -464,7 +464,7 @@ return i;
Parser parser = new Parser(
"""
struct S { int f; };
-S v = new S;
+S !v = new S;
S t = new S;
while(arg) {
arg=arg-1;
@@ -476,7 +476,7 @@ while(arg) {
return arg;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop20,arg,Phi(Region48,.f,0));", stop.toString());
+ assertEquals("return 0;", stop.toString());
}
@Test
@@ -484,7 +484,7 @@ return arg;
Parser parser = new Parser(
"""
struct S { int f; };
-S v = new S;
+S !v = new S;
S t = new S;
if (arg) {
v.f=2;
@@ -502,7 +502,7 @@ return v;
Parser parser = new Parser(
"""
struct S { int f; };
-S v = new S;
+S !v = new S;
int i = arg;
while (arg > 0) {
int j = i/3;
diff --git a/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/src/test/java/com/seaofnodes/simple/Chapter12Test.java
index c0f6266a..a70a5f33 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter12Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter12Test.java
@@ -43,7 +43,7 @@ while( 1 ) {
return guess;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop11,(flt)arg,(((ToFloat/Phi_guess)+Phi_guess)/2.0));", stop.toString());
+ assertEquals("return Phi(Loop,(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));
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/src/test/java/com/seaofnodes/simple/Chapter13Test.java
index 73fff8fd..eeb28f1d 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter13Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter13Test.java
@@ -23,9 +23,9 @@ return 3.14;
Parser parser = new Parser(
"""
struct LLI { LLI? next; int i; };
-LLI? head = null;
+LLI? !head = null;
while( arg ) {
- LLI x = new LLI;
+ LLI !x = new LLI;
x.next = head;
x.i = arg;
head = x;
@@ -42,9 +42,9 @@ return head.next.i;
Parser parser = new Parser(
"""
struct LLI { LLI? next; int i; };
-LLI? head = null;
+LLI? !head = null;
while( arg ) {
- LLI x = new LLI;
+ LLI !x = new LLI;
x.next = head;
x.i = arg;
head = x;
@@ -66,9 +66,9 @@ return next.i;
"""
struct int0 { int i; flt0? f; };
struct flt0 { flt f; int0? i; };
-int0 i0 = new int0;
+int0 !i0 = new int0;
i0.i = 17;
-flt0 f0 = new flt0;
+flt0 !f0 = new flt0;
f0.f = 3.14;
i0.f = f0;
f0.i = i0;
@@ -100,7 +100,7 @@ N n = new N { next = new M; };
return n.next;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return M;", stop.toString());
+ assertEquals("return (const)M;", stop.toString());
}
@Test
@@ -121,19 +121,19 @@ return n.next;
Parser parser = new Parser(
"""
struct N { N? next; int i; };
-N n = new N;
+N !n = new N;
n.i = 3.14;
return n.i;
""");
try { parser.parse().iterate(); fail(); }
- catch( Exception e ) { assertEquals("Cannot store 3.14 into field int i",e.getMessage()); }
+ catch( Exception e ) { assertEquals("Type 3.14 is not of declared type int",e.getMessage()); }
}
@Test
public void testNullRef4() {
- Parser parser = new Parser("-null-5/null-5");
+ Parser parser = new Parser("-null-5/null-5;");
try { parser.parse().iterate(); fail(); }
- catch( Exception e ) { assertEquals("Expected an identifier, found 'null'",e.getMessage()); }
+ catch( Exception e ) { assertEquals("Cannot 'Add' null",e.getMessage()); }
}
@Test public void testNullRef5() {
@@ -157,7 +157,7 @@ struct S{};
public void testForwardRef0() {
Parser parser = new Parser(
"""
-struct S1 { S2 s; };
+struct S1 { S2? s; };
return new S2;
""");
try { parser.parse().iterate(); fail(); }
@@ -182,7 +182,7 @@ return new S1.s=new S2;
"""
struct I {int i;};
struct P { I? pi; };
-P p1 = new P;
+P !p1 = new P;
P p2 = new P;
p2.pi = new I;
p2.pi.i = 2;
diff --git a/src/test/java/com/seaofnodes/simple/Chapter14Test.java b/src/test/java/com/seaofnodes/simple/Chapter14Test.java
index 7d7bb25a..23c82358 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter14Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter14Test.java
@@ -59,7 +59,7 @@ while( b ) b = b + 456;// Truncate
return b;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Loop11,123,((Phi_b+456)&255));", stop.toString());
+ assertEquals("return 0;", stop.toString());
}
@Test
@@ -94,7 +94,7 @@ return b;
Parser parser = new Parser(
"""
struct Foo { u1 b; };
-Foo f = new Foo;
+Foo !f = new Foo;
f.b = 123;
return f.b;
""");
@@ -175,7 +175,7 @@ while(v1) break;
return v1;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return (Phi(Loop18,((1<<arg)&1),0)&Phi(Loop,Shl,4294967295));", stop.toString());
+ assertEquals("return (Phi(Loop,((1<<arg)&1),0)&Phi(Loop,Shl,4294967295));", stop.toString());
assertEquals(1L, Evaluator.evaluate(stop, 0));
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/src/test/java/com/seaofnodes/simple/Chapter15Test.java
index 8161862f..4e2682dc 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter15Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter15Test.java
@@ -25,7 +25,7 @@ return 3.14;
Parser parser = new Parser(
"""
struct C { C? l; };
-C c = new C;
+C !c = new C;
c.l = c;
return c;
""");
@@ -39,7 +39,7 @@ return c;
Parser parser = new Parser(
"""
u8[] old = new u8[0];
-u8[] output = new u8[1];
+u8[] !output = new u8[1];
int i = 0;
while (i < old#) {
output[i] = old[i];
@@ -82,7 +82,7 @@ return is[1];
public void testBasic3() {
Parser parser = new Parser(
"""
-int[] a = new int[2];
+int[] !a = new int[2];
a[0] = 1;
a[1] = 2;
return a[0];
@@ -97,7 +97,7 @@ return a[0];
Parser parser = new Parser(
"""
struct A { int i; };
-A?[] a = new A?[2];
+A?[] !a = new A?[2];
return a;
""");
StopNode stop = parser.parse().iterate();
@@ -111,10 +111,10 @@ return a;
"""
struct S { int x; flt y; };
// A new S
-S s = new S; s.x=99; s.y = 3.14;
+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];
+S?[]?[] !iss = new S?[]?[2];
iss[0] = new S?[7];
iss[0][2] = s;
@@ -130,19 +130,18 @@ else {
return rez;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region117,1.2,Phi(Region114,2.3,3.14));", stop.toString());
+ assertEquals("return Phi(Region,1.2,Phi(Region,2.3,3.14));", stop.toString());
assertEquals(3.14, Evaluator.evaluate(stop, 0));
assertEquals(1.2 , Evaluator.evaluate(stop, 1));
}
- @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;
+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];
@@ -156,9 +155,8 @@ if( iss[arg] )
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));
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Might be null accessing 'y'",e.getMessage()); }
}
@Test
@@ -167,8 +165,8 @@ return rez;
"""
// Can we define a forward-reference array?
struct Tree { Tree?[]? _kids; };
-Tree root = new Tree;
-root._kids = new Tree?[2];
+Tree !root = new Tree;
+root._kids = new Tree?[2]; // NO BANG SO ARRAY IS OF IMMUTABLE TREES????
root._kids[0] = new Tree;
return root;
""");
@@ -192,7 +190,7 @@ return 0;
public void testRollingSum() {
Parser parser = new Parser(
"""
-int[] ary = new int[arg];
+int[] !ary = new int[arg];
// Fill [0,1,2,3,4,...]
int i=0;
while( i < ary# ) {
@@ -216,44 +214,42 @@ return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6
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;
+int[] !ary = new int[arg], !primes = new int[arg];
+int nprimes = 0, p=2;
+// Find primes while p^2 < arg
+while( p*p < arg ) {
+ // skip marked non-primes
+ while( ary[p]==1 ) p = p + 1;
+ // p is now a prime
+ primes[nprimes] = p; nprimes = nprimes + 1;
// Mark out the rest non-primes
- int i = j + j;
+ int i = p + p;
while( i < ary# ) {
ary[i] = 1;
- i = i + j;
+ i = i + p;
}
- j = j + 1;
+ p = p + 1;
}
-// Now just collect the remaining primes
-while( j < arg ) {
- if( ary[j] == 0 ) {
- primes[nprimes] = j; nprimes = nprimes + 1;
+// Now just collect the remaining primes, no more marking
+while( p < arg ) {
+ if( ary[p] == 0 ) {
+ primes[nprimes] = p; nprimes = nprimes + 1;
}
- j = j + 1;
+ p = p + 1;
}
-// Shrink the result array to size
-int[] rez = new int[nprimes];
-j = 0;
+// Copy/shrink the result array
+int[] !rez = new int[nprimes];
+int 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] { # :int; [] :int; }",obj.struct().toString());
+ assertEquals("[int] {int #; int ![]; }",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++ )
@@ -265,8 +261,8 @@ return rez;
Parser parser = new Parser(
"""
struct S {int i; flt f;};
-S s1 = new S;
-S s2 = new S;
+S !s1 = new S;
+S !s2 = new S;
s2.i = 3;
s2.f = 2.0;
if (arg) s1 = new S;
diff --git a/src/test/java/com/seaofnodes/simple/Chapter16Test.java b/src/test/java/com/seaofnodes/simple/Chapter16Test.java
index ad287e82..5450824a 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter16Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter16Test.java
@@ -43,28 +43,28 @@ return x+y;
assertEquals(5L, Evaluator.evaluate(stop, 0));
}
- @Test
- public void testFinal0() {
- Parser parser = new Parser(
-"""
-int !x=2;
-x=3;
-return x;
-""");
- try { parser.parse().iterate(); fail(); }
- catch( Exception e ) { assertEquals("Cannot reassign final 'x'",e.getMessage()); }
- }
+// @Test
+// public void testFinal0() {
+// Parser parser = new Parser(
+//"""
+//int !x=2;
+//x=3;
+//return x;
+//""");
+// try { parser.parse().iterate(); fail(); }
+// catch( Exception e ) { assertEquals("Cannot reassign final 'x'",e.getMessage()); }
+// }
@Test
public void testFinal1() {
Parser parser = new Parser(
"""
-int !x=2, y=3;
+int x=2, y=3;
if( arg ) { int x = y; x = x*x; y=x; } // Shadow final x
return y;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Phi(Region21,9,3);", stop.toString());
+ assertEquals("return Phi(Region,9,3);", stop.toString());
assertEquals(3L, Evaluator.evaluate(stop, 0));
assertEquals(9L, Evaluator.evaluate(stop, 1));
}
@@ -107,17 +107,78 @@ return z.x;
@Test
- public void testStructFinal() {
+ public void testStructFinal0() {
Parser parser = new Parser("""
struct Point { int !x, !y; };
Point p = new Point { x=3; y=4; };
return p;
""");
StopNode stop = parser.parse().iterate();
- assertEquals("return Point;", stop.toString());
+ assertEquals("return (const)Point;", stop.toString());
assertEquals("Obj<Point>{x=3,y=4}", Evaluator.evaluate(stop, 0).toString());
}
+ @Test
+ public void testStructFinal1() {
+ Parser parser = new Parser("""
+struct Point { int x=3, y=4; };
+Point p = new Point { x=5; y=6; };
+p.x++;
+return p;
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
+ }
+
+ @Test
+ public void testStructFinal2() {
+ Parser parser = new Parser("""
+struct Point { int x=3, y=4; };
+Point p = new Point;
+p.x++;
+return p;
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
+ }
+
+ @Test
+ public void testStructFinal3() {
+ Parser parser = new Parser("""
+struct Point { var x; var y; };
+Point p = new Point;
+p.x++;
+return p;
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("'Point' is not fully initialized, field 'x' needs to be set in a constructor",e.getMessage()); }
+ }
+
+ @Test
+ public void testStructFinal4() {
+ Parser parser = new Parser("""
+struct Point { val x=3; val y=4; };
+Point p = new Point;
+p.x++;
+return p;
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot reassign final 'x'",e.getMessage()); }
+ }
+
+ @Test
+ public void testStructFinal5() {
+ Parser parser = new Parser("""
+struct Point { var x=3; var y=4; };
+Point !p = new Point;
+p.x++;
+return p;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Point;", stop.toString());
+ assertEquals("Obj<Point>{x=4,y=4}", Evaluator.evaluate(stop, 0).toString());
+ }
+
// Same as the Chapter13 test with the same name, but using the new
// constructor syntax
@Test
@@ -125,7 +186,7 @@ return p;
Parser parser = new Parser(
"""
struct LLI { LLI? next; int i; };
-LLI? head = null;
+LLI? !head = null;
while( arg ) {
head = new LLI { next=head; i=arg; };
arg = arg-1;
@@ -147,12 +208,12 @@ return next.i;
Parser parser = new Parser(
"""
struct LLI { LLI? next; int i; };
-LLI? head = null;
+LLI? !head = null;
while( arg ) {
head = new LLI {
next=head;
// Any old code in the constructor
- int tmp=arg;
+ int !tmp=arg;
while( arg > 10 ) {
tmp = tmp + arg;
arg = arg - 1;
@@ -182,7 +243,7 @@ struct Square {
// Newtons approximation to the square root, computed in a constructor.
// The actual allocation will copy in this result as the initial
// value for 'diag'.
- flt diag = arg*arg/2;
+ flt !diag = arg*arg/2;
while( 1 ) {
flt next = (side/diag + diag)/2;
if( next == diag ) break;
diff --git a/src/test/java/com/seaofnodes/simple/Chapter17Test.java b/src/test/java/com/seaofnodes/simple/Chapter17Test.java
new file mode 100644
index 00000000..1ca9a515
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/Chapter17Test.java
@@ -0,0 +1,500 @@
+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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class Chapter17Test {
+
+ @Test
+ public void testJig() {
+ Parser parser = new Parser("return 1;");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 1;", stop.toString());
+ assertEquals(1L, Evaluator.evaluate(stop, 0));
+ }
+
+
+ // ---------------------------------------------------------------
+ @Test
+ public void testInc0() {
+ Parser parser = new Parser("""
+return arg++;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return arg;", stop.toString());
+ assertEquals(0L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test
+ public void testInc1() {
+ Parser parser = new Parser("""
+return arg+++arg++;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return ((arg*2)+1);", stop.toString());
+ assertEquals(1L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test
+ public void testInc2() {
+ Parser parser = new Parser("""
+// -(arg--)-(arg--)
+return -arg---arg--;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return (-((arg*2)+-1));", stop.toString());
+ assertEquals(1L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test
+ public void testInc3() {
+ Parser parser = new Parser("""
+int[] !xs = new int[arg];
+xs[0]++;
+xs[1]++;
+return xs[0];
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 1;", stop.toString());
+ assertEquals(1L, Evaluator.evaluate(stop, 2));
+ }
+
+ @Test
+ public void testInc4() {
+ Parser parser = new Parser("""
+u8[] !xs = new u8[1];
+xs[0]--;
+return xs[0];
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 255;", stop.toString());
+ assertEquals(255L, Evaluator.evaluate(stop, 2));
+ }
+
+ @Test
+ public void testInc5() {
+ Parser parser = new Parser("""
+struct S { u16 x; };
+S !s = new S;
+s.x--;
+return s.x;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 65535;", stop.toString());
+ assertEquals(65535L, Evaluator.evaluate(stop, 2));
+ }
+
+ @Test
+ public void testInc6() {
+ Parser parser = new Parser("return --arg;");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return (arg+-1);", stop.toString());
+ assertEquals(-1L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test
+ public void testInc7() {
+ Parser parser = new Parser("u8 x=0; return --x;");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 255;", stop.toString());
+ assertEquals(255L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test
+ public void testInc8() {
+ Parser parser = new Parser("int x; x+=2; return x+=3;");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 5;", stop.toString());
+ assertEquals(5L, Evaluator.evaluate(stop, 0));
+ }
+
+ // ---------------------------------------------------------------
+ @Test public void testVar0() {
+ Parser parser = new Parser("var d; return d;");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Syntax error, expected =expression: ;",e.getMessage()); }
+ }
+
+ @Test public void testVar1() {
+ Parser parser = new Parser("val d; return d;");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Syntax error, expected =expression: ;",e.getMessage()); }
+ }
+
+ @Test public void testVar2() {
+ Parser parser = new Parser("int x; x=3; x++; return x; // Ok, no initializer so x is mutable ");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 4;", stop.toString());
+ assertEquals(4L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test public void testVar3() {
+ Parser parser = new Parser("int x=3; x++; return x; // Ok, primitive so x is mutable despite initializer ");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 4;", stop.toString());
+ assertEquals(4L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test public void testVar4() {
+ Parser parser = new Parser("struct S{int x;}; S s; s=new S; s.x++; return s.x; // Ok, no initializer so x is mutable ");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 1;", stop.toString());
+ assertEquals(1L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test public void testVar5() {
+ Parser parser = new Parser("struct S{int x;}; S s; s=new S{x=3;}; s.x++; return s.x; // Ok, no initializer so x is mutable ");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 4;", stop.toString());
+ assertEquals(4L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test public void testVar6() {
+ Parser parser = new Parser("struct S{int x;}; S s=new S; s.x++; return s.x; // Error initializer so x is immutable ");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
+ }
+
+ @Test public void testVar7() {
+ Parser parser = new Parser("struct S{int x;}; S s=new S{x=3;}; s.x++; return s.x; // Error initializer so x is immutable ");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
+ }
+
+ @Test public void testVar8() {
+ Parser parser = new Parser("struct S{int x;}; S !s=new S; s.x++; return s.x; // Ok, has '!' so s.x is mutable ");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 1;", stop.toString());
+ assertEquals(1L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test public void testVar9() {
+ Parser parser = new Parser("struct S{int x;}; var s=new S; s.x++; return s.x; // Ok, has var so s.x is mutable ");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 1;", stop.toString());
+ assertEquals(1L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test public void testVar10() {
+ Parser parser = new Parser("struct S{int x;}; val s=new S; s.x++; return s.x; // Error, has val so x is immutable ");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
+ }
+
+ @Test public void testVar11() {
+ Parser parser = new Parser("""
+struct Bar { int x; };
+Bar !bar = new Bar;
+bar.x = 3; // Ok, bar is mutable
+
+struct Foo { Bar? !bar; int y; };
+Foo !foo = new Foo { bar = bar; };
+foo.bar = bar; // Ok foo is mutable
+foo.bar.x++; // Ok foo and foo.bar and foo.bar.x are all mutable
+
+val xfoo = foo; // Throw away mutability
+xfoo.bar.x++; // Error, cannot mutate through xfoo
+ """);
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
+ }
+
+ @Test public void testVar12() {
+ Parser parser = new Parser("""
+struct Bar { int x; };
+Bar !bar = new Bar;
+bar.x = 3; // Ok, bar is mutable
+
+struct Foo { Bar? !bar; int y; };
+Foo !foo = new Foo;
+foo.bar = bar; // Ok bar is mutable
+foo.bar.x++; // Ok foo and foo.bar and foo.bar.x are all mutable
+
+val xfoo = foo; // Throw away mutability
+int x4 = xfoo.bar.x; // Ok to read through xfoo, gets 4
+foo.bar.x++; // Bumps to 5
+int x5 = xfoo.bar.x; // Ok to read through xfoo, gets 5
+return x4*10+x5;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 45;", stop.toString());
+ assertEquals(45L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test
+ public void testVar13() {
+ Parser parser = new Parser("""
+int i,i++;
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Redefining name 'i'",e.getMessage()); }
+ }
+
+
+ @Test
+ public void testVar14() {
+ Parser parser = new Parser("""
+struct B {};
+struct A { B b; };
+A x = new A {
+ return b; // read before init
+ b = new B;
+};
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot read uninitialized field 'b'",e.getMessage()); }
+ }
+
+ @Test
+ public void testVar15() {
+ Parser parser = new Parser("""
+struct B {};
+struct A { B b; };
+return new A {
+ if (arg) b = new B; // Constructor ends with partial init of b
+}.b;
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("'A' is not fully initialized, field 'b' needs to be set in a constructor",e.getMessage()); }
+ }
+
+ // ---------------------------------------------------------------
+ @Test
+ public void testTrinary0() {
+ Parser parser = new Parser("""
+return arg ? 1 : 2;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Region,1,2);", stop.toString());
+ assertEquals(2L, Evaluator.evaluate(stop, 0));
+ assertEquals(1L, Evaluator.evaluate(stop, 1));
+ }
+
+ @Test
+ public void testTrinary1() {
+ Parser parser = new Parser("""
+return arg ? 0 : arg;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return 0;", stop.toString());
+ assertEquals(0L, Evaluator.evaluate(stop, 0));
+ }
+
+ @Test
+ public void testTrinary2() {
+ Parser parser = new Parser("""
+struct Bar { int x; };
+var b = arg ? new Bar : null;
+return b ? b.x++ + b.x++ : -1;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Region,1,-1);", stop.toString());
+ assertEquals(-1L, Evaluator.evaluate(stop, 0));
+ assertEquals( 1L, Evaluator.evaluate(stop, 1));
+ }
+
+ @Test
+ public void testTrinary3() {
+ Parser parser = new Parser("""
+struct Bar { int x; };
+var b = arg ? new Bar;
+return b ? b.x++ + b.x++ : -1;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Region,1,-1);", stop.toString());
+ assertEquals(-1L, Evaluator.evaluate(stop, 0));
+ assertEquals( 1L, Evaluator.evaluate(stop, 1));
+ }
+
+ @Test
+ public void testTrinary4() {
+ // This test case will benefit from an unzipping transformation
+ Parser parser = new Parser("""
+struct Bar { Bar? next; int x; };
+var b = arg ? new Bar { next = (arg==2) ? new Bar{x=2;}; x=1; };
+return b ? b.next ? b.next.x : b.x; // parses "b ? (b.next ? b.next.x : b.x) : 0"
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Region,Phi(Region,.x,.x),0);", stop.toString());
+ assertEquals( 0L, Evaluator.evaluate(stop, 0));
+ assertEquals( 1L, Evaluator.evaluate(stop, 1));
+ assertEquals( 2L, Evaluator.evaluate(stop, 2));
+ }
+
+ @Test
+ public void testTrinary5() {
+ Parser parser = new Parser("""
+flt f=arg?1:1.2;
+return f; // missing widening
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Region,1.0,1.2);", stop.toString());
+ assertEquals(1.2, Evaluator.evaluate(stop, 0));
+ }
+
+ // ---------------------------------------------------------------
+ @Test
+ public void testFor0() {
+ Parser parser = new Parser("""
+int sum=0;
+for( int i=0; i<arg; i++ )
+ sum += i;
+return sum;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", stop.toString());
+ assertEquals(3L, Evaluator.evaluate(stop, 3));
+ assertEquals(45L, Evaluator.evaluate(stop, 10));
+ }
+ @Test
+ public void testFor1() {
+ Parser parser = new Parser("""
+int sum=0, i=0;
+for( ; i<arg; i++ )
+ sum += i;
+return sum;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", stop.toString());
+ assertEquals(3L, Evaluator.evaluate(stop, 3));
+ assertEquals(45L, Evaluator.evaluate(stop, 10));
+ }
+ @Test
+ public void testFor2() {
+ Parser parser = new Parser("""
+int sum=0;
+for( int i=0; ; i++ ) {
+ if( i>=arg ) break;
+ sum += i;
+}
+return sum;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", stop.toString());
+ assertEquals(3L, Evaluator.evaluate(stop, 3));
+ assertEquals(45L, Evaluator.evaluate(stop, 10));
+ }
+ @Test
+ public void testFor3() {
+ Parser parser = new Parser("""
+int sum=0;
+for( int i=0; i<arg; )
+ sum += i++;
+return sum;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", stop.toString());
+ assertEquals(3L, Evaluator.evaluate(stop, 3));
+ assertEquals(45L, Evaluator.evaluate(stop, 10));
+ }
+ @Test
+ public void testFor4() {
+ Parser parser = new Parser("""
+int sum=0;
+for( int i=0; i<arg; i++ )
+ sum += i;
+return i;
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Undefined name 'i'",e.getMessage()); }
+ }
+ @Test
+ public void testFor5() {
+ Parser parser = new Parser("""
+for(;;arg++;) {}
+""");
+ try { parser.parse().iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Syntax error, expected Unexpected code after expression: ;",e.getMessage()); }
+ }
+
+
+
+ // ---------------------------------------------------------------
+ @Test
+ public void testForward0() {
+ Parser parser = new Parser("""
+struct A{
+ B? f1;
+ B? f2;
+};
+return new A;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return A;", stop.toString());
+ assertEquals("Obj<A>{f1=null,f2=null}", Evaluator.evaluate(stop).toString());
+ }
+
+ @Test
+ public void testForward1() {
+ Parser parser = new Parser("""
+struct A{
+ B?[]? nil_array_of_b;
+ B?[] not_array_of_b = new B?[0];
+};
+return new A.not_array_of_b;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return (const)[*B?];", stop.toString());
+ assertEquals("Obj<[*B?]>{#=0,[]=[]}", Evaluator.evaluate(stop).toString());
+ }
+
+ // ---------------------------------------------------------------
+ @Test
+ public void testLinkedList2() {
+ Parser parser = new Parser("""
+struct LLI { LLI? next; int i; };
+LLI? !head = null;
+while( arg-- )
+ head = new LLI { next=head; i=arg; };
+int sum=0;
+var ptr = head; // A read-only ptr, to be assigned from read-only next fields
+for( ; ptr; ptr = ptr.next )
+ sum += ptr.i;
+return sum;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Loop,0,(Phi_sum+.i));", stop.toString());
+ assertEquals(45L, Evaluator.evaluate(stop, 10));
+ }
+
+ @Test
+ public void sieveOfEratosthenes() {
+ Parser parser = new Parser(
+"""
+var ary = new bool[arg], primes = new int[arg];
+var nprimes=0, p=0;
+// Find primes while p^2 < arg
+for( p=2; p*p < arg; p++ ) {
+ // skip marked non-primes
+ while( ary[p] ) p++;
+ // p is now a prime
+ primes[nprimes++] = p;
+ // Mark out the rest non-primes
+ for( int i = p + p; i < ary#; i += p )
+ ary[i] = true;
+}
+// Now just collect the remaining primes, no more marking
+for( ; p < arg; p++ )
+ if( !ary[p] )
+ primes[nprimes++] = p;
+// Copy/shrink the result array
+var !rez = new int[nprimes];
+for( int j=0; j<nprimes; j++ )
+ rez[j] = primes[j];
+return rez;
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return [int];", stop.toString());
+ Evaluator.Obj obj = (Evaluator.Obj)Evaluator.evaluate(stop, 20);
+ assertEquals("[int] {int #; int ![]; }",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]);
+ }
+
+}
diff --git a/src/test/java/com/seaofnodes/simple/SchedulerTest.java b/src/test/java/com/seaofnodes/simple/SchedulerTest.java
index 168e0ed7..c67217af 100644
--- a/src/test/java/com/seaofnodes/simple/SchedulerTest.java
+++ b/src/test/java/com/seaofnodes/simple/SchedulerTest.java
@@ -24,7 +24,7 @@ public class SchedulerTest {
struct S {
int f;
}
-S v=new S;
+S !v=new S;
v.f = 2;
int i=v.f;
if (arg) v.f=1;
@@ -42,7 +42,7 @@ return i;
struct S {
int f;
};
-S v0=new S;
+S !v0=new S;
if(arg) v0.f=1;
return v0;
""");
@@ -58,7 +58,7 @@ return v0;
struct S {
int f;
};
-S v=new S;
+S !v=new S;
v.f = 2;
int i=new S.f;
i=v.f;
diff --git a/src/test/java/com/seaofnodes/simple/TypeTest.java b/src/test/java/com/seaofnodes/simple/TypeTest.java
index 6f7409cd..1cb97cf6 100644
--- a/src/test/java/com/seaofnodes/simple/TypeTest.java
+++ b/src/test/java/com/seaofnodes/simple/TypeTest.java
@@ -20,7 +20,7 @@ public class TypeTest {
Field.make("b", TypeInteger.BOT,-4, false) });
Assert.assertEquals(s1, s1.glb());
Assert.assertNotEquals(s1, s1.dual());
- Assert.assertEquals(s1, s1.dual().glb());
+ Assert.assertEquals(s1.makeRO(), s1.dual().glb());
TypeMem m1 = TypeMem.make(1,TypeInteger.ZERO);
TypeMem m2 = TypeMem.make(2,TypeInteger.U16);
@@ -57,7 +57,7 @@ public class TypeTest {
Assert.assertEquals(ptr1nil, ptr1.glb());
Assert.assertEquals(ptr1, ptr1.dual().dual());
- Assert.assertEquals(ptr1.glb(), ptr1.dual().glb());
+ Assert.assertEquals(ptr1.glb().makeRO(), ptr1.dual().glb());
Assert.assertEquals(TypeMemPtr.make(TypeStruct.BOT,true), ptr1.meet(ptr2nil));
Assert.assertEquals(ptr1.glb(), ptr1.meet(TypeMemPtr.NULLPTR));
@@ -79,7 +79,7 @@ public class TypeTest {
// Test theoretical properties.
// This is a symmetric complete bounded (ranked) lattice.
- // Also the meet is commutative and associative.
+ // Also, the meet is commutative and associative.
// The lattice has a dual (symmetric), and join is ~(~x meet ~y).
// See https://en.wikipedia.org/wiki/Lattice_(order).
@Test
diff --git a/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java b/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
index c215de00..72f84fa2 100644
--- a/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
+++ b/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
@@ -36,7 +36,7 @@ public class Evaluator {
sb.append("obj@").append(cid);
return id;
}
- if (struct._name.equals("u8[]")) {
+ if (struct._name.equals("[u8]")) {
sb.append('"');
for (int i=struct._fields.length-1; i<fields.length; i++) {
var v = fields[i];
@@ -308,6 +308,7 @@ public class Evaluator {
case CProjNode cproj -> ((Object[])val(cproj.ctrl()))[cproj._idx];
case ProjNode proj -> ((Object[])val( proj.in(0) ))[ proj._idx];
case ScopeMinNode mem -> null;
+ case ReadOnlyNode ro -> val(ro.in(1));
default -> throw new AssertionError("Unexpected node " + node);
};
}