diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-04-17 20:41:47 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-04-17 20:41:47 -0400 |
| commit | 7c222f25d4b2d9f3b149d880f0e1acf8d673e4f5 (patch) | |
| tree | a07cd6b07522d9ffe24a82c5a1a487d307875561 /dice-lang/src/main | |
| parent | d9437c1d328ccc2b26bd0aae19c2aff7140e466b (diff) | |
Fixed a bug with arithmetic operators
Diffstat (limited to 'dice-lang/src/main')
5 files changed, 147 insertions, 22 deletions
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java b/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java index 5ad0a0f..5c00fe2 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java @@ -16,8 +16,7 @@ import bjc.utils.funcdata.Tree; * @author ben * */ -final class ArithmeticCollapser - implements IOperatorCollapser { +final class ArithmeticCollapser implements IOperatorCollapser { private OperatorDiceNode type; private BinaryOperator<Integer> valueOp; @@ -35,12 +34,18 @@ final class ArithmeticCollapser new Pair<>(0, new Tree<>(type)); BinaryOperator<IPair<Integer, ITree<IDiceASTNode>>> reducer = - (accumulatedState, currentState) -> { - return reduceStates(accumulatedState, - currentState); + (currentState, accumulatedState) -> { + // Force evaluation of accumulated state to prevent + // certain bugs from occuring + accumulatedState.merge((l, r) -> null); + + return reduceStates(accumulatedState, currentState); }; - return nodes.reduceAux(initState, reducer, (state) -> state); + IPair<Integer, ITree<IDiceASTNode>> reducedState = + nodes.reduceAux(initState, reducer, (state) -> state); + + return reducedState; } private IPair<Integer, ITree<IDiceASTNode>> reduceStates( @@ -52,9 +57,8 @@ final class ArithmeticCollapser .bind((currentValue, currentTree) -> { accumulatedTree.addChild(currentTree); - Integer combinedValue = - valueOp.apply(accumulatedValue, - currentValue); + Integer combinedValue = valueOp.apply( + accumulatedValue, currentValue); return new Pair<>(combinedValue, accumulatedTree); diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java index e934b9f..016fa8a 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java @@ -112,7 +112,10 @@ public class DiceASTEvaluator { String variableName = ((VariableDiceNode) leafNode).getVariable(); if (enviroment.containsKey(variableName)) { - return evaluateAST(enviroment.get(variableName), enviroment); + int result = + evaluateAST(enviroment.get(variableName), enviroment); + + return result; } // Value to allow for assignments @@ -148,6 +151,9 @@ public class DiceASTEvaluator { IPair<Integer, ITree<IDiceASTNode>> valueNode = nodes.getByIndex(1); + // Force valueNode to materialize for debugging purposes + valueNode.merge((l, r) -> null); + return nameNode.bindRight((nameTree) -> { return valueNode.bind((valueValue, valueTree) -> { if (containsSimpleVariable(nameTree)) { diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java new file mode 100644 index 0000000..6091cc3 --- /dev/null +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java @@ -0,0 +1,115 @@ +package bjc.dicelang.ast; + +import bjc.dicelang.ast.nodes.DiceASTType; +import bjc.dicelang.ast.nodes.IDiceASTNode; +import bjc.dicelang.ast.nodes.VariableDiceNode; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.ITree; +import bjc.utils.funcdata.Tree; + +/** + * Inline variables in a dice AST + * + * @author ben + * + */ +public class DiceASTInliner { + /** + * Inline all the variables in the AST + * + * @param ast + * The AST to inline variables into + * @param enviroment + * The enviroment to inline from + * @return The inlined AST + */ + public static ITree<IDiceASTNode> inlineAll(ITree<IDiceASTNode> ast, + IFunctionalMap<String, ITree<IDiceASTNode>> enviroment) { + // Tell the compiler that the null is for the entire varargs + // parameter, not a single one with a null value + return selectiveInline(ast, enviroment, (String[]) null); + } + + private static ITree<IDiceASTNode> inlineNode(IDiceASTNode node, + IFunctionalMap<String, ITree<IDiceASTNode>> enviroment, + boolean specificInline, + IFunctionalList<String> variableNames) { + if (node.getType() != DiceASTType.VARIABLE) { + return new Tree<>(node); + } + + String variableName = ((VariableDiceNode) node).getVariable(); + + if (specificInline) { + if (variableNames.contains(variableName)) { + if (!enviroment.containsKey(variableName)) { + throw new UnsupportedOperationException( + "Attempted to inline non-existant variable " + + variableName); + } + + return enviroment.get(variableName); + } + } else { + if (!enviroment.containsKey(variableName)) { + throw new UnsupportedOperationException( + "Attempted to inline non-existant variable " + + variableName); + } + + return enviroment.get(variableName); + } + + return new Tree<>(node); + } + + /** + * Inline the specified variables in the AST + * + * @param ast + * The AST to inline variables into + * @param enviroment + * The enviroment to inline from + * @param variables + * The variables to inline + * @return The inlined AST + */ + public static ITree<IDiceASTNode> selectiveInline( + ITree<IDiceASTNode> ast, + IFunctionalMap<String, ITree<IDiceASTNode>> enviroment, + String... variables) { + if (variables != null && variables.length > 0) { + IFunctionalList<String> variableNames = + new FunctionalList<>(variables); + + return ast.flatMapTree((node) -> { + return inlineNode(node, enviroment, true, variableNames); + }); + } + + return ast.flatMapTree((node) -> { + return inlineNode(node, enviroment, false, null); + }); + } + + /** + * Inline the specified variables in the AST + * + * @param ast + * The AST to inline variables into + * @param enviroment + * The enviroment to inline from + * @param variables + * The variables to inline + * @return The inlined AST + */ + public static ITree<IDiceASTNode> selectiveInline( + ITree<IDiceASTNode> ast, + IFunctionalMap<String, ITree<IDiceASTNode>> enviroment, + IFunctionalList<String> variables) { + return selectiveInline(ast, enviroment, + variables.toArray(new String[0])); + } +} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java index 95495bd..d8c94dc 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java @@ -28,17 +28,21 @@ public class DiceASTParser { * The list of tokens to convert * @return An AST built from the tokens */ - public static ITree<IDiceASTNode> createFromString( - IFunctionalList<String> tokens) { - ITree<String> rawTokens = TreeConstructor.constructTree(tokens, - (token) -> { + public static ITree<IDiceASTNode> + createFromString(IFunctionalList<String> tokens) { + ITree<String> rawTokens = + TreeConstructor.constructTree(tokens, (token) -> { return isOperatorNode(token); }, (operator) -> false, null); + // The last argument is valid because there are no special // operators yet, so it'll never get called - return rawTokens.rebuildTree(DiceASTParser::convertLeafNode, - DiceASTParser::convertOperatorNode); + ITree<IDiceASTNode> tokenizedTree = + rawTokens.rebuildTree(DiceASTParser::convertLeafNode, + DiceASTParser::convertOperatorNode); + + return tokenizedTree; } private static boolean isOperatorNode(String token) { @@ -52,8 +56,8 @@ public class DiceASTParser { } private static IDiceASTNode convertLeafNode(String leafNode) { - DiceLiteralType literalType = ILiteralDiceNode - .getLiteralType(leafNode); + DiceLiteralType literalType = + ILiteralDiceNode.getLiteralType(leafNode); if (literalType != null) { switch (literalType) { diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java index d034943..ab47b56 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java @@ -2,10 +2,6 @@ package bjc.dicelang.ast.nodes; import static bjc.dicelang.ast.nodes.DiceOperatorType.*; -// The following classes need to be changed upon addition of a new operator -// 1. DiceASTExpression -// 2. DiceASTFlattener -// 3. DiceASTParser /** * A node that represents an operator * |
