summaryrefslogtreecommitdiff
path: root/dice-lang/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'dice-lang/src/main/java')
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java22
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java8
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java115
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java20
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java4
5 files changed, 147 insertions, 22 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
index 5ad0a0f..5c00fe2 100644
--- a/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java
@@ -16,8 +16,7 @@ import bjc.utils.funcdata.Tree;
* @author ben
*
*/
-final class ArithmeticCollapser
- implements IOperatorCollapser {
+final class ArithmeticCollapser implements IOperatorCollapser {
private OperatorDiceNode type;
private BinaryOperator<Integer> valueOp;
@@ -35,12 +34,18 @@ final class ArithmeticCollapser
new Pair<>(0, new Tree<>(type));
BinaryOperator<IPair<Integer, ITree<IDiceASTNode>>> reducer =
- (accumulatedState, currentState) -> {
- return reduceStates(accumulatedState,
- currentState);
+ (currentState, accumulatedState) -> {
+ // Force evaluation of accumulated state to prevent
+ // certain bugs from occuring
+ accumulatedState.merge((l, r) -> null);
+
+ return reduceStates(accumulatedState, currentState);
};
- return nodes.reduceAux(initState, reducer, (state) -> state);
+ IPair<Integer, ITree<IDiceASTNode>> reducedState =
+ nodes.reduceAux(initState, reducer, (state) -> state);
+
+ return reducedState;
}
private IPair<Integer, ITree<IDiceASTNode>> reduceStates(
@@ -52,9 +57,8 @@ final class ArithmeticCollapser
.bind((currentValue, currentTree) -> {
accumulatedTree.addChild(currentTree);
- Integer combinedValue =
- valueOp.apply(accumulatedValue,
- currentValue);
+ Integer combinedValue = valueOp.apply(
+ accumulatedValue, currentValue);
return new Pair<>(combinedValue,
accumulatedTree);
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 e934b9f..016fa8a 100644
--- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTEvaluator.java
@@ -112,7 +112,10 @@ public class DiceASTEvaluator {
String variableName = ((VariableDiceNode) leafNode).getVariable();
if (enviroment.containsKey(variableName)) {
- return evaluateAST(enviroment.get(variableName), enviroment);
+ int result =
+ evaluateAST(enviroment.get(variableName), enviroment);
+
+ return result;
}
// Value to allow for assignments
@@ -148,6 +151,9 @@ public class DiceASTEvaluator {
IPair<Integer, ITree<IDiceASTNode>> valueNode =
nodes.getByIndex(1);
+ // Force valueNode to materialize for debugging purposes
+ valueNode.merge((l, r) -> null);
+
return nameNode.bindRight((nameTree) -> {
return valueNode.bind((valueValue, valueTree) -> {
if (containsSimpleVariable(nameTree)) {
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java
new file mode 100644
index 0000000..6091cc3
--- /dev/null
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java
@@ -0,0 +1,115 @@
+package bjc.dicelang.ast;
+
+import bjc.dicelang.ast.nodes.DiceASTType;
+import bjc.dicelang.ast.nodes.IDiceASTNode;
+import bjc.dicelang.ast.nodes.VariableDiceNode;
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
+import bjc.utils.funcdata.IFunctionalMap;
+import bjc.utils.funcdata.ITree;
+import bjc.utils.funcdata.Tree;
+
+/**
+ * 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,
+ IFunctionalMap<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,
+ IFunctionalMap<String, ITree<IDiceASTNode>> enviroment,
+ boolean specificInline,
+ IFunctionalList<String> variableNames) {
+ if (node.getType() != DiceASTType.VARIABLE) {
+ return new Tree<>(node);
+ }
+
+ String variableName = ((VariableDiceNode) node).getVariable();
+
+ if (specificInline) {
+ if (variableNames.contains(variableName)) {
+ if (!enviroment.containsKey(variableName)) {
+ throw new UnsupportedOperationException(
+ "Attempted to inline non-existant variable "
+ + variableName);
+ }
+
+ return enviroment.get(variableName);
+ }
+ } else {
+ if (!enviroment.containsKey(variableName)) {
+ throw new UnsupportedOperationException(
+ "Attempted to inline non-existant variable "
+ + variableName);
+ }
+
+ 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,
+ IFunctionalMap<String, ITree<IDiceASTNode>> enviroment,
+ String... variables) {
+ if (variables != null && variables.length > 0) {
+ IFunctionalList<String> variableNames =
+ new FunctionalList<>(variables);
+
+ return ast.flatMapTree((node) -> {
+ return inlineNode(node, enviroment, true, variableNames);
+ });
+ }
+
+ return ast.flatMapTree((node) -> {
+ return inlineNode(node, enviroment, false, null);
+ });
+ }
+
+ /**
+ * 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,
+ IFunctionalMap<String, ITree<IDiceASTNode>> enviroment,
+ IFunctionalList<String> variables) {
+ return selectiveInline(ast, enviroment,
+ variables.toArray(new String[0]));
+ }
+}
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 95495bd..d8c94dc 100644
--- a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java
@@ -28,17 +28,21 @@ public class DiceASTParser {
* The list of tokens to convert
* @return An AST built from the tokens
*/
- public static ITree<IDiceASTNode> createFromString(
- IFunctionalList<String> tokens) {
- ITree<String> rawTokens = TreeConstructor.constructTree(tokens,
- (token) -> {
+ public static ITree<IDiceASTNode>
+ createFromString(IFunctionalList<String> tokens) {
+ ITree<String> rawTokens =
+ TreeConstructor.constructTree(tokens, (token) -> {
return isOperatorNode(token);
}, (operator) -> false, null);
+
// The last argument is valid because there are no special
// operators yet, so it'll never get called
- return rawTokens.rebuildTree(DiceASTParser::convertLeafNode,
- DiceASTParser::convertOperatorNode);
+ ITree<IDiceASTNode> tokenizedTree =
+ rawTokens.rebuildTree(DiceASTParser::convertLeafNode,
+ DiceASTParser::convertOperatorNode);
+
+ return tokenizedTree;
}
private static boolean isOperatorNode(String token) {
@@ -52,8 +56,8 @@ public class DiceASTParser {
}
private static IDiceASTNode convertLeafNode(String leafNode) {
- DiceLiteralType literalType = ILiteralDiceNode
- .getLiteralType(leafNode);
+ DiceLiteralType literalType =
+ ILiteralDiceNode.getLiteralType(leafNode);
if (literalType != null) {
switch (literalType) {
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
index d034943..ab47b56 100644
--- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java
@@ -2,10 +2,6 @@ package bjc.dicelang.ast.nodes;
import static bjc.dicelang.ast.nodes.DiceOperatorType.*;
-// The following classes need to be changed upon addition of a new operator
-// 1. DiceASTExpression
-// 2. DiceASTFlattener
-// 3. DiceASTParser
/**
* A node that represents an operator
*