summaryrefslogtreecommitdiff
path: root/dice-lang/src/main/java/bjc/dicelang/ast/optimization
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-18 08:34:32 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-18 08:34:32 -0400
commit9ce39956fa1702f157c347dc4b8807d9b5dd2185 (patch)
treed981c0010a92660a1f0501431c4a3bc02d94e56d /dice-lang/src/main/java/bjc/dicelang/ast/optimization
parent7c222f25d4b2d9f3b149d880f0e1acf8d673e4f5 (diff)
Reimplemented basic optimization.
Diffstat (limited to 'dice-lang/src/main/java/bjc/dicelang/ast/optimization')
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/optimization/ArithmeticCollapser.java49
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/optimization/ConstantCollapser.java86
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/optimization/IOptimizationPass.java34
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/optimization/package-info.java6
4 files changed, 175 insertions, 0 deletions
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ArithmeticCollapser.java b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ArithmeticCollapser.java
new file mode 100644
index 0000000..5318119
--- /dev/null
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ArithmeticCollapser.java
@@ -0,0 +1,49 @@
+package bjc.dicelang.ast.optimization;
+
+import java.util.function.BinaryOperator;
+
+import bjc.dicelang.ast.DiceASTUtils;
+import bjc.dicelang.ast.nodes.DiceASTType;
+import bjc.dicelang.ast.nodes.IDiceASTNode;
+import bjc.dicelang.ast.nodes.ILiteralDiceNode;
+import bjc.dicelang.ast.nodes.IntegerLiteralNode;
+import bjc.dicelang.ast.nodes.OperatorDiceNode;
+import bjc.utils.funcdata.IFunctionalList;
+import bjc.utils.funcdata.ITree;
+import bjc.utils.funcdata.Tree;
+
+class ArithmeticCollapser {
+ private BinaryOperator<Integer> reducer;
+ private OperatorDiceNode type;
+
+ public ArithmeticCollapser(BinaryOperator<Integer> reducr,
+ OperatorDiceNode typ) {
+ reducer = reducr;
+ this.type = typ;
+ }
+
+ public ITree<IDiceASTNode>
+ collapse(IFunctionalList<ITree<IDiceASTNode>> children) {
+ boolean allConstant = children.allMatch((subtree) -> {
+ return subtree.transformHead((node) -> {
+ if (node.getType() == DiceASTType.LITERAL) {
+ return ((ILiteralDiceNode) node).canOptimize();
+ }
+
+ return false;
+ });
+ });
+
+ if (!allConstant) {
+ return new Tree<>(type, children);
+ }
+
+ int initState = DiceASTUtils.toInt(children.first());
+
+ return children.tail().reduceAux(initState,
+ (currentNode, state) -> {
+ return reducer.apply(state,
+ DiceASTUtils.toInt(currentNode));
+ }, (state) -> new Tree<>(new IntegerLiteralNode(state)));
+ }
+}
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ConstantCollapser.java b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ConstantCollapser.java
new file mode 100644
index 0000000..5062170
--- /dev/null
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ConstantCollapser.java
@@ -0,0 +1,86 @@
+package bjc.dicelang.ast.optimization;
+
+import bjc.dicelang.ComplexDice;
+import bjc.dicelang.ast.DiceASTUtils;
+import bjc.dicelang.ast.nodes.IDiceASTNode;
+import bjc.dicelang.ast.nodes.IntegerLiteralNode;
+import bjc.dicelang.ast.nodes.OperatorDiceNode;
+import bjc.utils.funcdata.IFunctionalList;
+import bjc.utils.funcdata.ITree;
+import bjc.utils.funcdata.Tree;
+
+/**
+ * Collapses operations with constants to constants
+ *
+ * @author ben
+ *
+ */
+public class ConstantCollapser implements IOptimizationPass {
+ private static final ArithmeticCollapser additionCollapser =
+ new ArithmeticCollapser((left, right) -> left + right,
+ OperatorDiceNode.ADD);
+
+ private static final ArithmeticCollapser divideCollapser =
+ new ArithmeticCollapser((left, right) -> left / right,
+ OperatorDiceNode.DIVIDE);
+
+ private static final ArithmeticCollapser multiplyCollapser =
+ new ArithmeticCollapser((left, right) -> left * right,
+ OperatorDiceNode.MULTIPLY);
+
+ private static final ArithmeticCollapser subtractCollapser =
+ new ArithmeticCollapser((left, right) -> left - right,
+ OperatorDiceNode.SUBTRACT);
+
+ private static final ArithmeticCollapser compoundCollapser =
+ new ArithmeticCollapser((left,
+ right) -> Integer.parseInt(Integer.toString(left)
+ + Integer.toString(left)),
+ OperatorDiceNode.SUBTRACT);
+
+ @Override
+ public ITree<IDiceASTNode> optimizeLeaf(IDiceASTNode leafNode) {
+ // We don't do anything special here
+ return new Tree<>(leafNode);
+ }
+
+ @Override
+ public ITree<IDiceASTNode> optimizeOperator(IDiceASTNode operator,
+ IFunctionalList<ITree<IDiceASTNode>> children) {
+ if (!operator.isOperator()) {
+ return new Tree<>(operator, children);
+ }
+
+ switch ((OperatorDiceNode) operator) {
+ case ADD:
+ return additionCollapser.collapse(children);
+ case DIVIDE:
+ return divideCollapser.collapse(children);
+ case MULTIPLY:
+ return multiplyCollapser.collapse(children);
+ case SUBTRACT:
+ return subtractCollapser.collapse(children);
+ case COMPOUND:
+ return compoundCollapser.collapse(children);
+ case GROUP:
+ if (children.getSize() != 2) {
+ return new Tree<>(operator, children);
+ }
+
+ ComplexDice dice = new ComplexDice(
+ DiceASTUtils.toExpression(children.getByIndex(0)),
+ DiceASTUtils.toExpression(children.getByIndex(1)));
+
+ if (dice.canOptimize()) {
+ return new Tree<>(
+ new IntegerLiteralNode(dice.optimize()));
+ }
+
+ return new Tree<>(operator, children);
+ case ASSIGN:
+ default:
+ // We don't optimize these operators
+ return new Tree<>(operator, children);
+ }
+ }
+}
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/IOptimizationPass.java b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/IOptimizationPass.java
new file mode 100644
index 0000000..b631fb5
--- /dev/null
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/IOptimizationPass.java
@@ -0,0 +1,34 @@
+package bjc.dicelang.ast.optimization;
+
+import bjc.dicelang.ast.nodes.IDiceASTNode;
+import bjc.utils.funcdata.IFunctionalList;
+import bjc.utils.funcdata.ITree;
+
+/**
+ * Represents a pass of optimizations over a dice AST
+ *
+ * @author ben
+ *
+ */
+public interface IOptimizationPass {
+ /**
+ * Optimize a leaf in the tree
+ *
+ * @param leafNode
+ * The node to optimize
+ * @return The optimized node
+ */
+ public ITree<IDiceASTNode> optimizeLeaf(IDiceASTNode leafNode);
+
+ /**
+ * Optimize an operator in an AST node
+ *
+ * @param operator
+ * The operator being optimized
+ * @param children
+ * The children of the operator being optimized
+ * @return The optimized node
+ */
+ public ITree<IDiceASTNode> optimizeOperator(IDiceASTNode operator,
+ IFunctionalList<ITree<IDiceASTNode>> children);
+}
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/package-info.java b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/package-info.java
new file mode 100644
index 0000000..a3ec93c
--- /dev/null
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Contains optimizations on dice ASTs
+ * @author ben
+ *
+ */
+package bjc.dicelang.ast.optimization; \ No newline at end of file