diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-04-08 13:29:48 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-04-08 13:29:48 -0400 |
| commit | 90d1cc6c9f47f1b6f74fb57e07865795a46c23b8 (patch) | |
| tree | b74cd5b9989c9f5a1bbde1e1b8c751faf9cb7086 /dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java | |
| parent | b1df3ff8c890bf6d4cc16fb4f28ddb7833512d71 (diff) | |
Change to data interfaces, as well as prepare to rewrite parser
Diffstat (limited to 'dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java')
| -rw-r--r-- | dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java deleted file mode 100644 index 3552926..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java +++ /dev/null @@ -1,307 +0,0 @@ -package bjc.dicelang.ast; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - -import bjc.dicelang.ComplexDice; -import bjc.dicelang.IDiceExpression; -import bjc.dicelang.ast.nodes.DiceASTType; -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.nodes.LiteralDiceNode; -import bjc.dicelang.ast.nodes.OperatorDiceNode; -import bjc.dicelang.ast.nodes.VariableDiceNode; -import bjc.utils.data.GenHolder; -import bjc.utils.data.Pair; -import bjc.utils.funcdata.bst.ITreePart.TreeLinearizationMethod; -import bjc.utils.parserutils.AST; - -/** - * An implementation of {@link IDiceExpression} backed by an AST of - * {@link IDiceASTNode}s - * - * @author ben - * - */ -public class DiceASTExpression implements IDiceExpression { - - private static final class VariableRetriever - implements Function<IDiceASTNode, String> { - @Override - public String apply(IDiceASTNode node) { - if (node.getType() != DiceASTType.VARIABLE) { - throw new UnsupportedOperationException( - "Attempted to assign to something that isn't a variable." - + " This isn't supported yet. The problem node is " - + node); - } - - return ((VariableDiceNode) node).getVariable(); - } - } - - /** - * Build the map of operations to use when collapsing the AST - * - * @param enviroment - * The enviroment to evaluate bindings and such against - * @return The operations to use when collapsing the AST - */ - private static Map<IDiceASTNode, IOperatorCollapser> buildOperations( - Map<String, DiceASTExpression> enviroment) { - Map<IDiceASTNode, IOperatorCollapser> operatorCollapsers = new HashMap<>(); - - operatorCollapsers.put(OperatorDiceNode.ADD, - (leftNode, rightNode) -> { - return leftNode.merge((leftValue, leftAST) -> { - return rightNode.merge((rightValue, rightAST) -> { - return new Pair<>(leftValue + rightValue, - new AST<>(OperatorDiceNode.ADD, - leftAST, rightAST)); - }); - }); - - }); - operatorCollapsers.put(OperatorDiceNode.SUBTRACT, - (leftNode, rightNode) -> { - return leftNode.merge((leftValue, leftAST) -> { - return rightNode.merge((rightValue, rightAST) -> { - return new Pair<>(leftValue - rightValue, - new AST<>(OperatorDiceNode.SUBTRACT, - leftAST, rightAST)); - }); - }); - }); - - operatorCollapsers.put(OperatorDiceNode.MULTIPLY, - (leftNode, rightNode) -> { - return leftNode.merge((leftValue, leftAST) -> { - return rightNode.merge((rightValue, rightAST) -> { - return new Pair<>(leftValue * rightValue, - new AST<>(OperatorDiceNode.MULTIPLY, - leftAST, rightAST)); - }); - }); - - }); - operatorCollapsers.put(OperatorDiceNode.DIVIDE, - (leftNode, rightNode) -> { - return leftNode.merge((leftValue, leftAST) -> { - return rightNode.merge((rightValue, rightAST) -> { - if (rightValue == 0) { - throw new ArithmeticException( - "Attempted to divide by zero. The AST of the problem expression is " - + rightAST); - } - - return new Pair<>(leftValue / rightValue, - new AST<>(OperatorDiceNode.DIVIDE, - leftAST, rightAST)); - }); - }); - }); - - operatorCollapsers.put(OperatorDiceNode.ASSIGN, (left, right) -> { - return parseBinding(enviroment, left, right); - }); - - operatorCollapsers.put(OperatorDiceNode.COMPOUND, - DiceASTExpression::parseCompound); - - operatorCollapsers.put(OperatorDiceNode.GROUP, - DiceASTExpression::parseGroup); - - return operatorCollapsers; - } - - private static Pair<Integer, AST<IDiceASTNode>> parseBinding( - Map<String, DiceASTExpression> enviroment, - Pair<Integer, AST<IDiceASTNode>> left, - Pair<Integer, AST<IDiceASTNode>> right) { - return left.merge((leftValue, leftAST) -> { - return right.merge((rightValue, rightAST) -> { - String variableName = leftAST - .collapse(new VariableRetriever(), (operator) -> { - throw new UnsupportedOperationException( - "Can only assign to plain variable names. The problem operator is " - + operator); - }, (returnedAST) -> returnedAST); - - GenHolder<Boolean> selfReference = new GenHolder<>(false); - - DiceASTReferenceChecker refChecker = new DiceASTReferenceChecker( - selfReference, variableName); - - rightAST.traverse(TreeLinearizationMethod.PREORDER, - refChecker); - - // Ignore meta-variable that'll be auto-frozen to restore - // definition sanity - if (selfReference.unwrap((bool) -> bool) - && !variableName.equals("last")) { - throw new UnsupportedOperationException( - "Variable '" + variableName - + "' references itself. Problematic definition: \n\t" - + rightAST); - } - - if (!variableName.equals("last")) { - enviroment.put(variableName, - new DiceASTExpression(rightAST, enviroment)); - } else { - // Do nothing, last is a auto-handled meta-variable - } - - return new Pair<>(rightValue, new AST<>( - OperatorDiceNode.ASSIGN, leftAST, rightAST)); - }); - }); - } - - private static Pair<Integer, AST<IDiceASTNode>> parseCompound( - Pair<Integer, AST<IDiceASTNode>> leftNode, - Pair<Integer, AST<IDiceASTNode>> rightNode) { - return leftNode.merge((leftValue, leftAST) -> { - return rightNode.merge((rightValue, rightAST) -> { - int compoundValue = Integer - .parseInt(Integer.toString(leftValue) - + Integer.toString(rightValue)); - - return new Pair<>(compoundValue, new AST<>( - OperatorDiceNode.COMPOUND, leftAST, rightAST)); - }); - }); - } - - private static Pair<Integer, AST<IDiceASTNode>> parseGroup( - Pair<Integer, AST<IDiceASTNode>> leftNode, - Pair<Integer, AST<IDiceASTNode>> rightNode) { - return leftNode.merge((leftValue, leftAST) -> { - return rightNode.merge((rightValue, rightAST) -> { - if (leftValue < 0) { - throw new UnsupportedOperationException( - "Can't attempt to roll a negative number of dice." - + " The problematic AST is " - + leftAST); - } else if (rightValue < 1) { - throw new UnsupportedOperationException( - "Can't roll dice with less than one side." - + " The problematic AST is " - + rightAST); - } - - int rolledValue = new ComplexDice(leftValue, rightValue) - .roll(); - - return new Pair<>(rolledValue, new AST<>( - OperatorDiceNode.GROUP, leftAST, rightAST)); - }); - }); - } - - /** - * The AST this expression will evaluate - */ - private AST<IDiceASTNode> ast; - - /** - * The enviroment to evaluate bindings and such against - */ - private Map<String, DiceASTExpression> env; - - /** - * Create a new dice expression backed by an AST - * - * @param ast - * The AST backing this expression - * @param env - * The enviroment to evaluate bindings against - */ - public DiceASTExpression(AST<IDiceASTNode> ast, - Map<String, DiceASTExpression> env) { - this.ast = ast; - this.env = env; - } - - /** - * Expand a leaf AST token into a pair for evaluation - * - * @param leafNode - * The token to evaluate - * @return A pair consisting of the token's value and the AST it - * represents - */ - private Pair<Integer, AST<IDiceASTNode>> evaluateLeaf( - IDiceASTNode leafNode) { - if (leafNode.getType() == DiceASTType.VARIABLE) { - VariableDiceNode node = (VariableDiceNode) leafNode; - - return parseVariable(node); - } else if (leafNode.getType() == DiceASTType.LITERAL) { - LiteralDiceNode node = (LiteralDiceNode) leafNode; - - return node.toParseValue(); - } else { - throw new UnsupportedOperationException("Found leaf operator " - + leafNode + ". These aren't supported."); - } - } - - private Pair<Integer, AST<IDiceASTNode>> parseVariable( - VariableDiceNode leafNode) { - String varName = leafNode.getVariable(); - - if (env.containsKey(varName)) { - return new Pair<>(env.get(varName).roll(), - new AST<>(leafNode)); - } else { - // Handle special case for defining variables - return new Pair<>(0, new AST<>(leafNode)); - } - } - - /** - * Get the AST bound to this expression - * - * @return the ast - */ - public AST<IDiceASTNode> getAst() { - return ast; - } - - /* - * (non-Javadoc) - * - * @see bjc.utils.dice.IDiceExpression#roll() - */ - @Override - public int roll() { - Map<IDiceASTNode, IOperatorCollapser> operations = buildOperations( - env); - - return ast.collapse(this::evaluateLeaf, operations::get, - (returnedValue) -> returnedValue - .merge((left, right) -> left)); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return ast.toString(); - } - - @Override - public int optimize() { - throw new UnsupportedOperationException( - "Use DiceASTOptimizer for optimizing these"); - } - - @Override - public boolean canOptimize() { - return false; - } -}
\ No newline at end of file |
