diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-10-27 21:56:18 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-10-27 22:12:47 -0400 |
| commit | e7413128ff4e376997de6e94e4bea5eca14811ef (patch) | |
| tree | 0749e270fdb754d04dc223abd95d47436508047f /dice-lang/src/main/java/bjc/dicelang/ast | |
| parent | e13a6981bd278c2cfc3b5ecb2517367b117f7a52 (diff) | |
Moved examples
Diffstat (limited to 'dice-lang/src/main/java/bjc/dicelang/ast')
30 files changed, 0 insertions, 2165 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 deleted file mode 100644 index 2b9eaa4..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java +++ /dev/null @@ -1,192 +0,0 @@ -package bjc.dicelang.ast; - -import java.util.function.BinaryOperator; - -import bjc.utils.data.IPair; -import bjc.utils.data.Pair; -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.Tree; - -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.nodes.OperatorDiceNode; - -/** - * Responsible for collapsing arithmetic operators - * - * @author ben - * - */ -final class ArithmeticCollapser implements IOperatorCollapser { - // The type of operator we're collapsing - private OperatorDiceNode type; - - // The operator to use to collapse operators - private BinaryOperator<Integer> valueOp; - - private int initialValue; - - public ArithmeticCollapser(OperatorDiceNode type, - BinaryOperator<Integer> valueOp, int initVal) { - this.type = type; - this.valueOp = valueOp; - this.initialValue = initVal; - } - - @Override - public IPair<IResult, ITree<IDiceASTNode>> apply( - IList<IPair<IResult, ITree<IDiceASTNode>>> nodes) { - IPair<IResult, ITree<IDiceASTNode>> initialState = new Pair<>( - new IntegerResult(initialValue), new Tree<>(type)); - - BinaryOperator<IPair<IResult, ITree<IDiceASTNode>>> reducer = ( - currentState, accumulatedState) -> { - // Force evaluation of accumulated state to prevent - // certain bugs from occuring - // accumulatedState.merge((l, r) -> null); - - return reduceStates(accumulatedState, currentState); - }; - - IPair<IResult, ITree<IDiceASTNode>> reducedState = nodes - .reduceAux(initialState, reducer, (state) -> state); - - return reducedState; - } - - private IList<IResult> combineArrayResults(IResult accumulatedValue, - IResult currentValue) { - IList<IResult> currentList = ((ArrayResult) currentValue) - .getValue(); - IList<IResult> accumulatedList = ((ArrayResult) accumulatedValue) - .getValue(); - - if (currentList.getSize() != accumulatedList.getSize()) { - throw new UnsupportedOperationException( - "Can only apply operations to equal-length arrays"); - } - - IList<IResult> resultList = currentList.combineWith( - accumulatedList, (currentNode, accumulatedNode) -> { - boolean currentNotInt = currentNode - .getType() != ResultType.INTEGER; - boolean accumulatedNotInt = accumulatedNode - .getType() != ResultType.INTEGER; - - if (currentNotInt || accumulatedNotInt) { - throw new UnsupportedOperationException( - "Nesting of array operations isn't allowed"); - } - - int accumulatedInt = ((IntegerResult) accumulatedNode) - .getValue(); - int currentInt = ((IntegerResult) currentNode) - .getValue(); - - IResult combinedValue = new IntegerResult( - valueOp.apply(accumulatedInt, currentInt)); - return combinedValue; - }); - return resultList; - } - - private IPair<IResult, ITree<IDiceASTNode>> doArithmeticCollapse( - IResult accumulatedValue, ITree<IDiceASTNode> accumulatedTree, - IResult currentValue) { - if (accumulatedValue.getType() == ResultType.DUMMY - || currentValue.getType() == ResultType.DUMMY) { - DummyResult result = new DummyResult( - "Found dummy result with either accumulated dummy (" - + ((DummyResult) accumulatedValue).getData() - + ") or current dummy (" - + ((DummyResult) currentValue).getData() - + ")."); - - return new Pair<>(result, accumulatedTree); - } - - boolean currentIsInt = currentValue - .getType() == ResultType.INTEGER; - boolean accumulatedIsInt = accumulatedValue - .getType() == ResultType.INTEGER; - - if (!currentIsInt) { - if (!accumulatedIsInt) { - IList<IResult> resultList = combineArrayResults( - accumulatedValue, currentValue); - - return new Pair<>(new ArrayResult(resultList), - accumulatedTree); - } - - IList<IResult> resultList = halfCombineLists( - ((ArrayResult) currentValue).getValue(), - accumulatedValue, true); - - return new Pair<>(new ArrayResult(resultList), - accumulatedTree); - } else if (!accumulatedIsInt) { - IList<IResult> resultList = halfCombineLists( - ((ArrayResult) accumulatedValue).getValue(), - currentValue, false); - - return new Pair<>(new ArrayResult(resultList), - accumulatedTree); - } - - int accumulatedInt = ((IntegerResult) accumulatedValue).getValue(); - int currentInt = ((IntegerResult) currentValue).getValue(); - - int combinedValue = valueOp.apply(accumulatedInt, currentInt); - - return new Pair<>(new IntegerResult(combinedValue), - accumulatedTree); - } - - private IList<IResult> halfCombineLists(IList<IResult> list, - IResult scalar, boolean scalarLeft) { - if (scalar.getType() != ResultType.INTEGER) { - throw new UnsupportedOperationException( - "Nested array operations not supported"); - } - - int scalarInt = ((IntegerResult) scalar).getValue(); - - return list.map((element) -> { - if (element.getType() != ResultType.INTEGER) { - throw new UnsupportedOperationException( - "Nested array operations not supported"); - } - - int elementInt = ((IntegerResult) element).getValue(); - - IResult combinedValue; - - if (scalarLeft) { - combinedValue = new IntegerResult( - valueOp.apply(scalarInt, elementInt)); - } else { - combinedValue = new IntegerResult( - valueOp.apply(elementInt, scalarInt)); - } - - return combinedValue; - }); - } - - private IPair<IResult, ITree<IDiceASTNode>> reduceStates( - IPair<IResult, ITree<IDiceASTNode>> accumulatedState, - IPair<IResult, ITree<IDiceASTNode>> currentState) { - return accumulatedState - .bind((accumulatedValue, accumulatedTree) -> { - return currentState - .bind((currentValue, currentTree) -> { - accumulatedTree.addChild(currentTree); - - return doArithmeticCollapse( - accumulatedValue, accumulatedTree, - currentValue); - }); - }); - } -}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/ArrayResult.java b/dice-lang/src/main/java/bjc/dicelang/ast/ArrayResult.java deleted file mode 100644 index ac78287..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/ArrayResult.java +++ /dev/null @@ -1,43 +0,0 @@ -package bjc.dicelang.ast; - -import bjc.utils.funcdata.IList; - -/** - * Represents a result that is an array of other results - * - * @author ben - * - * TODO finish implementing me - */ -public class ArrayResult implements IResult { - private IList<IResult> arrayContents; - - /** - * Create a new array-valued result - * - * @param results - * The results in the array - */ - public ArrayResult(IList<IResult> results) { - this.arrayContents = results; - } - - @Override - public ResultType getType() { - return ResultType.ARRAY; - } - - /** - * Get the value of this result - * - * @return The value of this result - */ - public IList<IResult> getValue() { - return arrayContents; - } - - @Override - public String toString() { - return arrayContents.toString(); - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java deleted file mode 100644 index cef2e19..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java +++ /dev/null @@ -1,321 +0,0 @@ -package bjc.dicelang.ast; - -import java.util.function.Supplier; - -import bjc.utils.data.IHolder; -import bjc.utils.data.IPair; -import bjc.utils.data.Identity; -import bjc.utils.data.LazyPair; -import bjc.utils.data.Pair; -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.IMap; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.Tree; - -import bjc.dicelang.ComplexDice; -import bjc.dicelang.ast.nodes.DiceASTType; -import bjc.dicelang.ast.nodes.DiceLiteralNode; -import bjc.dicelang.ast.nodes.DiceLiteralType; -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.dicelang.ast.nodes.VariableDiceNode; - -/** - * Evaluate a dice AST to an integer value - * - * @author ben - * - */ -public class DiceASTEvaluator { - private static IResult bindLiteralValue(IDiceASTNode leafNode, - IMap<String, ITree<IDiceASTNode>> enviroment) { - String variableName = ((VariableDiceNode) leafNode).getVariable(); - - if (enviroment.containsKey(variableName)) { - IResult result = evaluateAST(enviroment.get(variableName), - enviroment); - - return result; - } - - // Return a DummyResult to handle lets properly - return new DummyResult( - "Attempted to deref unbound variable " + variableName); - } - - /** - * 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 IMap<IDiceASTNode, IOperatorCollapser> buildOperations( - IMap<String, ITree<IDiceASTNode>> enviroment) { - IMap<IDiceASTNode, IOperatorCollapser> operatorCollapsers = new FunctionalMap<>(); - - operatorCollapsers.put(OperatorDiceNode.ADD, - new ArithmeticCollapser(OperatorDiceNode.ADD, - (left, right) -> left + right, 0)); - - operatorCollapsers.put(OperatorDiceNode.SUBTRACT, - new ArithmeticCollapser(OperatorDiceNode.SUBTRACT, - (left, right) -> left - right, 0)); - - operatorCollapsers.put(OperatorDiceNode.MULTIPLY, - new ArithmeticCollapser(OperatorDiceNode.MULTIPLY, - (left, right) -> left * right, 1)); - - operatorCollapsers.put(OperatorDiceNode.DIVIDE, - new ArithmeticCollapser(OperatorDiceNode.DIVIDE, - (left, right) -> left / right, 1)); - - operatorCollapsers.put(OperatorDiceNode.ASSIGN, (nodes) -> { - return parseBinding(enviroment, nodes); - }); - - operatorCollapsers.put(OperatorDiceNode.COMPOUND, - new ArithmeticCollapser(OperatorDiceNode.COMPOUND, - (left, right) -> { - return Integer.parseInt(Integer.toString(left) - + Integer.toString(right)); - }, 0)); - - operatorCollapsers.put(OperatorDiceNode.GROUP, - DiceASTEvaluator::parseGroup); - - operatorCollapsers.put(OperatorDiceNode.LET, (nodes) -> { - // @TODO Fix lets prematurely evaluating things - return parseLet(enviroment, nodes); - }); - - operatorCollapsers.put(OperatorDiceNode.ARRAY, (nodes) -> { - - // This is so that arrays respect lazy results properly - Supplier<IResult> resultSupplier = () -> { - IList<IResult> resultList = new FunctionalList<>(); - - nodes.forEach((node) -> { - resultList.add(node.getLeft()); - }); - - return new ArrayResult(resultList); - }; - - Supplier<ITree<IDiceASTNode>> treeSupplier = () -> { - ITree<IDiceASTNode> returnedTree = new Tree<>( - OperatorDiceNode.ARRAY); - - nodes.forEach((element) -> { - returnedTree.addChild(element.getRight()); - }); - - return returnedTree; - }; - - return new LazyPair<>(resultSupplier, treeSupplier); - }); - - return operatorCollapsers; - } - - private static void doArrayAssign( - IMap<String, ITree<IDiceASTNode>> enviroment, - IPair<IResult, ITree<IDiceASTNode>> nameNode, - ITree<IDiceASTNode> nameTree, ITree<IDiceASTNode> valueTree, - IHolder<Integer> childCount, ITree<IDiceASTNode> child) { - if (nameTree.getHead().getType() != DiceASTType.VARIABLE) { - throw new UnsupportedOperationException( - "Assigning to complex variables isn't supported. Problem node is " - + nameNode.getRight()); - } - - String varName = child.transformHead((nameNod) -> { - return ((VariableDiceNode) nameNod).getVariable(); - }); - - enviroment.put(varName, valueTree.getChild(childCount.getValue())); - - childCount.transform(val -> val + 1); - } - - /** - * Evaluate the provided AST to a numeric value - * - * @param expression - * The expression to evaluate - * @param enviroment - * The enviroment to look up variables in - * @return The integer value of the expression - */ - public static IResult evaluateAST(ITree<IDiceASTNode> expression, - IMap<String, ITree<IDiceASTNode>> enviroment) { - IMap<IDiceASTNode, IOperatorCollapser> collapsers = buildOperations( - enviroment); - - return expression.collapse( - (node) -> evaluateLeaf(node, enviroment), collapsers::get, - (pair) -> pair.getLeft()); - } - - private static IPair<IResult, ITree<IDiceASTNode>> evaluateLeaf( - IDiceASTNode leafNode, - IMap<String, ITree<IDiceASTNode>> enviroment) { - ITree<IDiceASTNode> returnedAST = new Tree<>(leafNode); - - switch (leafNode.getType()) { - case LITERAL: - return new Pair<>(evaluateLiteral(leafNode), returnedAST); - - case VARIABLE: - return new LazyPair<>(() -> { - return bindLiteralValue(leafNode, enviroment); - }, () -> returnedAST); - - case OPERATOR: - default: - throw new UnsupportedOperationException( - "Node '" + leafNode + "' cannot be a leaf."); - } - } - - private static IResult evaluateLiteral(IDiceASTNode leafNode) { - DiceLiteralType literalType = ((ILiteralDiceNode) leafNode) - .getLiteralType(); - - switch (literalType) { - case DICE: - int diceRoll = ((DiceLiteralNode) leafNode).getValue() - .roll(); - - return new IntegerResult(diceRoll); - case INTEGER: - int val = ((IntegerLiteralNode) leafNode).getValue(); - - return new IntegerResult(val); - default: - throw new UnsupportedOperationException("Literal value '" - + leafNode + "' is of a type (" + literalType - + ") not currently supported."); - } - } - - private static IPair<IResult, ITree<IDiceASTNode>> parseBinding( - IMap<String, ITree<IDiceASTNode>> enviroment, - IList<IPair<IResult, ITree<IDiceASTNode>>> nodes) { - if (nodes.getSize() != 2) { - throw new UnsupportedOperationException( - "Can only bind nodes with two children. Problem children are " - + nodes); - } - - IPair<IResult, ITree<IDiceASTNode>> nameNode = nodes.getByIndex(0); - IPair<IResult, ITree<IDiceASTNode>> valueNode = nodes - .getByIndex(1); - - return nameNode.bindRight((nameTree) -> { - return valueNode.bind((valueValue, valueTree) -> { - if (DiceASTUtils.containsSimpleVariable(nameTree)) { - String varName = nameTree.transformHead((nameNod) -> { - return ((VariableDiceNode) nameNod).getVariable(); - }); - - enviroment.put(varName, valueTree); - - return new Pair<>(valueValue, nameTree); - } else if (nameTree.getHead() == OperatorDiceNode.ARRAY) { - if (valueTree.getHead() == OperatorDiceNode.ARRAY) { - if (nameTree.getChildrenCount() != valueTree - .getChildrenCount()) { - throw new UnsupportedOperationException( - "Array assignment must be between two equal length arrays"); - } - - IHolder<Integer> childCount = new Identity<>(0); - - nameTree.doForChildren((child) -> { - doArrayAssign(enviroment, nameNode, nameTree, - valueTree, childCount, child); - - childCount.transform(val -> val + 1); - }); - - return new Pair<>(valueValue, nameTree); - } - - nameTree.doForChildren((child) -> { - String varName = child.transformHead((nameNod) -> { - return ((VariableDiceNode) nameNod) - .getVariable(); - }); - - enviroment.put(varName, valueTree); - }); - - return new Pair<>(valueValue, nameTree); - } - - throw new UnsupportedOperationException( - "Assigning to complex variables isn't supported. Problem node is " - + nameNode.getRight()); - }); - }); - } - - private static IPair<IResult, ITree<IDiceASTNode>> parseGroup( - IList<IPair<IResult, ITree<IDiceASTNode>>> nodes) { - if (nodes.getSize() != 2) { - throw new UnsupportedOperationException( - "Can only form a group from two dice"); - } - - IPair<IResult, ITree<IDiceASTNode>> numberDiceNode = nodes - .getByIndex(0); - IPair<IResult, ITree<IDiceASTNode>> diceTypeNode = nodes - .getByIndex(1); - - return numberDiceNode.bind((numberDiceValue, numberDiceTree) -> { - return diceTypeNode.bind((diceTypeValue, diceTypeTree) -> { - ComplexDice cDice = new ComplexDice( - ((IntegerResult) numberDiceValue).getValue(), - ((IntegerResult) diceTypeValue).getValue()); - - return new Pair<>(new IntegerResult(cDice.roll()), - new Tree<>(OperatorDiceNode.GROUP, numberDiceTree, - diceTypeTree)); - }); - }); - } - - private static IPair<IResult, ITree<IDiceASTNode>> parseLet( - IMap<String, ITree<IDiceASTNode>> enviroment, - IList<IPair<IResult, ITree<IDiceASTNode>>> nodes) { - if (nodes.getSize() != 2) { - throw new UnsupportedOperationException( - "Can only use let with two expressions."); - } - - ITree<IDiceASTNode> bindTree = nodes.getByIndex(0).getRight(); - ITree<IDiceASTNode> expressionTree = nodes.getByIndex(1) - .getRight(); - - IMap<String, ITree<IDiceASTNode>> letEnviroment = enviroment - .extend(); - - System.out.println("Evaluating tree for bound values"); - - evaluateAST(bindTree, letEnviroment); - - IResult exprResult = evaluateAST(expressionTree, letEnviroment); - - IList<ITree<IDiceASTNode>> childrn = nodes - .map((pair) -> pair.getRight()); - - return new Pair<>(exprResult, - new Tree<>(OperatorDiceNode.LET, childrn)); - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java deleted file mode 100644 index 305c9af..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java +++ /dev/null @@ -1,125 +0,0 @@ -package bjc.dicelang.ast; - -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.IMap; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.Tree; - -import bjc.dicelang.ast.nodes.DiceASTType; -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.nodes.VariableDiceNode; - -/** - * 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, - IMap<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, - IMap<String, ITree<IDiceASTNode>> enviroment, - boolean specificInline, IList<String> variableNames) { - // Only variables get inlined - if (node.getType() != DiceASTType.VARIABLE) { - return new Tree<>(node); - } - - // Get the name of what we're inlining - String variableName = ((VariableDiceNode) node).getVariable(); - - // If we're inlining only certain variables, do so - if (specificInline) { - // Only inline the variable if we're supposed to - if (variableNames.contains(variableName)) { - // You can't inline non-existent variables - if (!enviroment.containsKey(variableName)) { - throw new UnsupportedOperationException( - "Attempted to inline non-existant variable " - + variableName); - } - - // Return the tree for the variable - return enviroment.get(variableName); - } - } else { - // You can't inline non-existent variables - if (!enviroment.containsKey(variableName)) { - throw new UnsupportedOperationException( - "Attempted to inline non-existant variable " - + variableName); - } - - // Return the tree for the variable - 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, - IMap<String, ITree<IDiceASTNode>> enviroment, - IList<String> variables) { - return selectiveInline(ast, enviroment, - variables.toArray(new String[0])); - } - - /** - * 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, - IMap<String, ITree<IDiceASTNode>> enviroment, - String... variables) { - // If we're selectively inlining, do so - if (variables != null && variables.length > 0) { - IList<String> variableNames = new FunctionalList<>(variables); - - // Selectively inline each tree node - return ast.flatMapTree((node) -> { - return inlineNode(node, enviroment, true, variableNames); - }); - } - - // Inline everything in each node - return ast.flatMapTree((node) -> { - return inlineNode(node, enviroment, false, null); - }); - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTOptimizer.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTOptimizer.java deleted file mode 100644 index d7fc23c..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTOptimizer.java +++ /dev/null @@ -1,60 +0,0 @@ -package bjc.dicelang.ast; - -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.IMap; -import bjc.utils.funcdata.ITree; - -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.optimization.IOptimizationPass; - -/** - * Contains optimizations appliable to a dice AST - * - * @author ben - * - */ -public class DiceASTOptimizer { - private IList<IOptimizationPass> passes; - - /** - * Create a new optimizer - */ - public DiceASTOptimizer() { - passes = new FunctionalList<>(); - } - - /** - * Add a pass to the list of optimization passes - * - * @param pass - * The pass to add - */ - public void addPass(IOptimizationPass pass) { - passes.add(pass); - } - - /** - * Optimize the passed in tree - * - * @param ast - * The tree to optimize - * @param enviroment - * The enviroment for variable references - * @return The optimized tree - */ - public ITree<IDiceASTNode> optimizeTree(ITree<IDiceASTNode> ast, - IMap<String, ITree<IDiceASTNode>> enviroment) { - ITree<IDiceASTNode> optimizedTree = passes.reduceAux(ast, - (currentPass, currentTree) -> { - return currentTree.collapse(currentPass::optimizeLeaf, - (operator) -> { - return (nodes) -> { - return currentPass.optimizeOperator( - operator, nodes); - }; - }, (tree) -> tree); - }, (tree) -> tree); - return optimizedTree; - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java deleted file mode 100644 index 9a36951..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java +++ /dev/null @@ -1,160 +0,0 @@ -package bjc.dicelang.ast; - -import java.util.Deque; -import java.util.InputMismatchException; -import java.util.function.Function; -import java.util.function.Predicate; - -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.IMap; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.Tree; -import bjc.utils.funcutils.StringUtils; -import bjc.utils.parserutils.TreeConstructor; - -import bjc.dicelang.IDiceExpression; -import bjc.dicelang.ast.nodes.DiceLiteralNode; -import bjc.dicelang.ast.nodes.DiceLiteralType; -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.dicelang.ast.nodes.VariableDiceNode; - -/** - * Parse a string expression into AST form. Doesn't do anything else - * - * @author ben - * - */ -public class DiceASTParser { - private static IDiceASTNode convertLeafNode(String leafNode) { - DiceLiteralType literalType = ILiteralDiceNode - .getLiteralType(leafNode); - - if (literalType != null) { - switch (literalType) { - case DICE: - return new DiceLiteralNode( - IDiceExpression.toExpression(leafNode)); - case INTEGER: - return new IntegerLiteralNode( - Integer.parseInt(leafNode)); - default: - throw new InputMismatchException( - "Cannot convert string '" + leafNode - + "' into a literal."); - } - } - - if (leafNode.matches("[+-]?\\d*\\.\\d+")) { - throw new InputMismatchException( - "Floating point literals are not supported"); - } - - return new VariableDiceNode(leafNode); - } - - private static IDiceASTNode convertOperatorNode(String operatorNode) { - try { - return OperatorDiceNode.fromString(operatorNode); - } catch (IllegalArgumentException iaex) { - InputMismatchException imex = new InputMismatchException( - "Attempted to parse invalid operator " + operatorNode); - - imex.initCause(iaex); - - throw imex; - } - } - - /** - * Create an AST from a list of tokens - * - * @param tokens - * The list of tokens to convert - * @return An AST built from the tokens - */ - public static ITree<IDiceASTNode> createFromString( - IList<String> tokens) { - Predicate<String> specialPicker = (operator) -> { - if (StringUtils.containsOnly(operator, "\\[")) { - return true; - } else if (StringUtils.containsOnly(operator, "\\]")) { - return true; - } - - return false; - }; - - IMap<String, Function<Deque<ITree<String>>, ITree<String>>> operators = new FunctionalMap<>(); - - operators.put("[", (queuedTrees) -> { - Tree<String> openArray = new Tree<>("["); - - return openArray; - }); - - operators.put("]", (queuedTrees) -> { - return parseCloseArray(queuedTrees); - }); - - ITree<String> rawTokens = TreeConstructor.constructTree(tokens, - (token) -> { - return isOperatorNode(token); - }, specialPicker, operators::get); - - ITree<IDiceASTNode> tokenizedTree = rawTokens.rebuildTree( - DiceASTParser::convertLeafNode, - DiceASTParser::convertOperatorNode); - - return tokenizedTree; - } - - private static boolean isOperatorNode(String token) { - if (StringUtils.containsOnly(token, "\\[")) { - return true; - } else if (StringUtils.containsOnly(token, "\\]")) { - return true; - } - - if (token.equals("[]")) { - // This is a synthetic operator, constructed by [ and ] - return true; - } - - try { - OperatorDiceNode.fromString(token); - return true; - } catch (@SuppressWarnings("unused") IllegalArgumentException iaex) { - // We don't care about details - return false; - } - } - - private static ITree<String> parseCloseArray( - Deque<ITree<String>> queuedTrees) { - IList<ITree<String>> children = new FunctionalList<>(); - - while (shouldContinuePopping(queuedTrees)) { - children.add(queuedTrees.pop()); - } - - queuedTrees.pop(); - - children.reverse(); - - ITree<String> arrayTree = new Tree<>("[]", children); - - return arrayTree; - } - - private static boolean shouldContinuePopping( - Deque<ITree<String>> queuedTrees) { - String peekToken = queuedTrees.peek().getHead(); - - return !peekToken.equals("["); - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceChecker.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceChecker.java deleted file mode 100644 index 34414c5..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceChecker.java +++ /dev/null @@ -1,61 +0,0 @@ -package bjc.dicelang.ast; - -import java.util.function.Consumer; - -import bjc.utils.data.IHolder; - -import bjc.dicelang.ast.nodes.DiceASTType; -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.nodes.VariableDiceNode; - -/** - * Check if the specified node references a particular variable - * - * @author ben - * - */ -public final class DiceASTReferenceChecker - implements Consumer<IDiceASTNode> { - /** - * This is true if the specified node references the set variable - */ - private IHolder<Boolean> referencesVariable; - - private String varName; - - /** - * Create a new reference checker - * - * @param referencesVar - * The holder of whether the variable is referenced or not - * @param varName - * The variable to check for references in - */ - public DiceASTReferenceChecker(IHolder<Boolean> referencesVar, - String varName) { - this.referencesVariable = referencesVar; - this.varName = varName; - } - - @Override - public void accept(IDiceASTNode astNode) { - referencesVariable.transform((bool) -> isDirectReference(astNode)); - } - - /** - * Check if a given AST node directly references the specified variable - * - * @param astNode - * The node to check - * @return Whether or not the node directly the variable - */ - private boolean isDirectReference(IDiceASTNode astNode) { - if (astNode.getType() == DiceASTType.VARIABLE) { - VariableDiceNode node = (VariableDiceNode) astNode; - - return node.getVariable().equals(varName); - } - - return false; - } -}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceSanitizer.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceSanitizer.java deleted file mode 100644 index d8f658e..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceSanitizer.java +++ /dev/null @@ -1,201 +0,0 @@ -package bjc.dicelang.ast; - -import bjc.utils.data.IHolder; -import bjc.utils.data.Identity; -import bjc.utils.funcdata.IMap; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.TopDownTransformResult; -import bjc.utils.funcdata.Tree; - -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.nodes.OperatorDiceNode; -import bjc.dicelang.ast.nodes.VariableDiceNode; - -/** - * Sanitize the references in an AST so that a variable that refers to - * itself in its definition has the occurance of it replaced with its - * previous definition - * - * @author ben - * - */ -public class DiceASTReferenceSanitizer { - private static ITree<IDiceASTNode> doSanitize(ITree<IDiceASTNode> ast, - IMap<String, ITree<IDiceASTNode>> enviroment) { - if (ast.getChildrenCount() != 2) { - throw new UnsupportedOperationException( - "Assignment must have two arguments."); - } - - ITree<IDiceASTNode> nameTree = ast.getChild(0); - ITree<IDiceASTNode> valueTree = ast.getChild(1); - - if (!DiceASTUtils.containsSimpleVariable(nameTree)) { - if (nameTree.getHead() == OperatorDiceNode.ARRAY) { - IHolder<Boolean> allSimpleVariables = new Identity<>(true); - - nameTree.doForChildren((child) -> { - if (allSimpleVariables.getValue()) { - boolean isSimple = DiceASTUtils - .containsSimpleVariable(child); - - allSimpleVariables.replace(isSimple); - } - }); - - if (!allSimpleVariables.getValue()) { - throw new UnsupportedOperationException( - "Array assignment must be between variables and" - + " a expression/array of expressions"); - } - - if (valueTree.getHead() == OperatorDiceNode.ARRAY) { - if (nameTree.getChildrenCount() != valueTree - .getChildrenCount()) { - throw new UnsupportedOperationException( - "Array assignment between arrays must be" - + " between two arrays of equal length"); - } - } - } else { - throw new UnsupportedOperationException( - "Assignment must be between a variable and a expression"); - } - } - - if (nameTree.getHead() == OperatorDiceNode.ARRAY) { - if (valueTree.getHead() == OperatorDiceNode.ARRAY) { - IHolder<Integer> childCounter = new Identity<>(0); - - ITree<IDiceASTNode> returnTree = new Tree<>( - OperatorDiceNode.ARRAY); - - nameTree.doForChildren((child) -> { - String variableName = child.transformHead((node) -> { - return ((VariableDiceNode) node).getVariable(); - }); - - ITree<IDiceASTNode> currentValue = valueTree - .getChild(childCounter.getValue()); - - ITree<IDiceASTNode> sanitizedSubtree = doSingleSanitize( - ast, enviroment, child, currentValue, - variableName); - - if (sanitizedSubtree == null) { - ITree<IDiceASTNode> oldTree = new Tree<>( - ast.getHead(), child, currentValue); - - returnTree.addChild(oldTree); - } else { - returnTree.addChild(sanitizedSubtree); - } - - childCounter.transform((count) -> count + 1); - }); - - return returnTree; - } - - ITree<IDiceASTNode> returnTree = new Tree<>( - OperatorDiceNode.ARRAY); - - nameTree.doForChildren((child) -> { - String variableName = child.transformHead( - (node) -> ((VariableDiceNode) node).getVariable()); - - ITree<IDiceASTNode> sanitizedChild = doSingleSanitize(ast, - enviroment, child, valueTree, variableName); - if (sanitizedChild == null) { - ITree<IDiceASTNode> oldTree = new Tree<>(ast.getHead(), - child, valueTree); - - returnTree.addChild(oldTree); - } else { - returnTree.addChild(sanitizedChild); - } - }); - - return returnTree; - } - - String variableName = nameTree.transformHead( - (node) -> ((VariableDiceNode) node).getVariable()); - - ITree<IDiceASTNode> sanitizedTree = doSingleSanitize(ast, - enviroment, nameTree, valueTree, variableName); - - if (sanitizedTree == null) { - return ast; - } - - return sanitizedTree; - } - - private static ITree<IDiceASTNode> doSingleSanitize( - ITree<IDiceASTNode> ast, - IMap<String, ITree<IDiceASTNode>> enviroment, - ITree<IDiceASTNode> nameTree, ITree<IDiceASTNode> valueTree, - String variableName) { - if (enviroment.containsKey(variableName)) { - // @ is a meta-variable standing for the left side of an - // assignment - ITree<IDiceASTNode> oldVal = enviroment.put("@", - enviroment.get(variableName)); - - // We should always inline out references to last, because it - // will always change - ITree<IDiceASTNode> inlinedValue = DiceASTInliner - .selectiveInline(valueTree, enviroment, variableName, - "last", "@"); - - if (oldVal != null) { - enviroment.put("@", oldVal); - } else { - enviroment.remove("@"); - } - - return new Tree<>(ast.getHead(), nameTree, inlinedValue); - } - - return null; - } - - /** - * Sanitize the references in an AST - * - * @param ast - * @param enviroment - * @return The sanitized AST - */ - public static ITree<IDiceASTNode> sanitize(ITree<IDiceASTNode> ast, - IMap<String, ITree<IDiceASTNode>> enviroment) { - return ast.topDownTransform( - DiceASTReferenceSanitizer::shouldSanitize, (subTree) -> { - return doSanitize(subTree, enviroment); - }); - } - - private static TopDownTransformResult shouldSanitize( - IDiceASTNode node) { - if (!node.isOperator()) { - return TopDownTransformResult.SKIP; - } - - switch (((OperatorDiceNode) node)) { - case ASSIGN: - return TopDownTransformResult.TRANSFORM; - case ARRAY: - case LET: - return TopDownTransformResult.PASSTHROUGH; - case ADD: - case COMPOUND: - case DIVIDE: - case GROUP: - case MULTIPLY: - case SUBTRACT: - default: - return TopDownTransformResult.SKIP; - } - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTUtils.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTUtils.java deleted file mode 100644 index d98c8fe..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTUtils.java +++ /dev/null @@ -1,86 +0,0 @@ -package bjc.dicelang.ast; - -import bjc.utils.funcdata.ITree; - -import bjc.dicelang.IDiceExpression; -import bjc.dicelang.ScalarDie; -import bjc.dicelang.ast.nodes.DiceASTType; -import bjc.dicelang.ast.nodes.DiceLiteralNode; -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.nodes.ILiteralDiceNode; -import bjc.dicelang.ast.nodes.IntegerLiteralNode; - -/** - * Functions that are useful when dealing with dice ASTs - * - * @author ben - * - */ -public class DiceASTUtils { - /** - * Check if a dice AST contains a simple variable reference - * - * @param nameTree - * The tree to check for a reference in - * @return Whether or not a dice AST contains a simple variable - * reference - */ - public static boolean containsSimpleVariable( - ITree<IDiceASTNode> nameTree) { - return nameTree.transformHead((nameNode) -> { - if (nameNode.getType() != DiceASTType.VARIABLE) { - return false; - } - - return true; - }); - } - - /** - * Convert an literal AST node to a dice expression, if possible. - * - * @param tree - * The node to convert in tree form - * @return The tree as a dice expression - * - * @throws ClassCastException - * if the head of the tree is not a literal (implements - * {@link ILiteralDiceNode}) - * @throws UnsupportedOperationException - * if the head of the tree is not optimizable - */ - public static IDiceExpression literalToExpression( - ITree<IDiceASTNode> tree) { - ILiteralDiceNode literalNode = (ILiteralDiceNode) tree.getHead(); - - switch (literalNode.getLiteralType()) { - case DICE: - return ((DiceLiteralNode) literalNode).getValue(); - case INTEGER: - return new ScalarDie( - ((IntegerLiteralNode) literalNode).getValue()); - default: - throw new UnsupportedOperationException( - "This type of literal isn't convertable to an expression"); - } - } - - /** - * Convert an literal AST node to an integer, if possible. - * - * @param tree - * The literal node to convert, as a tree - * @return The node as an integer - * - * @throws ClassCastException - * if the head of the tree is not a literal (implements - * {@link ILiteralDiceNode}) - * @throws UnsupportedOperationException - * if the head of the tree is not optimizable - */ - public static int literalToInteger(ITree<IDiceASTNode> tree) { - return tree.transformHead((node) -> { - return ((ILiteralDiceNode) node).optimize(); - }); - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DummyResult.java b/dice-lang/src/main/java/bjc/dicelang/ast/DummyResult.java deleted file mode 100644 index a84bb7c..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DummyResult.java +++ /dev/null @@ -1,31 +0,0 @@ -package bjc.dicelang.ast; - -public class DummyResult implements IResult { - /* - * The reason why this result is a dummy - */ - private String dummyData; - - public DummyResult(String data) { - dummyData = data; - } - - /** - * Get the data in this dummy - * - * @return The reason why this result is a dummy - */ - public String getData() { - return dummyData; - } - - @Override - public ResultType getType() { - return ResultType.DUMMY; - } - - @Override - public String toString() { - return "Dummy with reason " + dummyData; - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/IOperatorCollapser.java b/dice-lang/src/main/java/bjc/dicelang/ast/IOperatorCollapser.java deleted file mode 100644 index 0efaca9..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/IOperatorCollapser.java +++ /dev/null @@ -1,20 +0,0 @@ -package bjc.dicelang.ast; - -import java.util.function.Function; - -import bjc.utils.data.IPair; -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.ITree; - -import bjc.dicelang.ast.nodes.IDiceASTNode; - -/** - * Alias for operator collapsers. Because 68-char types are too long - * - * @author ben - * - */ -public interface IOperatorCollapser extends - Function<IList<IPair<IResult, ITree<IDiceASTNode>>>, IPair<IResult, ITree<IDiceASTNode>>> { - // Just an alias -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/IResult.java b/dice-lang/src/main/java/bjc/dicelang/ast/IResult.java deleted file mode 100644 index 9a3f325..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/IResult.java +++ /dev/null @@ -1,16 +0,0 @@ -package bjc.dicelang.ast; - -/** - * Represents a result from an expression evaluation - * - * @author ben - * - */ -public interface IResult { - /** - * Get the type of this result - * - * @return The type of this result - */ - public ResultType getType(); -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/IntegerResult.java b/dice-lang/src/main/java/bjc/dicelang/ast/IntegerResult.java deleted file mode 100644 index ce61d38..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/IntegerResult.java +++ /dev/null @@ -1,40 +0,0 @@ -package bjc.dicelang.ast; - -/** - * Represents a integer-valued result - * - * @author ben - * - */ -public class IntegerResult implements IResult { - private int value; - - /** - * Create a new integer valued result - * - * @param val - * The value of the result - */ - public IntegerResult(int val) { - value = val; - } - - @Override - public ResultType getType() { - return ResultType.INTEGER; - } - - /** - * Get the value of this result - * - * @return The value of this result - */ - public int getValue() { - return value; - } - - @Override - public String toString() { - return Integer.toString(value); - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/ResultType.java b/dice-lang/src/main/java/bjc/dicelang/ast/ResultType.java deleted file mode 100644 index 9e3b129..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/ResultType.java +++ /dev/null @@ -1,22 +0,0 @@ -package bjc.dicelang.ast; - -/** - * Represents the result of a computation - * - * @author ben - * - */ -public enum ResultType { - /** - * Represents a result that is equivalent to a single integer - */ - INTEGER, - /** - * Represents a result that is an array - */ - ARRAY, - /** - * Represents something not to poke at - */ - DUMMY -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceASTType.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceASTType.java deleted file mode 100644 index 9feb461..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceASTType.java +++ /dev/null @@ -1,27 +0,0 @@ -package bjc.dicelang.ast.nodes; - -/** - * An enum to represent the type of node an AST node is - * - * @author ben - * - */ -public enum DiceASTType { - /** - * A node that contains a literal value - */ - LITERAL, - /** - * A node that contains an operator expression - */ - OPERATOR, - /** - * A node that contains a variable reference - */ - VARIABLE; - - @Override - public String toString() { - return this.name().toLowerCase(); - } -}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralNode.java deleted file mode 100644 index b398ac6..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralNode.java +++ /dev/null @@ -1,52 +0,0 @@ -package bjc.dicelang.ast.nodes; - -import bjc.dicelang.IDiceExpression; - -/** - * Represents a literal backed by a dice expression - * - * @author ben - * - */ -public class DiceLiteralNode implements ILiteralDiceNode { - private IDiceExpression expression; - - /** - * Create a new literal from an expression - * - * @param exp - * The expression to attempt to create a literal from - */ - public DiceLiteralNode(IDiceExpression exp) { - expression = exp; - } - - @Override - public boolean canOptimize() { - return expression.canOptimize(); - } - - @Override - public DiceLiteralType getLiteralType() { - return DiceLiteralType.DICE; - } - - /** - * Return the expression being represented - * - * @return The expression being represented - */ - public IDiceExpression getValue() { - return expression; - } - - @Override - public int optimize() { - return expression.optimize(); - } - - @Override - public String toString() { - return expression.toString(); - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralType.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralType.java deleted file mode 100644 index 41c6b05..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralType.java +++ /dev/null @@ -1,18 +0,0 @@ -package bjc.dicelang.ast.nodes; - -/** - * Represents the type of literals that can be in an AST - * - * @author ben - * - */ -public enum DiceLiteralType { - /** - * Represents a integral constant - */ - INTEGER, - /** - * Represents a dice literal - */ - DICE; -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceOperatorType.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceOperatorType.java deleted file mode 100644 index 7cc1e42..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceOperatorType.java +++ /dev/null @@ -1,29 +0,0 @@ -package bjc.dicelang.ast.nodes; - -/** - * Represents the different type of operators. - * - * Mostly, what distinguishes groups is that all the operators in a group - * have similiar precedence, and operate on similiar things - * - * @author ben - * - */ -public enum DiceOperatorType { - /** - * Represents operators that do math operations - */ - MATH, - /** - * Represents operators that do things with arrays - */ - ARRAY, - /** - * Represents operators that do things with dice - */ - DICE, - /** - * Represents operators that do things with expressions - */ - EXPRESSION; -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IDiceASTNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IDiceASTNode.java deleted file mode 100644 index b7bf9a6..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IDiceASTNode.java +++ /dev/null @@ -1,23 +0,0 @@ -package bjc.dicelang.ast.nodes; - -/** - * The interface for a node in a dice AST - * - * @author ben - * - */ -public interface IDiceASTNode { - /** - * Get the type of AST node this node is - * - * @return The type of AST node this AST node is - */ - public DiceASTType getType(); - - /** - * Check if this node represents an operator or not - * - * @return Whether or not this node represents an operator - */ - public boolean isOperator(); -}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/ILiteralDiceNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/ILiteralDiceNode.java deleted file mode 100644 index b94bcc8..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/ILiteralDiceNode.java +++ /dev/null @@ -1,73 +0,0 @@ -package bjc.dicelang.ast.nodes; - -/** - * Represents a literal of some type in the AST - * - * @author ben - * - */ -public interface ILiteralDiceNode extends IDiceASTNode { - /** - * Check if a token represents a literal, and if so, what type - * - * @param tok - * The token to check - * @return The type the literal would be if it is one, or null - * otherwise - */ - static DiceLiteralType getLiteralType(String tok) { - String diceGroupOrNumber = "[(?:\\d*d\\d+)(?:\\d+)]"; - - if (tok.matches("\\A" + diceGroupOrNumber + "?" + "c" - + diceGroupOrNumber + "\\Z")) { - return DiceLiteralType.DICE; - } - - String diceGroup = "\\d*d\\d+\\"; - - if (tok.matches("\\A" + diceGroup + "Z")) { - return DiceLiteralType.DICE; - } - - try { - Integer.parseInt(tok); - return DiceLiteralType.INTEGER; - } catch (@SuppressWarnings("unused") NumberFormatException nfex) { - // We don't care about details - return null; - } - } - - /** - * Check if this node can be optimized to a constant - * - * @return Whether or not this node can be optimized to a constant - * @see bjc.dicelang.IDiceExpression#canOptimize() - */ - boolean canOptimize(); - - /** - * Get the type of literal this node represents - * - * @return The type of literal this node represents - */ - DiceLiteralType getLiteralType(); - - @Override - default DiceASTType getType() { - return DiceASTType.LITERAL; - } - - @Override - default boolean isOperator() { - return false; - } - - /** - * Optimize this node to a constant if possible - * - * @return This node in constant form if possible - * @see bjc.dicelang.IDiceExpression#optimize() - */ - int optimize(); -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IntegerLiteralNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IntegerLiteralNode.java deleted file mode 100644 index 3d43bb1..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IntegerLiteralNode.java +++ /dev/null @@ -1,50 +0,0 @@ -package bjc.dicelang.ast.nodes; - -/** - * Represents an integer literal of some kind - * - * @author ben - * - */ -public class IntegerLiteralNode implements ILiteralDiceNode { - private int value; - - /** - * Create a new integer literal from the given number - * - * @param val - * The value this node represents - */ - public IntegerLiteralNode(int val) { - value = val; - } - - @Override - public boolean canOptimize() { - return true; - } - - @Override - public DiceLiteralType getLiteralType() { - return DiceLiteralType.INTEGER; - } - - /** - * Get the value this node represents - * - * @return The integer value of this node - */ - public int getValue() { - return value; - } - - @Override - public int optimize() { - return value; - } - - @Override - public String toString() { - return Integer.toString(value); - } -} 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 deleted file mode 100644 index 7c0a29d..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java +++ /dev/null @@ -1,110 +0,0 @@ -package bjc.dicelang.ast.nodes; - -import static bjc.dicelang.ast.nodes.DiceOperatorType.DICE; -import static bjc.dicelang.ast.nodes.DiceOperatorType.EXPRESSION; -import static bjc.dicelang.ast.nodes.DiceOperatorType.MATH; - -/** - * A node that represents an operator - * - * @author ben - * - */ -public enum OperatorDiceNode implements IDiceASTNode { - /** - * Represents adding two nodes - */ - ADD(MATH), - /** - * Represents dividing two nodes - */ - DIVIDE(MATH), - /** - * Represents multiplying two nodes - */ - MULTIPLY(MATH), - /** - * Represents subtracting two nodes - */ - SUBTRACT(MATH), - /** - * Representings combining two node values together - */ - COMPOUND(DICE), - /** - * Represents using one node a variable number of times - */ - GROUP(DICE), - /** - * Represents constructing an array from a sequence of expressions - */ - ARRAY(DiceOperatorType.ARRAY), - /** - * Represents assigning one node to another - */ - ASSIGN(EXPRESSION), - /** - * Represents evaluating one expression in the context of another - */ - LET(EXPRESSION); - - /** - * Create a operator node from a string - * - * @param s - * The string to convert to a node - * @return The operator corresponding to the node - */ - public static OperatorDiceNode fromString(String s) { - switch (s) { - case ":=": - return ASSIGN; - case "+": - return ADD; - case "-": - return SUBTRACT; - case "*": - return MULTIPLY; - case "/": - return DIVIDE; - case "d": - case "group": - return GROUP; - case "c": - case "compound": - return COMPOUND; - case "=>": - return LET; - case "[]": - return ARRAY; - default: - throw new IllegalArgumentException( - s + " is not a valid operator node"); - } - } - - /** - * Represents the group of operator this operator is sorted into. - * - */ - public final DiceOperatorType type; - - private OperatorDiceNode(DiceOperatorType ty) { - type = ty; - } - - @Override - public DiceASTType getType() { - return DiceASTType.OPERATOR; - } - - /* - * (non-Javadoc) - * - * @see bjc.utils.dice.ast.IDiceASTNode#isOperator() - */ - @Override - public boolean isOperator() { - return true; - } -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/VariableDiceNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/VariableDiceNode.java deleted file mode 100644 index da66608..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/VariableDiceNode.java +++ /dev/null @@ -1,101 +0,0 @@ -package bjc.dicelang.ast.nodes; - -/** - * A node that represents a reference to a variable - * - * @author ben - * - */ -public class VariableDiceNode implements IDiceASTNode { - /** - * The variable referenced by this node - */ - private String variableName; - - /** - * Create a new node representing the specified variable - * - * @param varName - * The name of the variable being referenced - */ - public VariableDiceNode(String varName) { - this.variableName = varName; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - // Handle special cases - if (this == obj) { - return true; - } else if (obj == null) { - return false; - } else if (getClass() != obj.getClass()) { - return false; - } else { - VariableDiceNode other = (VariableDiceNode) obj; - - if (variableName == null) { - if (other.variableName != null) { - return false; - } - } else if (!variableName.equals(other.variableName)) { - return false; - } - - return true; - } - } - - @Override - public DiceASTType getType() { - return DiceASTType.VARIABLE; - } - - /** - * Get the variable referenced by this AST node - * - * @return the variable referenced by this AST node - */ - public String getVariable() { - return variableName; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((variableName == null) ? 0 : variableName.hashCode()); - return result; - } - - /* - * (non-Javadoc) - * - * @see bjc.utils.dice.ast.IDiceASTNode#isOperator() - */ - @Override - public boolean isOperator() { - return false; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return variableName; - } -}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/package-info.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/package-info.java deleted file mode 100644 index f0f7366..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Classes for nodes in the dice-lang AST - * - * @author ben - * - */ -package bjc.dicelang.ast.nodes;
\ No newline at end of file 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 deleted file mode 100644 index 960fbf7..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ArithmeticCollapser.java +++ /dev/null @@ -1,50 +0,0 @@ -package bjc.dicelang.ast.optimization; - -import java.util.function.BinaryOperator; - -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.Tree; - -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; - -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( - IList<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.literalToInteger(children.first()); - - return children.tail().reduceAux(initState, - (currentNode, state) -> { - return reducer.apply(state, - DiceASTUtils.literalToInteger(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 deleted file mode 100644 index 95badd2..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/ConstantCollapser.java +++ /dev/null @@ -1,91 +0,0 @@ -package bjc.dicelang.ast.optimization; - -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.Tree; - -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; - -/** - * 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.COMPOUND); - - @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, - IList<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.literalToExpression( - children.getByIndex(0)), - DiceASTUtils.literalToExpression( - children.getByIndex(1))); - - if (dice.canOptimize()) { - return new Tree<>( - new IntegerLiteralNode(dice.optimize())); - } - - return new Tree<>(operator, children); - case ARRAY: - if (children.getSize() != 1) { - return new Tree<>(operator, children); - } - - return children.first(); - case ASSIGN: - case LET: - 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 deleted file mode 100644 index 36b03f1..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/IOptimizationPass.java +++ /dev/null @@ -1,35 +0,0 @@ -package bjc.dicelang.ast.optimization; - -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.ITree; - -import bjc.dicelang.ast.nodes.IDiceASTNode; - -/** - * 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, - IList<ITree<IDiceASTNode>> children); -} diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/OperationCondenser.java b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/OperationCondenser.java deleted file mode 100644 index f646a17..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/OperationCondenser.java +++ /dev/null @@ -1,107 +0,0 @@ -package bjc.dicelang.ast.optimization; - -import bjc.utils.data.IHolder; -import bjc.utils.data.Identity; -import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.TopDownTransformResult; -import bjc.utils.funcdata.Tree; - -import bjc.dicelang.ast.nodes.DiceASTType; -import bjc.dicelang.ast.nodes.IDiceASTNode; -import bjc.dicelang.ast.nodes.OperatorDiceNode; - -/** - * Condenses chained operations into a single level - * - * @author ben - * - */ -public class OperationCondenser { - /** - * Condense chained similiar operations into a single level - * - * @param ast - * The AST to condense - * @return The condensed AST - */ - public static ITree<IDiceASTNode> condense(ITree<IDiceASTNode> ast) { - return ast.topDownTransform(OperationCondenser::pickNode, - OperationCondenser::doCondense); - } - - private static ITree<IDiceASTNode> doCondense( - ITree<IDiceASTNode> ast) { - OperatorDiceNode operation = ast - .transformHead((node) -> (OperatorDiceNode) node); - - IHolder<Boolean> canCondense = new Identity<>(true); - - ast.doForChildren((child) -> { - if (canCondense.getValue()) { - canCondense.replace(child.transformHead((node) -> { - if (node.getType() == DiceASTType.OPERATOR) { - if (operation.equals(node)) { - return true; - } - - return false; - } - - return true; - })); - } - }); - - if (!canCondense.getValue()) { - return ast; - } - - ITree<IDiceASTNode> condensedAST = new Tree<>(operation); - - ast.doForChildren((child) -> { - if (child.getHead().getType() == DiceASTType.OPERATOR) { - child.doForChildren((subChild) -> { - condensedAST.addChild(subChild); - }); - } else { - condensedAST.addChild(child); - } - }); - - return condensedAST; - } - - private static TopDownTransformResult pickNode(IDiceASTNode node) { - switch (node.getType()) { - case LITERAL: - return TopDownTransformResult.SKIP; - case OPERATOR: - return pickOperator((OperatorDiceNode) node); - case VARIABLE: - return TopDownTransformResult.SKIP; - default: - throw new UnsupportedOperationException( - "Attempted to traverse unknown node type " + node); - } - } - - private static TopDownTransformResult pickOperator( - OperatorDiceNode node) { - switch (node) { - case ADD: - case MULTIPLY: - case SUBTRACT: - case DIVIDE: - case COMPOUND: - return TopDownTransformResult.PUSHDOWN; - case ARRAY: - case ASSIGN: - case GROUP: - case LET: - return TopDownTransformResult.PASSTHROUGH; - default: - throw new UnsupportedOperationException( - "Attempted to traverse unknown operator " + node); - } - } -} 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 deleted file mode 100644 index 6f75bf9..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Contains optimizations on dice ASTs - * - * @author ben - * - */ -package bjc.dicelang.ast.optimization;
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/package-info.java b/dice-lang/src/main/java/bjc/dicelang/ast/package-info.java deleted file mode 100644 index f6352aa..0000000 --- a/dice-lang/src/main/java/bjc/dicelang/ast/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * New implementation of AST for dice-lang - * - * @author ben - * - */ -package bjc.dicelang.ast;
\ No newline at end of file |
