summaryrefslogtreecommitdiff
path: root/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-08 13:29:48 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-08 13:29:48 -0400
commit90d1cc6c9f47f1b6f74fb57e07865795a46c23b8 (patch)
treeb74cd5b9989c9f5a1bbde1e1b8c751faf9cb7086 /dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java
parentb1df3ff8c890bf6d4cc16fb4f28ddb7833512d71 (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.java307
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