summaryrefslogtreecommitdiff
path: root/dice-lang/src/bjc/dicelang/v2/Evaluator.java
diff options
context:
space:
mode:
authorbjculkin <bjculkin@WIT-136XG42.wvu-ad.wvu.edu>2017-03-01 10:13:41 -0500
committerbjculkin <bjculkin@WIT-136XG42.wvu-ad.wvu.edu>2017-03-01 10:13:41 -0500
commit36e0911c6ec27707a74f0b90b1052a16374243ea (patch)
tree08ca7723b0c0a6a7f3ce1830c59e5211e46168b8 /dice-lang/src/bjc/dicelang/v2/Evaluator.java
parent6ed83507953322c35a456d64d89f8f4f9cb0a6a1 (diff)
Package reorganization
Diffstat (limited to 'dice-lang/src/bjc/dicelang/v2/Evaluator.java')
-rw-r--r--dice-lang/src/bjc/dicelang/v2/Evaluator.java424
1 files changed, 0 insertions, 424 deletions
diff --git a/dice-lang/src/bjc/dicelang/v2/Evaluator.java b/dice-lang/src/bjc/dicelang/v2/Evaluator.java
deleted file mode 100644
index ed9db17..0000000
--- a/dice-lang/src/bjc/dicelang/v2/Evaluator.java
+++ /dev/null
@@ -1,424 +0,0 @@
-package bjc.dicelang.v2;
-
-import bjc.dicelang.v2.dice.CompoundDie;
-import bjc.dicelang.v2.dice.MathDie;
-import bjc.dicelang.v2.dice.SimpleDie;
-import bjc.dicelang.v2.dice.SimpleDieList;
-import bjc.utils.data.ITree;
-import bjc.utils.data.SingleIterator;
-import bjc.utils.data.Tree;
-import bjc.utils.data.TopDownTransformIterator;
-import bjc.utils.data.TopDownTransformResult;
-
-import static bjc.dicelang.v2.Errors.ErrorKey.*;
-import static bjc.dicelang.v2.EvaluatorResult.Type.*;
-
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.function.Consumer;
-
-public class Evaluator {
- private static enum CoerceSteps {
- INTEGER, FLOAT;
- }
-
- private static class Context {
- public Consumer<Iterator<ITree<Node>>> thunk;
-
- public boolean isDebug;
- }
-
- private static Node FAIL() {
- return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE));
- }
-
- private static Node FAIL(ITree<Node> orig) {
- return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE, orig));
- }
-
- private static Node FAIL(Node orig) {
- return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE, orig));
- }
-
- private static Node FAIL(EvaluatorResult res) {
- return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE, new Node(Node.Type.RESULT, res)));
- }
-
- private DiceLangEngine eng;
-
- public Evaluator(DiceLangEngine en) {
- eng = en;
- }
-
- public EvaluatorResult evaluate(ITree<Node> comm) {
- Context ctx = new Context();
-
- ctx.isDebug = false;
- ctx.thunk = (itr) -> {
- // Deliberately finish the iterator, but ignore results. It's only for stepwise evaluation
- // but we don't know if stepping the iterator causes something to happen
- while(itr.hasNext()) itr.next();
- };
-
- return comm.topDownTransform(this::pickEvaluationType,
- (node) -> this.evaluateNode(node, ctx)).getHead().resultVal;
- }
-
- // @FIXME Something's broken with step evaluation
- public Iterator<ITree<Node>> stepDebug(ITree<Node> comm) {
- Context ctx = new Context();
-
- ctx.isDebug = true;
-
- return new TopDownTransformIterator<>(this::pickEvaluationType, (node, thnk) -> {
- ctx.thunk = thnk;
-
- return this.evaluateNode(node, ctx);
- }, comm);
- }
-
- private TopDownTransformResult pickEvaluationType(Node nd) {
- switch(nd.type) {
- case UNARYOP:
- switch(nd.operatorType) {
- case COERCE:
- return TopDownTransformResult.RTRANSFORM;
- default:
- return TopDownTransformResult.PUSHDOWN;
- }
- default:
- return TopDownTransformResult.PUSHDOWN;
- }
- }
-
- private ITree<Node> evaluateNode(ITree<Node> ast, Context ctx) {
- switch(ast.getHead().type) {
- case UNARYOP:
- return evaluateUnaryOp(ast, ctx);
- case BINOP:
- return evaluateBinaryOp(ast, ctx);
- case TOKREF:
- return evaluateTokenRef(ast.getHead().tokenVal, ctx);
- case ROOT:
- return ast.getChild(ast.getChildrenCount() - 1);
- case RESULT:
- return ast;
- default:
- Errors.inst.printError(EK_EVAL_INVNODE, ast.getHead().type.toString());
- return new Tree<>(FAIL(ast));
- }
- }
-
- private ITree<Node> evaluateUnaryOp(ITree<Node> ast, Context ctx) {
- switch(ast.getHead().operatorType) {
- case COERCE:
- if(ast.getChildrenCount() != 1) {
- Errors.inst.printError(EK_EVAL_UNUNARY, Integer.toString(ast.getChildrenCount()));
- return new Tree<>(FAIL(ast));
- }
-
- ITree<Node> toCoerce = ast.getChild(0);
- ITree<Node> retVal = new Tree<>(toCoerce.getHead());
- Deque<ITree<Node>> children = new LinkedList<>();
-
- CoerceSteps curLevel = CoerceSteps.INTEGER;
-
- for(int i = 0; i < toCoerce.getChildrenCount(); i++) {
- ITree<Node> child = toCoerce.getChild(i);
- ITree<Node> nChild = null;
-
- if(ctx.isDebug) {
- Iterator<ITree<Node>> nd = stepDebug(child);
-
- for(; nd.hasNext(); nChild = nd.next()) {
- ctx.thunk.accept(new SingleIterator<>(child));
- }
- } else {
- nChild = new Tree<>(new Node(Node.Type.RESULT, evaluate(child)));
-
- if(nChild != null) ctx.thunk.accept(new SingleIterator<>(nChild));
- }
-
- Node childNode = nChild.getHead();
- EvaluatorResult res = childNode.resultVal;
-
- if(res.type == FLOAT) curLevel = CoerceSteps.FLOAT;
-
- children.add(nChild);
- }
-
- for(ITree<Node> child : children) {
- Node nd = child.getHead();
- EvaluatorResult res = nd.resultVal;
-
- switch(res.type) {
- case INT:
- if(curLevel == CoerceSteps.FLOAT) {
- nd.resultVal = new EvaluatorResult(FLOAT, (double)res.intVal);
- }
- default:
- // Do nothing
- break;
- }
-
- retVal.addChild(child);
- }
-
- return retVal;
- default:
- Errors.inst.printError(EK_EVAL_INVUNARY, ast.getHead().operatorType.toString());
- return new Tree<>(FAIL(ast));
- }
- }
-
- private ITree<Node> evaluateBinaryOp(ITree<Node> ast, Context ctx) {
- Token.Type binOp = ast.getHead().operatorType;
-
- if(ast.getChildrenCount() != 2) {
- Errors.inst.printError(EK_EVAL_INVBIN, Integer.toString(ast.getChildrenCount()), ast.toString());
-
- return new Tree<>(FAIL(ast));
- }
-
- ITree<Node> left = ast.getChild(0);
- ITree<Node> right = ast.getChild(1);
-
- switch(binOp) {
- case ADD:
- case SUBTRACT:
- case MULTIPLY:
- case DIVIDE:
- case IDIVIDE:
- return evaluateMathBinary(binOp,
- left.getHead().resultVal, right.getHead().resultVal,
- ctx);
- case DICEGROUP:
- case DICECONCAT:
- case DICELIST:
- return evaluateDiceBinary(binOp,
- left.getHead().resultVal, right.getHead().resultVal,
- ctx);
- default:
- Errors.inst.printError(EK_EVAL_UNBIN, binOp.toString());
- return new Tree<>(FAIL(ast));
- }
- }
-
- private ITree<Node> evaluateDiceBinary(Token.Type op,
- EvaluatorResult left, EvaluatorResult right, Context ctx) {
- EvaluatorResult res = null;
-
- switch(op) {
- case DICEGROUP:
- if(left.type == DICE && !left.diceVal.isList) {
- if(right.type == DICE && !right.diceVal.isList) {
- res = new EvaluatorResult(DICE,
- new SimpleDie(left.diceVal.scalar, right.diceVal.scalar));
- } else if (right.type == INT) {
- res = new EvaluatorResult(DICE, new SimpleDie(left.diceVal.scalar, right.intVal));
- } else {
- Errors.inst.printError(EK_EVAL_INVDGROUP, right.type.toString());
- return new Tree<>(FAIL(right));
- }
- } else if(left.type == INT) {
- if(right.type == DICE && !right.diceVal.isList) {
- res = new EvaluatorResult(DICE, new SimpleDie(left.intVal, right.diceVal.scalar));
- } else if (right.type == INT) {
- res = new EvaluatorResult(DICE, new SimpleDie(left.intVal, right.intVal));
- } else {
- Errors.inst.printError(EK_EVAL_INVDGROUP, right.type.toString());
- return new Tree<>(FAIL(right));
- }
- } else {
- Errors.inst.printError(EK_EVAL_INVDGROUP, left.type.toString());
- return new Tree<>(FAIL(left));
- }
- case DICECONCAT:
- if(left.type != DICE || left.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, left.type.toString());
- return new Tree<>(FAIL(left));
- } else if(right.type != DICE || right.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, right.type.toString());
- return new Tree<>(FAIL(right));
- } else {
- res = new EvaluatorResult(DICE,
- new CompoundDie(left.diceVal.scalar, right.diceVal.scalar));
- }
- break;
- case DICELIST:
- if(left.type != DICE || left.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, left.type.toString());
- return new Tree<>(FAIL(left));
- } else if(right.type != DICE || right.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, right.type.toString());
- return new Tree<>(FAIL(right));
- } else {
- res = new EvaluatorResult(DICE,
- new SimpleDieList(left.diceVal.scalar, right.diceVal.scalar));
- }
- break;
- default:
- Errors.inst.printError(EK_EVAL_UNDICE, op.toString());
- return new Tree<>(FAIL());
- }
-
- return new Tree<>(new Node(Node.Type.RESULT, res));
- }
-
- private ITree<Node> evaluateMathBinary(Token.Type op,
- EvaluatorResult left, EvaluatorResult right, Context ctx) {
- if(left.type == STRING || right.type == STRING) {
- Errors.inst.printError(EK_EVAL_STRINGMATH);
- return new Tree<>(FAIL());
- } else if(left.type == FAILURE || right.type == FAILURE) {
- return new Tree<>(FAIL());
- } else if(left.type == INT && right.type != INT) {
- Errors.inst.printError(EK_EVAL_MISMATH);
- return new Tree<>(FAIL(right));
- } else if(left.type == FLOAT && right.type != FLOAT) {
- Errors.inst.printError(EK_EVAL_MISMATH);
- return new Tree<>(FAIL(right));
- } else if(left.type == DICE && right.type != DICE) {
- Errors.inst.printError(EK_EVAL_MISMATH);
- return new Tree<>(FAIL(right));
- } else if(right.type == INT && left.type != INT) {
- Errors.inst.printError(EK_EVAL_MISMATH);
- return new Tree<>(FAIL(left));
- } else if(right.type == FLOAT && left.type != FLOAT) {
- Errors.inst.printError(EK_EVAL_MISMATH);
- return new Tree<>(FAIL(left));
- } else if(right.type == DICE && left.type != DICE) {
- Errors.inst.printError(EK_EVAL_MISMATH);
- return new Tree<>(FAIL(left));
- }
-
- EvaluatorResult res = null;
-
- switch(op) {
- case ADD:
- if(left.type == INT) {
- res = new EvaluatorResult(INT, left.intVal + right.intVal);
- } else if(left.type == DICE) {
- if(left.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, left.toString());
- return new Tree<>(FAIL(left));
- } else if(right.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, right.toString());
- return new Tree<>(FAIL(right));
- }
-
- res = new EvaluatorResult(DICE, new MathDie(MathDie.MathOp.ADD,
- left.diceVal.scalar, right.diceVal.scalar));
- } else {
- res = new EvaluatorResult(FLOAT, left.floatVal + right.floatVal);
- }
- break;
- case SUBTRACT:
- if(left.type == INT) {
- res = new EvaluatorResult(INT, left.intVal - right.intVal);
- } else if(left.type == DICE) {
- if(left.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, left.toString());
- return new Tree<>(FAIL(left));
- } else if(right.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, right.toString());
- return new Tree<>(FAIL(right));
- }
-
- res = new EvaluatorResult(DICE, new MathDie(MathDie.MathOp.SUBTRACT,
- left.diceVal.scalar, right.diceVal.scalar));
- } else {
- res = new EvaluatorResult(FLOAT, left.floatVal - right.floatVal);
- }
- break;
- case MULTIPLY:
- if(left.type == INT) {
- res = new EvaluatorResult(INT, left.intVal * right.intVal);
- } else if(left.type == DICE) {
- if(left.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, left.toString());
- return new Tree<>(FAIL(left));
- } else if(right.diceVal.isList) {
- Errors.inst.printError(EK_EVAL_INVDICE, right.toString());
- return new Tree<>(FAIL(right));
- }
-
- res = new EvaluatorResult(DICE, new MathDie(MathDie.MathOp.MULTIPLY,
- left.diceVal.scalar, right.diceVal.scalar));
- } else {
- res = new EvaluatorResult(FLOAT, left.floatVal * right.floatVal);
- }
- break;
- case DIVIDE:
- if(left.type == INT) {
- if(right.intVal == 0) {
- Errors.inst.printError(EK_EVAL_DIVZERO);
- res = new EvaluatorResult(FAILURE, right);
- } else {
- res = new EvaluatorResult(FLOAT, left.intVal / right.intVal);
- }
- } else if(left.type == FLOAT) {
- if(right.floatVal == 0) {
- Errors.inst.printError(EK_EVAL_DIVZERO);
- res = new EvaluatorResult(FAILURE, right);
- } else {
- res = new EvaluatorResult(FLOAT, left.floatVal / right.floatVal);
- }
- } else {
- Errors.inst.printError(EK_EVAL_DIVDICE);
- return new Tree<>(FAIL());
- }
- break;
- case IDIVIDE:
- if(left.type == INT) {
- if(right.intVal == 0) {
- Errors.inst.printError(EK_EVAL_DIVZERO);
- res = new EvaluatorResult(FAILURE, right);
- } else {
- res = new EvaluatorResult(INT, (int) (left.intVal / right.intVal));
- }
- } else if(left.type == FLOAT) {
- if(right.floatVal == 0) {
- Errors.inst.printError(EK_EVAL_DIVZERO);
- res = new EvaluatorResult(FAILURE, right);
- } else {
- res = new EvaluatorResult(INT, (int) (left.floatVal / right.floatVal));
- }
- } else {
- Errors.inst.printError(EK_EVAL_DIVDICE);
- return new Tree<>(FAIL());
- }
- break;
- default:
- Errors.inst.printError(EK_EVAL_UNMATH, op.toString());
- return new Tree<>(FAIL());
- }
-
- return new Tree<>(new Node(Node.Type.RESULT, res));
- }
-
- private ITree<Node> evaluateTokenRef(Token tk, Context ctx) {
- EvaluatorResult res = null;
-
- switch(tk.type) {
- case INT_LIT:
- res = new EvaluatorResult(INT, tk.intValue);
- break;
- case FLOAT_LIT:
- res = new EvaluatorResult(FLOAT, tk.floatValue);
- break;
- case DICE_LIT:
- res = new EvaluatorResult(DICE, tk.diceValue);
- break;
- case STRING_LIT:
- res = new EvaluatorResult(STRING, eng.stringLits.get((int)(tk.intValue)));
- break;
- default:
- Errors.inst.printError(EK_EVAL_UNTOK, tk.type.toString());
- res = new EvaluatorResult(FAILURE);
- }
-
- return new Tree<>(new Node(Node.Type.RESULT, res));
- }
-}