summaryrefslogtreecommitdiff
path: root/chapter05
diff options
context:
space:
mode:
Diffstat (limited to 'chapter05')
-rw-r--r--chapter05/README.md2
-rw-r--r--chapter05/docs/Makefile12
-rw-r--r--chapter05/src/main/java/com/seaofnodes/simple/Parser.java10
-rw-r--r--chapter05/src/test/java/com/seaofnodes/simple/Chapter01Test.java100
-rw-r--r--chapter05/src/test/java/com/seaofnodes/simple/Chapter02Test.java66
-rw-r--r--chapter05/src/test/java/com/seaofnodes/simple/Chapter03Test.java68
-rw-r--r--chapter05/src/test/java/com/seaofnodes/simple/Chapter04Test.java128
-rw-r--r--chapter05/src/test/java/com/seaofnodes/simple/Chapter05Test.java350
8 files changed, 407 insertions, 329 deletions
diff --git a/chapter05/README.md b/chapter05/README.md
index cf95b545..4d36e40c 100644
--- a/chapter05/README.md
+++ b/chapter05/README.md
@@ -1,4 +1,4 @@
-# Chapter 5
+# Chapter 5: If Statement, Phi, and Region
In this chapter we extend the language grammar with the following features:
diff --git a/chapter05/docs/Makefile b/chapter05/docs/Makefile
new file mode 100644
index 00000000..12659b8f
--- /dev/null
+++ b/chapter05/docs/Makefile
@@ -0,0 +1,12 @@
+GV := $(wildcard *.gv)
+SVG := $(patsubst %.gv,%.svg,$(GV))
+
+.PHONY: all
+all: $(SVG)
+
+%.svg: %.gv
+ dot -Tsvg $< > $@
+
+.PHONY: clean
+clean:
+ @rm -f $(SVG)
diff --git a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java
index ff58fc25..8a02766f 100644
--- a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java
@@ -476,6 +476,7 @@ public class Parser {
String getAnyNextToken() {
if (isEOF()) return "";
if (isIdStart(peek())) return parseId();
+ if (isNumber(peek())) return parseNumberString();
if (isPunctuation(peek())) return parsePunctuation();
return String.valueOf(peek());
}
@@ -484,13 +485,16 @@ public class Parser {
boolean isNumber(char ch) {return Character.isDigit(ch);}
private Type parseNumber() {
- int start = _position;
- while (isNumber(nextChar())) ;
- String snum = new String(_input, start, --_position - start);
+ String snum = parseNumberString();
if (snum.length() > 1 && snum.charAt(0) == '0')
throw error("Syntax error: integer values cannot start with '0'");
return TypeInteger.constant(Long.parseLong(snum));
}
+ private String parseNumberString() {
+ int start = _position;
+ while (isNumber(nextChar())) ;
+ return new String(_input, start, --_position - start);
+ }
// First letter of an identifier
private boolean isIdStart(char ch) {
diff --git a/chapter05/src/test/java/com/seaofnodes/simple/Chapter01Test.java b/chapter05/src/test/java/com/seaofnodes/simple/Chapter01Test.java
new file mode 100644
index 00000000..547c36f8
--- /dev/null
+++ b/chapter05/src/test/java/com/seaofnodes/simple/Chapter01Test.java
@@ -0,0 +1,100 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.TypeInteger;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class Chapter01Test {
+
+ @Test
+ public void testSimpleProgram() {
+ Parser parser = new Parser("return 1;");
+ StopNode stop = parser.parse();
+ StartNode start = Parser.START;
+ ReturnNode ret = (ReturnNode)stop.in(0);
+
+ assertTrue(ret.ctrl() instanceof ProjNode);
+ Node expr = ret.expr();
+ if( expr instanceof ConstantNode con ) {
+ assertEquals(start,con.in(0));
+ assertEquals(TypeInteger.constant(1), con._type);
+ } else {
+ fail();
+ }
+ }
+
+ @Test
+ public void testZero() {
+ Parser parser = new Parser("return 0;");
+ parser.parse();
+ StartNode start = Parser.START;
+ for( Node use : start._outputs )
+ if( use instanceof ConstantNode con )
+ assertEquals(TypeInteger.constant(0),con._type);
+ }
+
+ @Test
+ public void testBad1() {
+ try {
+ new Parser("ret").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Syntax error, expected =: ",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testBad2() {
+ try {
+ new Parser("return 0123;").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Syntax error: integer values cannot start with '0'",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testNotBad3() {
+ // this test used to fail in chapter 1
+ assertEquals("return 12;", new Parser("return --12;").parse().print());
+ }
+
+ @Test
+ public void testBad4() {
+ try {
+ new Parser("return 100").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Syntax error, expected ;: ",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testNotBad5() {
+ // this test used to fail in chapter 1
+ assertEquals("return -100;", new Parser("return -100;").parse().print());
+ }
+
+ @Test
+ public void testBad6() {
+ try {
+ new Parser("return100").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Syntax error, expected =: ",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testBad7() {
+ try {
+ new Parser("return 1;}").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Syntax error, unexpected }",e.getMessage());
+ }
+ }
+
+}
diff --git a/chapter05/src/test/java/com/seaofnodes/simple/Chapter02Test.java b/chapter05/src/test/java/com/seaofnodes/simple/Chapter02Test.java
new file mode 100644
index 00000000..4085ed7e
--- /dev/null
+++ b/chapter05/src/test/java/com/seaofnodes/simple/Chapter02Test.java
@@ -0,0 +1,66 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.TypeInteger;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class Chapter02Test {
+
+ @Test
+ public void testParseGrammar() {
+ Parser parser = new Parser("return 1+2*3+-5;");
+ Node._disablePeephole = true; // disable peephole so we can observe full graph
+ StopNode ret = parser.parse();
+ assertEquals("return (1+((2*3)+(-5)));", ret.print());
+ GraphVisualizer gv = new GraphVisualizer();
+ System.out.println(gv.generateDotOutput(parser));
+ Node._disablePeephole = false;
+ }
+
+ @Test
+ public void testAddPeephole() {
+ Parser parser = new Parser("return 1+2;");
+ StopNode ret = parser.parse();
+ assertEquals("return 3;", ret.print());
+ }
+
+ @Test
+ public void testSubPeephole() {
+ Parser parser = new Parser("return 1-2;");
+ StopNode ret = parser.parse();
+ assertEquals("return -1;", ret.print());
+ }
+
+ @Test
+ public void testMulPeephole() {
+ Parser parser = new Parser("return 2*3;");
+ StopNode ret = parser.parse();
+ assertEquals("return 6;", ret.print());
+ }
+
+ @Test
+ public void testDivPeephole() {
+ Parser parser = new Parser("return 6/3;");
+ StopNode ret = parser.parse();
+ assertEquals("return 2;", ret.print());
+ }
+
+ @Test
+ public void testMinusPeephole() {
+ Parser parser = new Parser("return 6/-3;");
+ StopNode ret = parser.parse();
+ assertEquals("return -2;", ret.print());
+ }
+
+ @Test
+ public void testExample() {
+ Parser parser = new Parser("return 1+2*3+-5;");
+ StopNode ret = parser.parse();
+ assertEquals("return 2;", ret.print());
+ GraphVisualizer gv = new GraphVisualizer();
+ System.out.println(gv.generateDotOutput(parser));
+ }
+
+}
diff --git a/chapter05/src/test/java/com/seaofnodes/simple/Chapter03Test.java b/chapter05/src/test/java/com/seaofnodes/simple/Chapter03Test.java
new file mode 100644
index 00000000..407fbe48
--- /dev/null
+++ b/chapter05/src/test/java/com/seaofnodes/simple/Chapter03Test.java
@@ -0,0 +1,68 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.TypeInteger;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class Chapter03Test {
+
+ @Test
+ public void testVarDecl() {
+ Parser parser = new Parser("int a=1; return a;");
+ StopNode ret = parser.parse();
+ assertEquals("return 1;", ret.print());
+ }
+
+ @Test
+ public void testVarAdd() {
+ Parser parser = new Parser("int a=1; int b=2; return a+b;");
+ StopNode ret = parser.parse();
+ assertEquals("return 3;", ret.print());
+ }
+
+ @Test
+ public void testVarScope() {
+ Parser parser = new Parser("int a=1; int b=2; int c=0; { int b=3; c=a+b; } return c;");
+ StopNode ret = parser.parse();
+ assertEquals("return 4;", ret.print());
+ }
+
+ @Test
+ public void testVarScopeNoPeephole() {
+ Parser parser = new Parser("int a=1; int b=2; int c=0; { int b=3; c=a+b; #showGraph; } return c; #showGraph;");
+ Node._disablePeephole = true;
+ StopNode ret = parser.parse();
+ Node._disablePeephole = false;
+ assertEquals("return (1+3);", ret.print());
+ }
+
+ @Test
+ public void testVarDist() {
+ Parser parser = new Parser("int x0=1; int y0=2; int x1=3; int y1=4; return (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1); #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return 8;", ret.print());
+ }
+
+ @Test
+ public void testSelfAssign() {
+ try {
+ new Parser("int a=a; return a;").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Undefined name 'a'",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testBad1() {
+ try {
+ 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/chapter05/src/test/java/com/seaofnodes/simple/Chapter04Test.java b/chapter05/src/test/java/com/seaofnodes/simple/Chapter04Test.java
new file mode 100644
index 00000000..cde23324
--- /dev/null
+++ b/chapter05/src/test/java/com/seaofnodes/simple/Chapter04Test.java
@@ -0,0 +1,128 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.TypeInteger;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class Chapter04Test {
+
+ @Test
+ public void testPeephole() {
+ Parser parser = new Parser("return 1+arg+2; #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return (arg+3);", ret.print());
+ }
+
+ @Test
+ public void testPeephole2() {
+ Parser parser = new Parser("return (1+arg)+2;");
+ StopNode ret = parser.parse();
+ assertEquals("return (arg+3);", ret.print());
+ }
+
+ @Test
+ public void testAdd0() {
+ Parser parser = new Parser("return 0+arg;");
+ StopNode ret = parser.parse();
+ assertEquals("return arg;", ret.print());
+ }
+
+ @Test
+ public void testAddAddMul() {
+ Parser parser = new Parser("return arg+0+arg;");
+ StopNode ret = parser.parse();
+ assertEquals("return (arg*2);", ret.print());
+ }
+
+ @Test
+ public void testPeephole3() {
+ Parser parser = new Parser("return 1+arg+2+arg+3; #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return ((arg*2)+6);", ret.print());
+ }
+
+ @Test
+ public void testMul1() {
+ Parser parser = new Parser("return 1*arg;");
+ StopNode ret = parser.parse();
+ assertEquals("return arg;", ret.print());
+ }
+
+ @Test
+ public void testVarArg() {
+ Parser parser = new Parser("return arg; #showGraph;");
+ StopNode stop = parser.parse();
+ ReturnNode ret = stop.ret();
+ assertTrue(ret.in(0) instanceof ProjNode);
+ assertTrue(ret.in(1) instanceof ProjNode);
+ }
+
+ @Test
+ public void testConstantArg() {
+ Parser parser = new Parser("return arg; #showGraph;", TypeInteger.constant(2));
+ StopNode ret = parser.parse();
+ assertEquals("return 2;", ret.print());
+ }
+
+ @Test
+ public void testCompEq() {
+ Parser parser = new Parser("return 3==3; #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return 1;", ret.print());
+ }
+
+ @Test
+ public void testCompEq2() {
+ Parser parser = new Parser("return 3==4; #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return 0;", ret.print());
+ }
+
+ @Test
+ public void testCompNEq() {
+ Parser parser = new Parser("return 3!=3; #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return 0;", ret.print());
+ }
+
+ @Test
+ public void testCompNEq2() {
+ Parser parser = new Parser("return 3!=4; #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return 1;", ret.print());
+ }
+
+ @Test
+ public void testBug1() {
+ Parser parser = new Parser("int a=arg+1; int b=a; b=1; return a+2; #showGraph;");
+ 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; #showGraph;");
+ StopNode ret = parser.parse();
+ assertEquals("return (arg+1);", ret.print());
+ }
+
+ @Test
+ public void testBug3() {
+ try {
+ new Parser("inta=1; return a;").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Undefined name 'inta'",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testBug4() {
+ Parser parser = new Parser("return -arg;");
+ StopNode ret = parser.parse();
+ assertEquals("return (-arg);", ret.print());
+ }
+
+}
diff --git a/chapter05/src/test/java/com/seaofnodes/simple/Chapter05Test.java b/chapter05/src/test/java/com/seaofnodes/simple/Chapter05Test.java
index 97666d27..b5fcbeaf 100644
--- a/chapter05/src/test/java/com/seaofnodes/simple/Chapter05Test.java
+++ b/chapter05/src/test/java/com/seaofnodes/simple/Chapter05Test.java
@@ -2,16 +2,14 @@ package com.seaofnodes.simple;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeInteger;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
import static org.junit.Assert.*;
public class Chapter05Test {
@Test
- public void testChapter5IfStmt() {
+ public void testIfStmt() {
Parser parser = new Parser(
"""
int a = 1;
@@ -28,7 +26,7 @@ return a;""");
}
@Test
- public void testChapter5Test() {
+ public void testTest() {
Parser parser = new Parser(
"""
int c = 3;
@@ -43,7 +41,7 @@ return c;""", TypeInteger.BOT);
}
@Test
- public void testChapter5Return2() {
+ public void testReturn2() {
Parser parser = new Parser(
"""
if( arg==1 )
@@ -56,7 +54,7 @@ else
}
@Test
- public void testChapter5IfMergeB() {
+ public void testIfMergeB() {
Parser parser = new Parser(
"""
int a=arg+1;
@@ -71,7 +69,7 @@ return a+b;""");
}
@Test
- public void testChapter5IfMerge2() {
+ public void testIfMerge2() {
Parser parser = new Parser(
"""
int a=arg+1;
@@ -86,7 +84,7 @@ return a+b;""");
}
@Test
- public void testChapter5Merge3() {
+ public void testMerge3() {
Parser parser = new Parser(
"""
int a=1;
@@ -106,7 +104,7 @@ return a;
}
@Test
- public void testChapter5Merge4() {
+ public void testMerge4() {
Parser parser = new Parser(
"""
int a=0;
@@ -122,7 +120,7 @@ return arg+a+b;
}
@Test
- public void testChapter5Merge5() {
+ public void testMerge5() {
Parser parser = new Parser(
"""
int a=arg==2;
@@ -136,13 +134,13 @@ return a;""");
}
@Test
- public void testChapter5True() {
+ public void testTrue() {
StopNode stop = new Parser("return true;").parse();
assertEquals("return 1;",stop.toString());
}
@Test
- public void testChapter5HalfDef() {
+ public void testHalfDef() {
try {
new Parser("if( arg==1 ) int b=2; return b;").parse();
fail();
@@ -152,7 +150,7 @@ return a;""");
}
@Test
- public void testChapter5HalfDef2() {
+ public void testHalfDef2() {
try {
new Parser("if( arg==1 ) { int b=2; } else { int b=3; } return b;").parse();
fail();
@@ -162,7 +160,17 @@ return a;""");
}
@Test
- public void testChapter5BadNum() {
+ public void testRegress1() {
+ try {
+ new Parser("if(arg==2) int a=1; else int b=2; return a;").parse();
+ fail();
+ } catch( RuntimeException e ) {
+ assertEquals("Cannot define a new name on one arm of an if",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testBadNum() {
try {
new Parser("return 1-;").parse();
fail();
@@ -172,7 +180,7 @@ return a;""");
}
@Test
- public void testChapter5Keyword1() {
+ public void testKeyword1() {
try {
new Parser("int true=0; return true;").parse();
fail();
@@ -182,7 +190,7 @@ return a;""");
}
@Test
- public void testChapter5Keyword2() {
+ public void testKeyword2() {
try {
new Parser("int else=arg; if(else) else=2; else else=1; return else;").parse();
fail();
@@ -192,7 +200,7 @@ return a;""");
}
@Test
- public void testChapter5Keyword3() {
+ public void testKeyword3() {
try {
new Parser("int a=1; ififif(arg)inta=2;return a;").parse();
fail();
@@ -201,312 +209,4 @@ return a;""");
}
}
- @Test
- public void testChapter4Peephole() {
- Parser parser = new Parser("return 1+arg+2; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return (arg+3);", ret.print());
- }
-
- @Test
- public void testChapter4Peephole2() {
- Parser parser = new Parser("return (1+arg)+2;");
- StopNode ret = parser.parse();
- assertEquals("return (arg+3);", ret.print());
- }
-
- @Test
- public void testChapter4Add0() {
- Parser parser = new Parser("return 0+arg;");
- StopNode ret = parser.parse();
- assertEquals("return arg;", ret.print());
- }
-
- @Test
- public void testChapter4AddAddMul() {
- Parser parser = new Parser("return arg+0+arg;");
- StopNode ret = parser.parse();
- assertEquals("return (arg*2);", ret.print());
- }
-
- @Test
- public void testChapter4Peephole3() {
- Parser parser = new Parser("return 1+arg+2+arg+3; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return ((arg*2)+6);", ret.print());
- }
-
- @Test
- public void testChapter4Mul1() {
- Parser parser = new Parser("return 1*arg;");
- StopNode ret = parser.parse();
- assertEquals("return arg;", ret.print());
- }
-
- @Test
- public void testChapter4VarArg() {
- Parser parser = new Parser("return arg; #showGraph;");
- StopNode stop = parser.parse();
- ReturnNode ret = stop.ret();
- assertTrue(ret.in(0) instanceof ProjNode);
- assertTrue(ret.in(1) instanceof ProjNode);
- }
-
- @Test
- public void testChapter4ConstantArg() {
- Parser parser = new Parser("return arg; #showGraph;", TypeInteger.constant(2));
- StopNode ret = parser.parse();
- assertEquals("return 2;", ret.print());
- }
-
- @Test
- public void testChapter4CompEq() {
- Parser parser = new Parser("return 3==3; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return 1;", ret.print());
- }
-
- @Test
- public void testChapter4CompEq2() {
- Parser parser = new Parser("return 3==4; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return 0;", ret.print());
- }
-
- @Test
- public void testChapter4CompNEq() {
- Parser parser = new Parser("return 3!=3; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return 0;", ret.print());
- }
-
- @Test
- public void testChapter4CompNEq2() {
- Parser parser = new Parser("return 3!=4; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return 1;", ret.print());
- }
-
- @Test
- public void testChapter4Bug1() {
- Parser parser = new Parser("int a=arg+1; int b=a; b=1; return a+2; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return (arg+3);", ret.print());
- }
-
- @Test
- public void testChapter4Bug2() {
- Parser parser = new Parser("int a=arg+1; a=a; return a; #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return (arg+1);", ret.print());
- }
-
- @Test
- public void testChapter4Bug3() {
- try {
- new Parser("inta=1; return a;").parse();
- fail();
- } catch( RuntimeException e ) {
- assertEquals("Undefined name 'inta'",e.getMessage());
- }
- }
-
- @Test
- public void testChapter4Bug4() {
- Parser parser = new Parser("return -arg;");
- StopNode ret = parser.parse();
- assertEquals("return (-arg);", ret.print());
- }
-
- @Test
- public void testVarDecl() {
- Parser parser = new Parser("int a=1; return a;");
- StopNode ret = parser.parse();
- assertEquals("return 1;", ret.print());
- }
-
- @Test
- public void testVarAdd() {
- Parser parser = new Parser("int a=1; int b=2; return a+b;");
- StopNode ret = parser.parse();
- assertEquals("return 3;", ret.print());
- }
-
- @Test
- public void testVarScope() {
- Parser parser = new Parser("int a=1; int b=2; int c=0; { int b=3; c=a+b; } return c;");
- StopNode ret = parser.parse();
- assertEquals("return 4;", ret.print());
- }
-
- @Test
- public void testVarScopeNoPeephole() {
- Parser parser = new Parser("int a=1; int b=2; int c=0; { int b=3; c=a+b; #showGraph; } return c; #showGraph;");
- Node._disablePeephole = true;
- StopNode ret = parser.parse();
- Node._disablePeephole = false;
- assertEquals("return (1+3);", ret.print());
- }
-
- @Test
- public void testVarDist() {
- Parser parser = new Parser("int x0=1; int y0=2; int x1=3; int y1=4; return (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1); #showGraph;");
- StopNode ret = parser.parse();
- assertEquals("return 8;", ret.print());
- }
-
- @Test
- public void testSelfAssign() {
- try {
- new Parser("int a=a; return a;").parse();
- fail();
- } catch( RuntimeException e ) {
- assertEquals("Undefined name 'a'",e.getMessage());
- }
- }
-
- @Test
- public void testChapter2ParseGrammar() {
- Parser parser = new Parser("return 1+2*3+-5;");
- Node._disablePeephole = true; // disable peephole so we can observe full graph
- StopNode ret = parser.parse();
- assertEquals("return (1+((2*3)+(-5)));", ret.print());
- GraphVisualizer gv = new GraphVisualizer();
- System.out.println(gv.generateDotOutput(parser));
- Node._disablePeephole = false;
- }
-
- @Test
- public void testChapter2AddPeephole() {
- Parser parser = new Parser("return 1+2;");
- StopNode ret = parser.parse();
- assertEquals("return 3;", ret.print());
- }
-
- @Test
- public void testChapter2SubPeephole() {
- Parser parser = new Parser("return 1-2;");
- StopNode ret = parser.parse();
- assertEquals("return -1;", ret.print());
- }
-
- @Test
- public void testChapter2MulPeephole() {
- Parser parser = new Parser("return 2*3;");
- StopNode ret = parser.parse();
- assertEquals("return 6;", ret.print());
- }
-
- @Test
- public void testChapter2DivPeephole() {
- Parser parser = new Parser("return 6/3;");
- StopNode ret = parser.parse();
- assertEquals("return 2;", ret.print());
- }
-
- @Test
- public void testChapter2MinusPeephole() {
- Parser parser = new Parser("return 6/-3;");
- StopNode ret = parser.parse();
- assertEquals("return -2;", ret.print());
- }
-
- @Test
- public void testChapter2Example() {
- Parser parser = new Parser("return 1+2*3+-5;");
- StopNode ret = parser.parse();
- assertEquals("return 2;", ret.print());
- GraphVisualizer gv = new GraphVisualizer();
- System.out.println(gv.generateDotOutput(parser));
- }
-
- @Test
- public void testSimpleProgram() {
- Parser parser = new Parser("return 1;");
- StopNode stop = parser.parse();
- StartNode start = Parser.START;
- ReturnNode ret = (ReturnNode)stop.in(0);
-
- assertTrue(ret.ctrl() instanceof ProjNode);
- Node expr = ret.expr();
- if( expr instanceof ConstantNode con ) {
- assertEquals(start,con.in(0));
- assertEquals(TypeInteger.constant(1), con._type);
- } else {
- fail();
- }
- }
-
- @Test
- public void testZero() {
- Parser parser = new Parser("return 0;");
- parser.parse();
- StartNode start = Parser.START;
- for( Node use : start._outputs )
- if( use instanceof ConstantNode con )
- assertEquals(TypeInteger.constant(0),con._type);
- }
-
- @Test
- public void testBad1() {
- try {
- new Parser("ret").parse();
- fail();
- } catch( RuntimeException e ) {
- assertEquals("Syntax error, expected =: ",e.getMessage());
- }
- }
-
- @Test
- public void testBad2() {
- try {
- new Parser("return 0123;").parse();
- fail();
- } catch( RuntimeException e ) {
- assertEquals("Syntax error: integer values cannot start with '0'",e.getMessage());
- }
- }
-
- @Test
- public void testNotBad3() {
- // this test used to fail in chapter 1
- assertEquals("return 12;", new Parser("return --12;").parse().print());
- }
-
- @Test
- public void testBad4() {
- try {
- new Parser("return 100").parse();
- fail();
- } catch( RuntimeException e ) {
- assertEquals("Syntax error, expected ;: ",e.getMessage());
- }
- }
-
- @Test
- public void testNotBad5() {
- // this test used to fail in chapter 1
- assertEquals("return -100;", new Parser("return -100;").parse().print());
- }
-
- @Test
- public void testBad6() {
- try {
- 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());
- }
- }
-
- @Test
- public void testBad7() {
- try {
- new Parser("return 1;}").parse();
- fail();
- } catch( RuntimeException e ) {
- assertEquals("Syntax error, unexpected }",e.getMessage());
- }
- }
-
}