summaryrefslogtreecommitdiff
path: root/dice-lang/src
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-10 22:05:24 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-10 22:05:24 -0400
commit75fe5c351630ce26a9bd4db631809bb8d5b26357 (patch)
tree90137a8470012b6e6a58118663c904c429311699 /dice-lang/src
parent6f42b318ee33152fb9f92e576706e7a368829d2e (diff)
Restored basic functionality with new system
Diffstat (limited to 'dice-lang/src')
-rw-r--r--dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java90
-rw-r--r--dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java61
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java147
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralNode.java5
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/IntegerLiteralNode.java5
5 files changed, 236 insertions, 72 deletions
diff --git a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java
new file mode 100644
index 0000000..94186dd
--- /dev/null
+++ b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java
@@ -0,0 +1,90 @@
+package bjc.dicelang.examples;
+
+import java.util.Scanner;
+
+import bjc.dicelang.ast.DiceASTEvaluator;
+import bjc.dicelang.ast.DiceASTParser;
+import bjc.dicelang.ast.nodes.IDiceASTNode;
+
+import bjc.utils.funcdata.FunctionalMap;
+import bjc.utils.funcdata.IFunctionalList;
+import bjc.utils.funcdata.IFunctionalMap;
+import bjc.utils.parserutils.AST;
+
+/**
+ * Test interface for AST-based dice language
+ *
+ * @author ben
+ *
+ */
+public class DiceASTLanguageTest {
+ /**
+ * Main method of class
+ *
+ * @param args
+ * Unused CLI args
+ */
+ public static void main(String[] args) {
+ Scanner inputSource = new Scanner(System.in);
+ int commandNumber = 0;
+
+ System.out.print("dice-lang-" + commandNumber + "> ");
+ String currentLine = inputSource.nextLine();
+
+ // The enviroment for variables
+ IFunctionalMap<String, AST<IDiceASTNode>> enviroment =
+ new FunctionalMap<>();
+
+ while (!currentLine.equalsIgnoreCase("quit")) {
+ // Build an AST from the string expression
+ AST<IDiceASTNode> builtAST;
+
+ IFunctionalList<String> preparedTokens =
+ DiceExpressionPreparer.prepareCommand(currentLine);
+
+ try {
+ builtAST = DiceASTParser.createFromString(preparedTokens);
+ } catch (IllegalStateException isex) {
+ System.out.println("ERROR: " + isex.getLocalizedMessage());
+
+ currentLine = getNextCommand(inputSource, commandNumber);
+
+ continue;
+ }
+
+ int sampleRoll;
+
+ try {
+ sampleRoll =
+ DiceASTEvaluator.evaluateAST(builtAST, enviroment);
+ } catch (UnsupportedOperationException usex) {
+ System.out.println("ERROR: " + usex.getLocalizedMessage());
+
+ currentLine = getNextCommand(inputSource, commandNumber);
+
+ continue;
+ }
+
+ // Print out results
+ System.out.println("\tParsed: " + builtAST.toString());
+ System.out.println("\t\tSample Roll: " + sampleRoll);
+
+ // Increase the number of commands
+ commandNumber++;
+
+ currentLine = getNextCommand(inputSource, commandNumber);
+ }
+
+ System.out.println("Bye.");
+
+ // Cleanup after ourselves
+ inputSource.close();
+ }
+
+ private static String getNextCommand(Scanner inputSource,
+ int commandNumber) {
+ System.out.print("dice-lang-" + commandNumber + "> ");
+
+ return inputSource.nextLine();
+ }
+}
diff --git a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java
new file mode 100644
index 0000000..1d46cc9
--- /dev/null
+++ b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java
@@ -0,0 +1,61 @@
+package bjc.dicelang.examples;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+import bjc.utils.data.IPair;
+import bjc.utils.data.Pair;
+import bjc.utils.funcdata.FunctionalStringTokenizer;
+import bjc.utils.funcdata.IFunctionalList;
+import bjc.utils.funcutils.ListUtils;
+import bjc.utils.parserutils.ShuntingYard;
+
+/**
+ * Prepare a dice expression to be parsed
+ *
+ * @author ben
+ *
+ */
+public class DiceExpressionPreparer {
+ /**
+ * The yard to use for shunting expressions
+ */
+ private static ShuntingYard<String> yard;
+
+ static {
+ yard = new ShuntingYard<>();
+
+ yard.addOp("d", 5); // dice operator: use for creating variable
+ // size dice groups
+ yard.addOp("c", 6); // compound operator: use for creating compound
+ // dice from expressions
+ yard.addOp(":=", 0); // binding operator: Bind a name to a variable
+ // expression
+ }
+
+ static IFunctionalList<String> prepareCommand(String currentLine) {
+ IFunctionalList<String> tokens =
+ FunctionalStringTokenizer.fromString(currentLine).toList();
+
+ Deque<IPair<String, String>> ops = new LinkedList<>();
+
+ ops.add(new Pair<>("+", "\\+"));
+ ops.add(new Pair<>("-", "-"));
+ ops.add(new Pair<>("*", "\\*"));
+ ops.add(new Pair<>("/", "/"));
+ ops.add(new Pair<>(":=", ":="));
+
+ IFunctionalList<String> semiExpandedTokens =
+ ListUtils.splitTokens(tokens, ops);
+
+ ops = new LinkedList<>();
+
+ ops.add(new Pair<>("(", "\\("));
+ ops.add(new Pair<>(")", "\\)"));
+
+ IFunctionalList<String> fullyExpandedTokens =
+ ListUtils.deAffixTokens(semiExpandedTokens, ops);
+
+ return yard.postfix(fullyExpandedTokens, (token) -> token);
+ }
+}
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java
index 93b56de..0257b91 100644
--- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java
@@ -28,6 +28,12 @@ import bjc.utils.parserutils.AST;
*
*/
public class DiceASTEvaluator {
+ /**
+ * Responsible for collapsing arithmetic operators
+ *
+ * @author ben
+ *
+ */
private static final class ArithmeticCollapser
implements IOperatorCollapser {
private OperatorDiceNode type;
@@ -61,27 +67,6 @@ public class DiceASTEvaluator {
}
/**
- * 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 int evaluateAST(AST<IDiceASTNode> expression,
- IFunctionalMap<String, AST<IDiceASTNode>> enviroment) {
- IFunctionalMap<IDiceASTNode, IOperatorCollapser> collapsers =
- buildOperations(enviroment);
-
- return expression.collapse((node) -> {
- return evaluateLeaf(node, enviroment);
- }, collapsers::get, (pair) -> {
- return pair.merge((left, right) -> left);
- });
- }
-
- /**
* Build the map of operations to use when collapsing the AST
*
* @param enviroment
@@ -123,6 +108,73 @@ public class DiceASTEvaluator {
return operatorCollapsers;
}
+ /**
+ * 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 int evaluateAST(AST<IDiceASTNode> expression,
+ IFunctionalMap<String, AST<IDiceASTNode>> enviroment) {
+ IFunctionalMap<IDiceASTNode, IOperatorCollapser> collapsers =
+ buildOperations(enviroment);
+
+ return expression.collapse(
+ (node) -> evaluateLeaf(node, enviroment), collapsers::get,
+ (pair) -> pair.merge((left, right) -> left));
+ }
+
+ private static IPair<Integer, AST<IDiceASTNode>> evaluateLeaf(
+ IDiceASTNode leafNode,
+ IFunctionalMap<String, AST<IDiceASTNode>> enviroment) {
+ int returnedValue = 0;
+
+ switch (leafNode.getType()) {
+ case LITERAL:
+ returnedValue = evaluateLiteral(leafNode, returnedValue);
+
+ break;
+ case VARIABLE:
+ String variableName =
+ ((VariableDiceNode) leafNode).getVariable();
+
+ returnedValue = evaluateAST(enviroment.get(variableName),
+ enviroment);
+ break;
+ case OPERATOR:
+ throw new UnsupportedOperationException(
+ "Operator '" + leafNode + "' cannot be a leaf.");
+ default:
+ break;
+
+ }
+
+ return new Pair<>(returnedValue, new AST<>(leafNode));
+ }
+
+ private static int evaluateLiteral(IDiceASTNode leafNode,
+ int returnedValue) {
+ DiceLiteralType literalType =
+ ((ILiteralDiceNode) leafNode).getLiteralType();
+
+ switch (literalType) {
+ case DICE:
+ returnedValue = ((DiceLiteralNode) leafNode).getValue();
+ break;
+ case INTEGER:
+ returnedValue = ((IntegerLiteralNode) leafNode).getValue();
+ break;
+ default:
+ throw new UnsupportedOperationException("Literal value '"
+ + leafNode + "' is of a type (" + literalType
+ + ") not currently supported.");
+ }
+ return returnedValue;
+ }
+
private static IPair<Integer, AST<IDiceASTNode>> parseBinding(
IFunctionalMap<String, AST<IDiceASTNode>> enviroment,
IPair<Integer, AST<IDiceASTNode>> left,
@@ -148,8 +200,7 @@ public class DiceASTEvaluator {
rightAST.traverse(TreeLinearizationMethod.PREORDER,
refChecker);
- // Ignore meta-variable that'll be auto-frozen to restore
- // definition sanity
+ // Ignore meta-variable
if (selfReference.unwrap((bool) -> bool)
&& !variableName.equals("last")) {
throw new UnsupportedOperationException(
@@ -161,7 +212,7 @@ public class DiceASTEvaluator {
if (!variableName.equals("last")) {
enviroment.put(variableName, rightAST);
} else {
- // Do nothing, last is a auto-handled meta-variable
+ // Do nothing, last is an auto-handled meta-variable
}
return new Pair<>(rightValue, new AST<>(
@@ -210,52 +261,4 @@ public class DiceASTEvaluator {
});
});
}
-
- private static IPair<Integer, AST<IDiceASTNode>> evaluateLeaf(
- IDiceASTNode leafNode,
- IFunctionalMap<String, AST<IDiceASTNode>> enviroment) {
- int returnedValue = 0;
-
- switch (leafNode.getType()) {
- case LITERAL:
- returnedValue = evaluateLiteral(leafNode, returnedValue);
-
- break;
- case VARIABLE:
- String variableName =
- ((VariableDiceNode) leafNode).getVariable();
-
- returnedValue = evaluateAST(enviroment.get(variableName),
- enviroment);
- break;
- case OPERATOR:
- throw new UnsupportedOperationException(
- "Operator '" + leafNode + "' cannot be a leaf.");
- default:
- break;
-
- }
-
- return new Pair<>(returnedValue, new AST<>(leafNode));
- }
-
- private static int evaluateLiteral(IDiceASTNode leafNode,
- int returnedValue) {
- DiceLiteralType literalType =
- ((ILiteralDiceNode) leafNode).getLiteralType();
-
- switch (literalType) {
- case DICE:
- returnedValue = ((DiceLiteralNode) leafNode).getValue();
- break;
- case INTEGER:
- returnedValue = ((IntegerLiteralNode) leafNode).getValue();
- break;
- default:
- throw new UnsupportedOperationException("Literal value '"
- + leafNode + "' is of a type (" + literalType
- + ") not currently supported.");
- }
- return returnedValue;
- }
}
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
index 82c764d..b2e1825 100644
--- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralNode.java
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceLiteralNode.java
@@ -54,4 +54,9 @@ public class DiceLiteralNode implements ILiteralDiceNode {
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/IntegerLiteralNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IntegerLiteralNode.java
index 415f30f..0ed2c2c 100644
--- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IntegerLiteralNode.java
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IntegerLiteralNode.java
@@ -32,4 +32,9 @@ public class IntegerLiteralNode implements ILiteralDiceNode {
public int getValue() {
return value;
}
+
+ @Override
+ public String toString() {
+ return Integer.toString(value);
+ }
}