summaryrefslogtreecommitdiff
path: root/dice-lang/src/main/java/bjc/dicelang/ast
diff options
context:
space:
mode:
Diffstat (limited to 'dice-lang/src/main/java/bjc/dicelang/ast')
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java70
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/DiceASTType.java27
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/IDiceASTNode.java23
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/LiteralDiceNode.java192
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java92
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/VariableDiceNode.java101
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/nodes/package-info.java6
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/optimization/DiceASTOptimizer.java210
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/optimization/package-info.java6
-rw-r--r--dice-lang/src/main/java/bjc/dicelang/ast/package-info.java6
10 files changed, 76 insertions, 657 deletions
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java
new file mode 100644
index 0000000..db2ba98
--- /dev/null
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTParser.java
@@ -0,0 +1,70 @@
+package bjc.dicelang.ast;
+
+import java.util.InputMismatchException;
+
+import bjc.dicelang.old.ast.nodes.IDiceASTNode;
+import bjc.dicelang.old.ast.nodes.LiteralDiceNode;
+import bjc.dicelang.old.ast.nodes.OperatorDiceNode;
+import bjc.dicelang.old.ast.nodes.VariableDiceNode;
+import bjc.utils.funcdata.IFunctionalList;
+import bjc.utils.parserutils.AST;
+import bjc.utils.parserutils.TreeConstructor;
+
+/**
+ * Parse a string expression into AST form. Doesn't do anything else
+ *
+ * @author ben
+ *
+ */
+public class DiceASTParser {
+ /**
+ * 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 AST<IDiceASTNode> createFromString(
+ IFunctionalList<String> tokens) {
+ AST<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);
+ }
+
+ private static boolean isOperatorNode(String token) {
+ try {
+ OperatorDiceNode.fromString(token);
+ return true;
+ } catch (@SuppressWarnings("unused") IllegalArgumentException iaex) {
+ // We don't care about details
+ return false;
+ }
+ }
+
+ private static IDiceASTNode convertLeafNode(String leafNode) {
+ if (LiteralDiceNode.isLiteral(leafNode)) {
+ return new LiteralDiceNode(leafNode);
+ }
+
+ 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;
+ }
+ }
+}
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/IDiceASTNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/IDiceASTNode.java
deleted file mode 100644
index afa0bcd..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 {
- /**
- * Check if this node represents an operator or not
- *
- * @return Whether or not this node represents an operator
- */
- public boolean isOperator();
-
- /**
- * Get the type of AST node this node is
- *
- * @return The type of AST node this AST node is
- */
- public DiceASTType getType();
-} \ No newline at end of file
diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/LiteralDiceNode.java b/dice-lang/src/main/java/bjc/dicelang/ast/nodes/LiteralDiceNode.java
deleted file mode 100644
index 1a6d2bf..0000000
--- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/LiteralDiceNode.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package bjc.dicelang.ast.nodes;
-
-import org.apache.commons.lang3.StringUtils;
-
-import bjc.dicelang.ComplexDice;
-import bjc.dicelang.CompoundDice;
-import bjc.dicelang.IDiceExpression;
-import bjc.dicelang.ScalarDie;
-import bjc.utils.data.Pair;
-import bjc.utils.parserutils.AST;
-
-/**
- * A AST node that represents a literal value
- *
- * @author ben
- *
- */
-public class LiteralDiceNode implements IDiceASTNode {
- private static boolean isValidInfixOperator(String dat, String op) {
- return StringUtils.countMatches(dat, op) == 1
- && !dat.equalsIgnoreCase(op) && !dat.startsWith(op);
- }
-
- /**
- * The value contained by this node
- */
- private String value;
-
- /**
- * Create a new node with the given value
- *
- * @param data
- * The value to be in this node
- */
- public LiteralDiceNode(String data) {
- this.value = data;
- }
-
- /**
- * Create a new node with the given value
- *
- * @param val
- * The value for this node
- */
- public LiteralDiceNode(int val) {
- this(Integer.toString(val));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- } else if (obj == null) {
- return false;
- } else if (getClass() != obj.getClass()) {
- return false;
- } else {
- LiteralDiceNode other = (LiteralDiceNode) obj;
-
- if (value == null) {
- if (other.value != null) {
- return false;
- }
- } else if (!value.equals(other.value)) {
- return false;
- }
-
- return true;
- }
- }
-
- /**
- * Get the data stored in this AST node
- *
- * @return the data stored in this AST node
- */
- public String getData() {
- return value;
- }
-
- @Override
- public DiceASTType getType() {
- return DiceASTType.LITERAL;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((value == null) ? 0 : value.hashCode());
- return result;
- }
-
- @Override
- public boolean isOperator() {
- return false;
- }
-
- /**
- * Parse this node into an expression
- *
- * @return The node in expression form
- */
- public IDiceExpression toExpression() {
- String literalData = this.getData();
-
- if (LiteralDiceNode.isValidInfixOperator(literalData, "c")) {
- String[] strangs = literalData.split("c");
-
- return new CompoundDice(strangs);
- } else if (LiteralDiceNode.isValidInfixOperator(literalData,
- "d")) {
- /*
- * Handle dice groups
- */
- return ComplexDice.fromString(literalData);
- } else {
- try {
- return new ScalarDie(Integer.parseInt(literalData));
- } catch (NumberFormatException nfex) {
- UnsupportedOperationException usex = new UnsupportedOperationException(
- "Found malformed leaf token " + this);
-
- usex.initCause(nfex);
-
- throw usex;
- }
- }
- }
-
- /**
- * Parse this node into an expression
- *
- * @return The node as a pair of a sample value and the AST it
- * represents
- */
- public Pair<Integer, AST<IDiceASTNode>> toParseValue() {
- AST<IDiceASTNode> returnedAST = new AST<>(this);
-
- IDiceExpression expression = toExpression();
-
- return new Pair<>(expression.roll(), returnedAST);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return value;
- }
-
- /**
- * Check if this node represents a constant value
- *
- * @return Whether or not this node represents a constant value
- */
- public boolean isConstant() {
- try {
- Integer.parseInt(value);
- return true;
- } catch (@SuppressWarnings("unused") NumberFormatException nfex) {
- // We don't care about details
- return false;
- }
- }
-
- /**
- * Return the constant value this node represents
- *
- * @return The constant value of this node
- *
- * @throws NumberFormatException
- * if you call this on a node that doesn't represent a
- * constant value
- */
- public int toConstant() {
- return Integer.parseInt(value);
- }
-} \ No newline at end of file
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 2820cfb..0000000
--- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/OperatorDiceNode.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package bjc.dicelang.ast.nodes;
-
-// 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
- *
- * @author ben
- *
- */
-public enum OperatorDiceNode implements IDiceASTNode {
- /**
- * Represents adding two nodes
- */
- ADD,
- /**
- * Represents assigning one node to another
- */
- ASSIGN,
- /**
- * Representings combining two node values together
- */
- COMPOUND,
- /**
- * Represents dividing two nodes
- */
- DIVIDE,
- /**
- * Represents using one node a variable number of times
- */
- GROUP,
- /**
- * Represents multiplying two nodes
- */
- MULTIPLY,
- /**
- * Represents subtracting two nodes
- */
- SUBTRACT,
- /**
- * Represents executing one statement in the context of the other
- */
- LET;
-
- /**
- * 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":
- return GROUP;
- case "c":
- return COMPOUND;
- case "->":
- return LET;
- default:
- throw new IllegalArgumentException(
- s + " is not a valid operator node");
- }
- }
-
- @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 29fd483..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 variable reference
- *
- * @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 97f1990..0000000
--- a/dice-lang/src/main/java/bjc/dicelang/ast/nodes/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * This package contains the various Node types in the Dice 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/DiceASTOptimizer.java b/dice-lang/src/main/java/bjc/dicelang/ast/optimization/DiceASTOptimizer.java
deleted file mode 100644
index f6be7ab..0000000
--- a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/DiceASTOptimizer.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package bjc.dicelang.ast.optimization;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
-
-import bjc.dicelang.IDiceExpression;
-import bjc.dicelang.ast.nodes.DiceASTType;
-import bjc.dicelang.ast.nodes.IDiceASTNode;
-import bjc.dicelang.ast.nodes.LiteralDiceNode;
-import bjc.dicelang.ast.nodes.OperatorDiceNode;
-
-import static bjc.dicelang.ast.nodes.DiceASTType.*;
-
-import bjc.utils.parserutils.AST;
-
-/**
- * Optimize an AST
- *
- * @author ben
- *
- */
-public class DiceASTOptimizer {
- private static final class NestedArithmeticOperationCollapser
- implements BinaryOperator<AST<IDiceASTNode>> {
- private IDiceASTNode type;
- private BiFunction<Integer, Integer, Integer> valueCollapser;
-
- public NestedArithmeticOperationCollapser(IDiceASTNode type,
- BiFunction<Integer, Integer, Integer> valueCollapser) {
- this.type = type;
- this.valueCollapser = valueCollapser;
- }
-
- @Override
- public AST<IDiceASTNode> apply(AST<IDiceASTNode> leftAST,
- AST<IDiceASTNode> rightAST) {
- AST<IDiceASTNode> rightBranchOfLeftAST = leftAST
- .applyToRight((rightSideAST) -> rightSideAST);
- AST<IDiceASTNode> leftBranchOfLeftAST = leftAST
- .applyToRight((rightSideAST) -> rightSideAST);
-
- boolean leftContainsNestedConstant = DiceASTOptimizer
- .checkNodeType(rightBranchOfLeftAST, LITERAL)
- && DiceASTOptimizer.isNodeConstant(leftAST);
-
- boolean isRightConstant = DiceASTOptimizer
- .checkNodeType(rightAST, LITERAL)
- && DiceASTOptimizer.isNodeConstant(leftAST);
-
- if (leftContainsNestedConstant && isRightConstant) {
- int combinedValue = valueCollapser.apply(
- getNodeValue(rightBranchOfLeftAST),
- getNodeValue(rightAST));
-
- AST<IDiceASTNode> newRightBranch = new AST<>(
- new LiteralDiceNode(combinedValue));
-
- return new AST<>(type, leftBranchOfLeftAST,
- newRightBranch);
- }
-
- return new AST<>(type, leftAST, rightAST);
- }
- }
-
- private static final class ArithmeticOperationCollapser
- implements BinaryOperator<AST<IDiceASTNode>> {
- private IDiceASTNode type;
- private BiFunction<Integer, Integer, Integer> valueCollapser;
- private boolean doSwap;
-
- public ArithmeticOperationCollapser(IDiceASTNode type,
- BiFunction<Integer, Integer, Integer> valueCollapser,
- boolean doSwap) {
- this.type = type;
- this.valueCollapser = valueCollapser;
- this.doSwap = doSwap;
- }
-
- @Override
- public AST<IDiceASTNode> apply(AST<IDiceASTNode> leftAST,
- AST<IDiceASTNode> rightAST) {
- boolean isLeftConstant = DiceASTOptimizer
- .checkNodeType(leftAST, LITERAL)
- && DiceASTOptimizer.isNodeConstant(leftAST);
-
- boolean isRightConstant = DiceASTOptimizer
- .checkNodeType(rightAST, LITERAL)
- && DiceASTOptimizer.isNodeConstant(leftAST);
-
- if (isLeftConstant) {
- if (isRightConstant) {
- int combinedValue = valueCollapser.apply(
- getNodeValue(leftAST), getNodeValue(rightAST));
-
- return new AST<>(new LiteralDiceNode(combinedValue));
- }
-
- if (doSwap) {
- return new AST<>(type, rightAST, leftAST);
- }
- }
-
- return new AST<>(type, leftAST, rightAST);
- }
- }
-
- private static Map<IDiceASTNode, BinaryOperator<AST<IDiceASTNode>>> buildConstantCollapsers() {
- Map<IDiceASTNode, BinaryOperator<AST<IDiceASTNode>>> operatorCollapsers = new HashMap<>();
-
- operatorCollapsers.put(OperatorDiceNode.ADD,
- new ArithmeticOperationCollapser(OperatorDiceNode.ADD,
- (leftVal, rightVal) -> leftVal + rightVal, true));
-
- operatorCollapsers.put(OperatorDiceNode.MULTIPLY,
- new ArithmeticOperationCollapser(OperatorDiceNode.MULTIPLY,
- (leftVal, rightVal) -> leftVal * rightVal, true));
-
- operatorCollapsers.put(OperatorDiceNode.SUBTRACT,
- new ArithmeticOperationCollapser(OperatorDiceNode.SUBTRACT,
- (leftVal, rightVal) -> leftVal - rightVal, false));
-
- operatorCollapsers.put(OperatorDiceNode.DIVIDE,
- new ArithmeticOperationCollapser(OperatorDiceNode.DIVIDE,
- (leftVal, rightVal) -> leftVal / rightVal, false));
-
- return operatorCollapsers;
- }
-
- private static Map<IDiceASTNode, BinaryOperator<AST<IDiceASTNode>>> buildNestedConstantCollapsers() {
- Map<IDiceASTNode, BinaryOperator<AST<IDiceASTNode>>> operatorCollapsers = new HashMap<>();
-
- operatorCollapsers.put(OperatorDiceNode.ADD,
- new NestedArithmeticOperationCollapser(
- OperatorDiceNode.ADD,
- (leftVal, rightVal) -> leftVal + rightVal));
-
- operatorCollapsers.put(OperatorDiceNode.MULTIPLY,
- new NestedArithmeticOperationCollapser(
- OperatorDiceNode.MULTIPLY,
- (leftVal, rightVal) -> leftVal * rightVal));
-
- return operatorCollapsers;
- }
-
- private static AST<IDiceASTNode> collapseLeaf(IDiceASTNode leaf) {
- // Can't optimize a simple reference
- if (leaf.getType() == VARIABLE) {
- return new AST<>(leaf);
- } else if (leaf.getType() == LITERAL) {
- LiteralDiceNode node = (LiteralDiceNode) leaf;
-
- return new AST<>(optimizeLiteral(node, node.toExpression()));
- } else {
- throw new UnsupportedOperationException(
- "Found leaf operator. This isn't supported");
- }
- }
-
- private static IDiceASTNode optimizeLiteral(LiteralDiceNode node,
- IDiceExpression leaf) {
- if (leaf.canOptimize()) {
- return new LiteralDiceNode(Integer.toString(leaf.optimize()));
- }
-
- return node;
- }
-
- private static AST<IDiceASTNode> finishTree(AST<IDiceASTNode> tree) {
- return tree;
- }
-
- /**
- * Optimize a tree of expressions into a simpler form
- *
- * @param tree
- * The tree to optimize
- * @return The optimized tree
- */
- public static AST<IDiceASTNode> optimizeTree(AST<IDiceASTNode> tree) {
- AST<IDiceASTNode> astWithConstantsFolded = tree.collapse(
- DiceASTOptimizer::collapseLeaf,
- buildConstantCollapsers()::get,
- DiceASTOptimizer::finishTree);
-
- AST<IDiceASTNode> astWithNestedConstantsFolded = astWithConstantsFolded
- .collapse(DiceASTOptimizer::collapseLeaf,
- buildNestedConstantCollapsers()::get,
- DiceASTOptimizer::finishTree);
-
- return astWithNestedConstantsFolded;
- }
-
- private static boolean checkNodeType(AST<IDiceASTNode> ast,
- DiceASTType type) {
- return ast.applyToHead((node) -> node.getType()) == type;
- }
-
- private static boolean isNodeConstant(AST<IDiceASTNode> ast) {
- return ast.applyToHead(
- (node) -> ((LiteralDiceNode) node).isConstant());
- }
-
- private static int getNodeValue(AST<IDiceASTNode> ast) {
- return ast.applyToHead(
- (node) -> ((LiteralDiceNode) node).toConstant());
- }
-}
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 132563d..0000000
--- a/dice-lang/src/main/java/bjc/dicelang/ast/optimization/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Contains classes for optimizing 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
new file mode 100644
index 0000000..105af50
--- /dev/null
+++ b/dice-lang/src/main/java/bjc/dicelang/ast/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * New implementation of AST for dice-lang
+ * @author ben
+ *
+ */
+package bjc.dicelang.ast; \ No newline at end of file