summaryrefslogtreecommitdiff
path: root/chapter15/src
diff options
context:
space:
mode:
Diffstat (limited to 'chapter15/src')
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/Parser.java2
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java17
-rw-r--r--chapter15/src/test/java/com/seaofnodes/simple/Chapter14Test.java3
3 files changed, 15 insertions, 7 deletions
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
index b3b1f3c5..2b09e943 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
@@ -813,7 +813,7 @@ public class Parser {
return (ConstantNode) new ConstantNode(_lexer.parseNumber()).peephole();
}
- private Node con( long con ) {
+ public static Node con( long con ) {
return new ConstantNode(TypeInteger.constant(con)).peephole();
}
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java
index 097a899c..28e6dd14 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java
@@ -1,8 +1,8 @@
package com.seaofnodes.simple.node;
+import com.seaofnodes.simple.Parser;
import com.seaofnodes.simple.type.Type;
import com.seaofnodes.simple.type.TypeInteger;
-
import java.util.BitSet;
public class ShlNode extends Node {
@@ -33,11 +33,18 @@ public class ShlNode extends Node {
public Node idealize() {
Node lhs = in(1);
Node rhs = in(2);
- Type t2 = rhs._type;
- // Shl of 0.
- if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 )
- return lhs;
+ if( rhs._type instanceof TypeInteger shl && shl.isConstant() ) {
+ // Shl of 0.
+ if( (shl.value()&63)==0 )
+ return lhs;
+ // (x + c) << i => (x << i) + (c << i)
+ if( lhs instanceof AddNode add && add.in(2)._type instanceof TypeInteger c && c.isConstant() ) {
+ long sum = c.value() << shl.value();
+ if( Integer.MIN_VALUE <= sum && sum <= Integer.MAX_VALUE )
+ return new AddNode( new ShlNode(add.in(1),rhs).peephole(), Parser.con(sum) );
+ }
+ }
// TODO: x << 3 << (y ? 1 : 2) ==> x << (y ? 4 : 5)
diff --git a/chapter15/src/test/java/com/seaofnodes/simple/Chapter14Test.java b/chapter15/src/test/java/com/seaofnodes/simple/Chapter14Test.java
index 5f7cf954..74815558 100644
--- a/chapter15/src/test/java/com/seaofnodes/simple/Chapter14Test.java
+++ b/chapter15/src/test/java/com/seaofnodes/simple/Chapter14Test.java
@@ -125,7 +125,8 @@ return b;
""");
StopNode stop = parser.parse(false).iterate(false);
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