diff options
Diffstat (limited to 'dice-lang/src/main/java')
13 files changed, 299 insertions, 161 deletions
diff --git a/dice-lang/src/main/java/bjc/dicelang/BindingDiceExpression.java b/dice-lang/src/main/java/bjc/dicelang/BindingDiceExpression.java index 94dd761..1813e97 100644 --- a/dice-lang/src/main/java/bjc/dicelang/BindingDiceExpression.java +++ b/dice-lang/src/main/java/bjc/dicelang/BindingDiceExpression.java @@ -13,12 +13,12 @@ public class BindingDiceExpression implements IDiceExpression { /** * The expression being bound to a name */ - private IDiceExpression exp; + private IDiceExpression expression; /** * The name to bind the expression to */ - private String name; + private String variableName; /** * Create a new dice expression binder from two expressions and an @@ -34,7 +34,15 @@ public class BindingDiceExpression implements IDiceExpression { */ public BindingDiceExpression(IDiceExpression left, IDiceExpression right, Map<String, IDiceExpression> env) { - this(((ReferenceDiceExpression) left).getName(), right, env); + if (!(left instanceof ReferenceDiceExpression)) { + throw new UnsupportedOperationException( + "Binding to non-references is unsupported." + + " Problematic expression is " + left); + } else { + String varName = ((ReferenceDiceExpression) left).getName(); + + initialize(varName, right, env); + } } /** @@ -49,8 +57,13 @@ public class BindingDiceExpression implements IDiceExpression { */ public BindingDiceExpression(String name, IDiceExpression exp, Map<String, IDiceExpression> env) { - this.name = name; - this.exp = exp; + initialize(name, exp, env); + } + + private void initialize(String name, IDiceExpression exp, + Map<String, IDiceExpression> env) { + this.variableName = name; + this.expression = exp; env.put(name, exp); } @@ -62,7 +75,7 @@ public class BindingDiceExpression implements IDiceExpression { */ @Override public int roll() { - return exp.roll(); + return expression.roll(); } /* @@ -72,6 +85,7 @@ public class BindingDiceExpression implements IDiceExpression { */ @Override public String toString() { - return "assign[n=" + name + ", exp=" + exp.toString() + "]"; + return "assign[n=" + variableName + ", exp=" + + expression.toString() + "]"; } } diff --git a/dice-lang/src/main/java/bjc/dicelang/ComplexDice.java b/dice-lang/src/main/java/bjc/dicelang/ComplexDice.java index 5d88001..054c73b 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ComplexDice.java +++ b/dice-lang/src/main/java/bjc/dicelang/ComplexDice.java @@ -89,6 +89,12 @@ public class ComplexDice implements IDiceExpression { */ int nRoll = nDice.roll(); + if (nRoll < 0) { + throw new UnsupportedOperationException( + "Attempted to roll a negative number of dice. " + + "The problematic expression is " + nDice); + } + for (int i = 0; i < nRoll; i++) { res += die.roll(); } @@ -110,4 +116,4 @@ public class ComplexDice implements IDiceExpression { + die.toString() + "]"; } } -} +}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/DiceExpressionBuilder.java b/dice-lang/src/main/java/bjc/dicelang/DiceExpressionBuilder.java index 5ced36d..b3cc37a 100644 --- a/dice-lang/src/main/java/bjc/dicelang/DiceExpressionBuilder.java +++ b/dice-lang/src/main/java/bjc/dicelang/DiceExpressionBuilder.java @@ -54,7 +54,7 @@ public class DiceExpressionBuilder { * @return A new expression adding the two dice */ public DiceExpressionBuilder add(IDiceExpression exp) { - baking = new CompoundDiceExpression(baking, exp, ADD); + baking = new OperatorDiceExpression(baking, exp, ADD); return this; } @@ -87,7 +87,7 @@ public class DiceExpressionBuilder { * @return A new expression dividing the two dice */ public DiceExpressionBuilder divide(IDiceExpression exp) { - baking = new CompoundDiceExpression(baking, exp, DIVIDE); + baking = new OperatorDiceExpression(baking, exp, DIVIDE); return this; } @@ -111,7 +111,7 @@ public class DiceExpressionBuilder { * @return A new expression multiplying the two dice */ public DiceExpressionBuilder multiply(IDiceExpression exp) { - baking = new CompoundDiceExpression(baking, exp, MULTIPLY); + baking = new OperatorDiceExpression(baking, exp, MULTIPLY); return this; } @@ -135,7 +135,7 @@ public class DiceExpressionBuilder { * @return A new expression adding the two dice */ public DiceExpressionBuilder subtract(IDiceExpression exp) { - baking = new CompoundDiceExpression(baking, exp, SUBTRACT); + baking = new OperatorDiceExpression(baking, exp, SUBTRACT); return this; } diff --git a/dice-lang/src/main/java/bjc/dicelang/DiceExpressionParser.java b/dice-lang/src/main/java/bjc/dicelang/DiceExpressionParser.java index 9f96835..05e8942 100644 --- a/dice-lang/src/main/java/bjc/dicelang/DiceExpressionParser.java +++ b/dice-lang/src/main/java/bjc/dicelang/DiceExpressionParser.java @@ -96,19 +96,19 @@ public class DiceExpressionParser { env)); break; case "+": - dexps.push(new CompoundDiceExpression(r, l, + dexps.push(new OperatorDiceExpression(r, l, DiceExpressionType.ADD)); break; case "-": - dexps.push(new CompoundDiceExpression(r, l, + dexps.push(new OperatorDiceExpression(r, l, DiceExpressionType.SUBTRACT)); break; case "*": - dexps.push(new CompoundDiceExpression(r, l, + dexps.push(new OperatorDiceExpression(r, l, DiceExpressionType.MULTIPLY)); break; case "/": - dexps.push(new CompoundDiceExpression(r, l, + dexps.push(new OperatorDiceExpression(r, l, DiceExpressionType.DIVIDE)); break; case "c": diff --git a/dice-lang/src/main/java/bjc/dicelang/Die.java b/dice-lang/src/main/java/bjc/dicelang/Die.java index addc2af..c6c6ddd 100644 --- a/dice-lang/src/main/java/bjc/dicelang/Die.java +++ b/dice-lang/src/main/java/bjc/dicelang/Die.java @@ -26,6 +26,11 @@ public class Die implements IDiceExpression { * The number of sides this dice has */ public Die(int nSides) { + if (nSides < 1) { + throw new UnsupportedOperationException( + "Dice with less than 1 side are not supported"); + } + this.nSides = nSides; } diff --git a/dice-lang/src/main/java/bjc/dicelang/CompoundDiceExpression.java b/dice-lang/src/main/java/bjc/dicelang/OperatorDiceExpression.java index 8db481f..4ca2568 100644 --- a/dice-lang/src/main/java/bjc/dicelang/CompoundDiceExpression.java +++ b/dice-lang/src/main/java/bjc/dicelang/OperatorDiceExpression.java @@ -6,7 +6,7 @@ package bjc.dicelang; * @author ben * */ -public class CompoundDiceExpression implements IDiceExpression { +public class OperatorDiceExpression implements IDiceExpression { /** * The operator to use for combining the dice */ @@ -32,7 +32,7 @@ public class CompoundDiceExpression implements IDiceExpression { * @param det * The operator to use for combining the dices */ - public CompoundDiceExpression(IDiceExpression right, + public OperatorDiceExpression(IDiceExpression right, IDiceExpression left, DiceExpressionType det) { this.right = right; this.left = left; @@ -61,7 +61,14 @@ public class CompoundDiceExpression implements IDiceExpression { * Round to keep results as integers. We don't really have * any need for floating-point dice */ - return right.roll() / left.roll(); + try { + return right.roll() / left.roll(); + } catch (ArithmeticException aex) { + throw new UnsupportedOperationException( + "Attempted to divide by zero." + + " Problematic expression is " + + left); + } default: throw new IllegalArgumentException( "Got passed a invalid ScalarExpressionType " + det diff --git a/dice-lang/src/main/java/bjc/dicelang/ReferenceDiceExpression.java b/dice-lang/src/main/java/bjc/dicelang/ReferenceDiceExpression.java index c1a4a79..27ec609 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ReferenceDiceExpression.java +++ b/dice-lang/src/main/java/bjc/dicelang/ReferenceDiceExpression.java @@ -51,6 +51,11 @@ public class ReferenceDiceExpression implements IDiceExpression { */ @Override public int roll() { + if (!env.containsKey(name)) { + throw new UnsupportedOperationException( + "Attempted to reference undefined variable " + name); + } + return env.get(name).roll(); } diff --git a/dice-lang/src/main/java/bjc/dicelang/ScalarDiceExpression.java b/dice-lang/src/main/java/bjc/dicelang/ScalarDiceExpression.java index be0cbb6..03b2f83 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ScalarDiceExpression.java +++ b/dice-lang/src/main/java/bjc/dicelang/ScalarDiceExpression.java @@ -54,7 +54,12 @@ public class ScalarDiceExpression implements IDiceExpression { case MULTIPLY: return exp.roll() * scalar; case DIVIDE: - return exp.roll() / scalar; + try { + return exp.roll() / scalar; + } catch (ArithmeticException aex) { + throw new UnsupportedOperationException( + "Attempted to divide by zero."); + } default: throw new IllegalStateException( "Got passed a invalid ScalarExpressionType " diff --git a/dice-lang/src/main/java/bjc/dicelang/ScalarDie.java b/dice-lang/src/main/java/bjc/dicelang/ScalarDie.java index 8078e8b..fbdfb7e 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ScalarDie.java +++ b/dice-lang/src/main/java/bjc/dicelang/ScalarDie.java @@ -41,5 +41,4 @@ public class ScalarDie implements IDiceExpression { public String toString() { return Integer.toString(num); } - -} +}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java index 078c952..eaadc53 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTExpression.java @@ -2,6 +2,8 @@ package bjc.dicelang.ast; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; + import org.apache.commons.lang3.StringUtils; import bjc.dicelang.ComplexDice; @@ -20,6 +22,21 @@ import bjc.utils.parserutils.AST; */ 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 * @@ -44,69 +61,104 @@ public class DiceASTExpression implements IDiceExpression { }); operatorCollapsers.put(OperatorDiceNode.SUBTRACT, - (left, right) -> { - return left.merge( - (lval, last) -> right.merge((rval, rast) -> { - return new Pair<>(lval - rval, - new AST<>( - OperatorDiceNode.SUBTRACT, - last, rast)); - })); - + (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, - (left, right) -> { - return left.merge( - (lval, last) -> right.merge((rval, rast) -> { - return new Pair<>(lval * rval, - new AST<>( - OperatorDiceNode.MULTIPLY, - last, rast)); - })); + (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, (left, right) -> { - return left.merge((lval, last) -> right.merge((rval, rast) -> { - return new Pair<>(lval / rval, - new AST<>(OperatorDiceNode.DIVIDE, last, rast)); - })); - }); + 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 left.merge((lval, last) -> right.merge((rval, rast) -> { - String nam = last.collapse((nod) -> { - return ((VariableDiceNode) nod).getVariable(); - }, (v) -> (lv, rv) -> null, (r) -> r); + 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); - enviroment.put(nam, - new DiceASTExpression(rast, enviroment)); + enviroment.put(variableName, + new DiceASTExpression(rightAST, enviroment)); - return new Pair<>(rval, - new AST<>(OperatorDiceNode.ASSIGN, last, rast)); - })); + return new Pair<>(rightValue, new AST<>( + OperatorDiceNode.ASSIGN, leftAST, rightAST)); + }); + }); }); operatorCollapsers.put(OperatorDiceNode.COMPOUND, - (left, right) -> { - return left.merge( - (lval, last) -> right.merge((rval, rast) -> { - int ival = Integer - .parseInt(Integer.toString(lval) - + Integer.toString(rval)); - - return new Pair<>(ival, - new AST<>( - OperatorDiceNode.COMPOUND, - last, rast)); - })); + (leftNode, 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)); + }); + }); }); - operatorCollapsers.put(OperatorDiceNode.GROUP, (left, right) -> { - return left.merge((lval, last) -> right.merge((rval, rast) -> { - return new Pair<>(new ComplexDice(lval, rval).roll(), - new AST<>(OperatorDiceNode.GROUP, last, rast)); - })); - }); + operatorCollapsers.put(OperatorDiceNode.GROUP, + (leftNode, 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)); + }); + }); + }); return operatorCollapsers; } @@ -144,7 +196,7 @@ public class DiceASTExpression implements IDiceExpression { * represents */ private Pair<Integer, AST<IDiceASTNode>> evalLeaf(IDiceASTNode tokn) { - if (tokn instanceof VariableDiceNode) { + if (tokn.getType() == DiceASTType.VARIABLE) { String varName = ((VariableDiceNode) tokn).getVariable(); if (env.containsKey(varName)) { @@ -154,25 +206,37 @@ public class DiceASTExpression implements IDiceExpression { // Handle special case for defining variables return new Pair<>(0, new AST<>(tokn)); } - } else { - LiteralDiceNode lnod = (LiteralDiceNode) tokn; - String dat = lnod.getData(); + } else if (tokn.getType() == DiceASTType.LITERAL) { + LiteralDiceNode literalNode = (LiteralDiceNode) tokn; + String dat = literalNode.getData(); if (StringUtils.countMatches(dat, 'c') == 1 - && !dat.equalsIgnoreCase("c")) { + && !dat.equalsIgnoreCase("c") + && !dat.startsWith("c")) { String[] strangs = dat.split("c"); + return new Pair<>(new CompoundDice(strangs).roll(), new AST<>(tokn)); } else if (StringUtils.countMatches(dat, 'd') == 1 - && !dat.equalsIgnoreCase("d")) { + && !dat.equalsIgnoreCase("d") + && !dat.startsWith("d")) { /* * Handle dice groups */ return new Pair<>(ComplexDice.fromString(dat).roll(), new AST<>(tokn)); } else { - return new Pair<>(Integer.parseInt(dat), new AST<>(tokn)); + try { + return new Pair<>(Integer.parseInt(dat), + new AST<>(tokn)); + } catch (NumberFormatException nfex) { + throw new UnsupportedOperationException( + "Found malformed leaf token " + tokn); + } } + } else { + throw new UnsupportedOperationException("Found leaf operator " + + tokn + ". These aren't supported."); } } @@ -196,7 +260,8 @@ public class DiceASTExpression implements IDiceExpression { buildOperations(env); return ast.collapse(this::evalLeaf, operations::get, - (r) -> r.merge((left, right) -> left)); + (returnedValue) -> returnedValue + .merge((left, right) -> left)); } /* @@ -208,4 +273,4 @@ public class DiceASTExpression implements IDiceExpression { public String toString() { return ast.toString(); } -} +}
\ No newline at end of file diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTFlattener.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTFlattener.java index aa15c4d..fad4870 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTFlattener.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTFlattener.java @@ -3,17 +3,19 @@ package bjc.dicelang.ast; import java.util.HashMap; import java.util.Map; import java.util.function.BinaryOperator; +import java.util.function.Function; import org.apache.commons.lang3.StringUtils; import bjc.dicelang.BindingDiceExpression; import bjc.dicelang.ComplexDice; import bjc.dicelang.CompoundDice; -import bjc.dicelang.CompoundDiceExpression; +import bjc.dicelang.OperatorDiceExpression; import bjc.dicelang.DiceExpressionType; import bjc.dicelang.IDiceExpression; import bjc.dicelang.ReferenceDiceExpression; import bjc.dicelang.ScalarDie; + import bjc.utils.parserutils.AST; /** @@ -24,6 +26,60 @@ import bjc.utils.parserutils.AST; * */ public class DiceASTFlattener { + private static final class NodeCollapser + implements Function<IDiceASTNode, IDiceExpression> { + private Map<String, IDiceExpression> enviroment; + + public NodeCollapser(Map<String, IDiceExpression> env) { + this.enviroment = env; + } + + @Override + public IDiceExpression apply(IDiceASTNode nod) { + if (nod.getType() == DiceASTType.LITERAL) { + return expFromLiteral((LiteralDiceNode) nod); + } else if (nod.getType() == DiceASTType.VARIABLE) { + String varName = ((VariableDiceNode) nod).getVariable(); + + return new ReferenceDiceExpression(varName, enviroment); + } else { + throw new UnsupportedOperationException( + "Attempted to flatten something that can't be" + + " flattened. The culprit is " + nod); + } + } + + /** + * Create a dice expression from a literal token + * + * @param tok + * The token to convert to an expression + * @return The dice expression represented by the token + */ + private static IDiceExpression + expFromLiteral(LiteralDiceNode tok) { + String data = tok.getData(); + + if (data.equals("")) { + throw new UnsupportedOperationException( + "Can't convert a blank token into a literal"); + } + + if (StringUtils.countMatches(data, 'c') == 1 + && !data.equalsIgnoreCase("c")) { + String[] strangs = data.split("c"); + + return new CompoundDice(ComplexDice.fromString(strangs[0]), + ComplexDice.fromString(strangs[1])); + } else if (StringUtils.countMatches(data, 'd') == 1 + && !data.equalsIgnoreCase("d")) { + return ComplexDice.fromString(data); + } else { + return new ScalarDie(Integer.parseInt(data)); + } + } + } + /** * Build the operations to use for tree flattening * @@ -35,20 +91,21 @@ public class DiceASTFlattener { buildOperations(Map<String, IDiceExpression> env) { Map<IDiceASTNode, BinaryOperator<IDiceExpression>> opCollapsers = new HashMap<>(); + opCollapsers.put(OperatorDiceNode.ADD, (left, right) -> { - return new CompoundDiceExpression(right, left, + return new OperatorDiceExpression(right, left, DiceExpressionType.ADD); }); opCollapsers.put(OperatorDiceNode.SUBTRACT, (left, right) -> { - return new CompoundDiceExpression(right, left, + return new OperatorDiceExpression(right, left, DiceExpressionType.SUBTRACT); }); opCollapsers.put(OperatorDiceNode.MULTIPLY, (left, right) -> { - return new CompoundDiceExpression(right, left, + return new OperatorDiceExpression(right, left, DiceExpressionType.MULTIPLY); }); opCollapsers.put(OperatorDiceNode.DIVIDE, (left, right) -> { - return new CompoundDiceExpression(right, left, + return new OperatorDiceExpression(right, left, DiceExpressionType.DIVIDE); }); opCollapsers.put(OperatorDiceNode.ASSIGN, (left, right) -> { @@ -65,30 +122,6 @@ public class DiceASTFlattener { } /** - * Create a dice expression from a literal token - * - * @param tok - * The token to convert to an expression - * @return The dice expression represented by the token - */ - private static IDiceExpression expFromLiteral(LiteralDiceNode tok) { - String data = tok.getData(); - - if (StringUtils.countMatches(data, 'c') == 1 - && !data.equalsIgnoreCase("c")) { - String[] strangs = data.split("c"); - - return new CompoundDice(ComplexDice.fromString(strangs[0]), - ComplexDice.fromString(strangs[1])); - } else if (StringUtils.countMatches(data, 'd') == 1 - && !data.equalsIgnoreCase("d")) { - return ComplexDice.fromString(data); - } else { - return new ScalarDie(Integer.parseInt(data)); - } - } - - /** * Flatten a AST into a dice expression * * @param ast @@ -102,13 +135,7 @@ public class DiceASTFlattener { Map<IDiceASTNode, BinaryOperator<IDiceExpression>> opCollapsers = buildOperations(env); - return ast.collapse((nod) -> { - if (nod instanceof LiteralDiceNode) { - return expFromLiteral((LiteralDiceNode) nod); - } else { - return new ReferenceDiceExpression( - ((VariableDiceNode) nod).getVariable(), env); - } - } , opCollapsers::get, (r) -> r); + return ast.collapse(new NodeCollapser(env), opCollapsers::get, + (r) -> r); } } diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java index d0b970a..67d2d50 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java @@ -2,6 +2,7 @@ package bjc.dicelang.ast; import java.util.Deque; import java.util.LinkedList; +import java.util.function.Function; import org.apache.commons.lang3.StringUtils; @@ -20,6 +21,44 @@ import bjc.utils.parserutils.TreeConstructor; * */ public class DiceASTParser { + private static final class NodeBaker + implements Function<String, IDiceASTNode> { + @Override + public IDiceASTNode apply(String tok) { + if (isOperator(tok)) { + return OperatorDiceNode.fromString(tok); + } else if (NodeBaker.isLiteral(tok)) { + return new LiteralDiceNode(tok); + } else { + return new VariableDiceNode(tok); + } + } + + /** + * Check if a token represents a literal + * + * @param tok + * The token to check + * @return Whether or not the token represents a literal + */ + private static boolean isLiteral(String tok) { + if (StringUtils.countMatches(tok, 'c') == 1 + && !tok.equalsIgnoreCase("c")) { + return true; + } else if (StringUtils.countMatches(tok, 'd') == 1 + && !tok.equalsIgnoreCase("d")) { + return true; + } else { + try { + Integer.parseInt(tok); + return true; + } catch (NumberFormatException nfx) { + return false; + } + } + } + } + /** * The yard to use for shunting expressions */ @@ -45,7 +84,7 @@ public class DiceASTParser { */ public AST<IDiceASTNode> buildAST(String exp) { FunctionalList<String> tokens = - FunctionalStringTokenizer.fromString(exp).toList((s) -> s); + FunctionalStringTokenizer.fromString(exp).toList(); Deque<Pair<String, String>> ops = new LinkedList<>(); @@ -70,53 +109,21 @@ public class DiceASTParser { yard.postfix(fullyExpandedTokens, (s) -> s); AST<String> rawAST = TreeConstructor.constructTree(shunted, - this::isOperator, (op) -> false, null); + DiceASTParser::isOperator); - AST<IDiceASTNode> bakedAST = rawAST.transmuteAST((tok) -> { - if (isOperator(tok)) { - return OperatorDiceNode.fromString(tok); - } else if (isLiteral(tok)) { - return new LiteralDiceNode(tok); - } else { - return new VariableDiceNode(tok); - } - }); + AST<IDiceASTNode> bakedAST = rawAST.transmuteAST(new NodeBaker()); return bakedAST; } /** - * Check if a token represents a literal - * - * @param tok - * The token to check - * @return Whether or not the token represents a literal - */ - private static boolean isLiteral(String tok) { - if (StringUtils.countMatches(tok, 'c') == 1 - && !tok.equalsIgnoreCase("c")) { - return true; - } else if (StringUtils.countMatches(tok, 'd') == 1 - && !tok.equalsIgnoreCase("d")) { - return true; - } else { - try { - Integer.parseInt(tok); - return true; - } catch (NumberFormatException nfx) { - return false; - } - } - } - - /** * Check if a token represents an operator * * @param tok * The token to check if it represents an operator * @return Whether or not the token represents an operator */ - private boolean isOperator(String tok) { + private static boolean isOperator(String tok) { switch (tok) { case ":=": case "+": diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceChecker.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceChecker.java index aaabe8b..a74d61e 100644 --- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceChecker.java +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTReferenceChecker.java @@ -23,8 +23,7 @@ public final class DiceASTReferenceChecker * Create a new reference checker * * @param referencesVar - * The holder of whether the variable is referenced or - * not + * The holder of whether the variable is referenced or not * @param varName * The variable to check for references in */ @@ -37,21 +36,20 @@ public final class DiceASTReferenceChecker @Override public void accept(IDiceASTNode astNode) { if (!referencesVariable.unwrap(bool -> bool)) { - if (isDirectReferenceToLast(astNode)) { + if (isDirectReference(astNode)) { referencesVariable.transform((bool) -> false); } } } /** - * Check if a given AST node directly references the meta-variable - * last + * Check if a given AST node directly references the specified variable * * @param astNode * The node to check - * @return Whether or not the node directly references last + * @return Whether or not the node directly the variable */ - private boolean isDirectReferenceToLast(IDiceASTNode astNode) { + private boolean isDirectReference(IDiceASTNode astNode) { if (astNode.getType() == DiceASTType.VARIABLE) { VariableDiceNode node = (VariableDiceNode) astNode; |
