summaryrefslogtreecommitdiff
path: root/dice-lang/src/examples/java/bjc/dicelang
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-10-27 21:40:28 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-10-27 21:40:28 -0400
commite13a6981bd278c2cfc3b5ecb2517367b117f7a52 (patch)
treec6a07aef91b5412a2f345316ccaa2fa8d0972e19 /dice-lang/src/examples/java/bjc/dicelang
parentbb27392419549bb40cbc4f194e38f471d2b9f63d (diff)
Work on documentation
Continued work on documenting how exactly the language works
Diffstat (limited to 'dice-lang/src/examples/java/bjc/dicelang')
-rw-r--r--dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java68
-rw-r--r--dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTPragma.java2
-rw-r--r--dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java15
3 files changed, 71 insertions, 14 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
index b331535..fa92fd2 100644
--- a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java
+++ b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java
@@ -3,11 +3,11 @@ package bjc.dicelang.examples;
import java.util.InputMismatchException;
import java.util.Scanner;
+import bjc.utils.data.ITree;
import bjc.utils.funcdata.FunctionalMap;
import bjc.utils.funcdata.FunctionalStringTokenizer;
import bjc.utils.funcdata.IList;
import bjc.utils.funcdata.IMap;
-import bjc.utils.funcdata.ITree;
import bjc.dicelang.ast.DiceASTEvaluator;
import bjc.dicelang.ast.DiceASTInliner;
@@ -30,26 +30,33 @@ public class DiceASTLanguageTest {
private static DiceASTOptimizer optimizer;
+ // Set up things that need to be configured
static {
actions = new FunctionalMap<>();
+ // Inline all the variables in a given expression
actions.put("inline", DiceASTLanguageTest::handleInlineAction);
+ // Print out the enviroment
actions.put("env", (tokenizer, enviroment) -> {
enviroment.forEach((varName, varValue) -> {
System.out.println(varName + " is bound to " + varValue);
});
});
-
+
+ // Create and configure the optimizer
optimizer = new DiceASTOptimizer();
optimizer.addPass(new ConstantCollapser());
}
+ // Read in a command
private static String getNextCommand(Scanner inputSource,
int commandNumber) {
+ // Print a prompt using the current command number
System.out.print("\ndice-lang-" + commandNumber + "> ");
+ // Read in the next command
return inputSource.nextLine();
}
@@ -59,24 +66,30 @@ public class DiceASTLanguageTest {
// Skip the pragma name
tokenizer.nextToken();
+ // Get the pragma arguments
IList<String> pragmaArgs = tokenizer.toList();
if (pragmaArgs.getSize() < 3) {
+ // Complain about pragma arguments not being valid
System.err.println(
"ERROR: Inline requires at least 3 parameters. They are:"
+ "\n\t1. The name of the expression to inline."
+ "\n\t2. The name of the variable to bind the result to."
+ "\n\t3 and onwards. Names of variables to inline in the expression.");
} else {
+ // Get arguments
String inlineExpression = pragmaArgs.getByIndex(0);
String variableName = pragmaArgs.getByIndex(1);
+ // Grab the variables we want to inline
IList<String> inlinedVariables = pragmaArgs.tail().tail();
+ // Actually inline the variable
ITree<IDiceASTNode> inlinedExpression = DiceASTInliner
.selectiveInline(enviroment.get(inlineExpression),
enviroment, inlinedVariables);
+ // Stick the inlined variable into the enviroment
enviroment.put(variableName, inlinedExpression);
}
}
@@ -85,39 +98,47 @@ public class DiceASTLanguageTest {
* Main method of class
*
* @param args
- * Unused CLI args
+ * Unused CLI args
*/
public static void main(String[] args) {
+ // Prepare the things we need for input
Scanner inputSource = new Scanner(System.in);
int commandNumber = 0;
- System.out.print("dice-lang-" + commandNumber + "> ");
- String currentLine = inputSource.nextLine();
+ // Grab the initial command
+ String currentLine = getNextCommand(inputSource, commandNumber);
// The enviroment for variables
IMap<String, ITree<IDiceASTNode>> enviroment = new FunctionalMap<>();
+ // Handle commands
while (!currentLine.equalsIgnoreCase("quit")) {
+ // Get the name of a possible action
String possibleActionName = currentLine.split(" ")[0];
+ // Check and see if we're executing an action
if (actions.containsKey(possibleActionName)) {
// Execute action
FunctionalStringTokenizer tokenizer = new FunctionalStringTokenizer(
currentLine);
+ // Execute the action
actions.get(possibleActionName).accept(tokenizer,
enviroment);
+ // Get the next command
currentLine = getNextCommand(inputSource, commandNumber);
continue;
}
- // Build an AST from the string expression
+ // The AST we are going to build
ITree<IDiceASTNode> builtAST;
+ // Time command preparation
long time = System.nanoTime();
+ // Prepare the command
IList<String> preparedTokens = DiceExpressionPreparer
.prepareCommand(currentLine);
@@ -126,8 +147,10 @@ public class DiceASTLanguageTest {
+ " s");
try {
+ // Time the AST creation
time = System.nanoTime();
+ // Create the AST
builtAST = DiceASTParser.createFromString(preparedTokens);
System.out
@@ -138,18 +161,22 @@ public class DiceASTLanguageTest {
+ " s");
} catch (InputMismatchException | IllegalStateException
| UnsupportedOperationException ex) {
- System.out.println("ERROR: " + ex.getLocalizedMessage());
+ // Tell the user there was an error in parsing
+ System.out.println("PARSING ERROR: " + ex.getLocalizedMessage());
+ // Move onto the next command
currentLine = getNextCommand(inputSource, commandNumber);
continue;
}
- // Print out results
+ // Print out parsed AST
System.out.println("\tParsed: " + builtAST.toString());
+ // Time AST transformation
time = System.nanoTime();
+ // Transform the AST
ITree<IDiceASTNode> transformedAST = transformAST(builtAST,
enviroment);
@@ -157,15 +184,17 @@ public class DiceASTLanguageTest {
+ (double) (System.nanoTime() - time) / 1000000000
+ " s");
+ // Print out the transformed AST
System.out
- .println("\tEvaluated: " + transformedAST.toString());
+ .println("\tTransformed: " + transformedAST.toString());
- IResult sampleRoll;
try {
+ // Time the evaluation
time = System.nanoTime();
- sampleRoll = DiceASTEvaluator.evaluateAST(transformedAST,
+ // Evaluate the expression once
+ IResult sampleResult = DiceASTEvaluator.evaluateAST(transformedAST,
enviroment);
System.out
@@ -175,20 +204,27 @@ public class DiceASTLanguageTest {
- time) / 1000000000
+ " s");
+ // Print out the result of evaluating the expression
+ System.out.println("\t\tSample Result: " + sampleResult);
+
+ // Update the 'last' meta-variable
enviroment.put("last", transformedAST);
} catch (UnsupportedOperationException usex) {
- System.out.println("ERROR: " + usex.getLocalizedMessage());
+ // Tell the user there was an error in evaluation
+ System.out.println("EVALUATION ERROR: " + usex.getLocalizedMessage());
+ // Get the next command
currentLine = getNextCommand(inputSource, commandNumber);
+ // Process it
continue;
}
- System.out.println("\t\tSample Roll: " + sampleRoll);
// Increase the number of commands
commandNumber++;
+ // Get the next command
currentLine = getNextCommand(inputSource, commandNumber);
}
@@ -198,20 +234,26 @@ public class DiceASTLanguageTest {
inputSource.close();
}
+ // Transform a parsed AST
private static ITree<IDiceASTNode> transformAST(
ITree<IDiceASTNode> builtAST,
IMap<String, ITree<IDiceASTNode>> enviroment) {
+ // Optimize the tree first
ITree<IDiceASTNode> optimizedTree = optimizer
.optimizeTree(builtAST, enviroment);
+ // Then, condense unnecessary operations
ITree<IDiceASTNode> condensedTree = OperationCondenser
.condense(optimizedTree);
+ // Next, sanitize references
ITree<IDiceASTNode> sanitizedTree = DiceASTReferenceSanitizer
.sanitize(condensedTree, enviroment);
+ // Re-optimize the sanitized & condensed tree
optimizedTree = optimizer.optimizeTree(sanitizedTree, enviroment);
+ // Re-condense the newly optimized tree
condensedTree = OperationCondenser.condense(optimizedTree);
return condensedTree;
diff --git a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTPragma.java b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTPragma.java
index 87065f1..4900e46 100644
--- a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTPragma.java
+++ b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTPragma.java
@@ -11,6 +11,8 @@ import bjc.dicelang.ast.nodes.IDiceASTNode;
/**
* Alias for the type of a 'pragma' or special language command
*
+ * To explain it, a pragma is a function that takes a tokenizer with the rest
+ * of the line, and an enviroment that contains variable bindings
* @author ben
*
*/
diff --git a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java
index b9b4aab..5488b5d 100644
--- a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java
+++ b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceExpressionPreparer.java
@@ -26,9 +26,12 @@ public class DiceExpressionPreparer {
private static final int DICE_PREC = 10;
private static final int EXPR_PREC = 0;
+ // Do initialization for all parsers
static {
+ // The shunter we're going to use
yard = new ShuntingYard<>(false);
+ // Configure the shunters operators
// Basic mathematical operators
yard.addOp("+", 0 + MATH_PREC);
yard.addOp("-", 0 + MATH_PREC);
@@ -47,12 +50,16 @@ public class DiceExpressionPreparer {
// to a variable expression
}
- static IList<String> prepareCommand(String currentLine) {
+ // Prepare a command, turning raw tokens into input for the tree builder
+ public static IList<String> prepareCommand(String currentLine) {
+ // Split the command into tokens
IList<String> tokens = FunctionalStringTokenizer
.fromString(currentLine).toList();
+ // The linked list to use for handling tokens
Deque<IPair<String, String>> ops = new LinkedList<>();
+ // Prepare the list for operator expansion
ops.add(new Pair<>("+", "\\+"));
ops.add(new Pair<>("-", "-"));
ops.add(new Pair<>("*", "\\*"));
@@ -60,21 +67,27 @@ public class DiceExpressionPreparer {
ops.add(new Pair<>(":=", ":="));
ops.add(new Pair<>("=>", "=>"));
+ // Expand infix single tokens to multiple infix tokens
IList<String> semiExpandedTokens = ListUtils.splitTokens(tokens,
ops);
+ // Reinitialize the list
ops = new LinkedList<>();
+ // Prepare the list for deaffixation
ops.add(new Pair<>("(", "\\("));
ops.add(new Pair<>(")", "\\)"));
ops.add(new Pair<>("[", "\\["));
ops.add(new Pair<>("]", "\\]"));
+ // Deaffix ('s and ['s from tokens
IList<String> fullyExpandedTokens = ListUtils
.deAffixTokens(semiExpandedTokens, ops);
+ // Remove blank tokens
fullyExpandedTokens.removeIf((strang) -> strang.equals(""));
+ // Shunt the tokens, and hand them back
return yard.postfix(fullyExpandedTokens, (token) -> token);
}
}