summaryrefslogtreecommitdiff
path: root/dice-lang/src/bjc/dicelang/DiceLangEngine.java
diff options
context:
space:
mode:
authorBenjamin J. Culkin <bjculkin@mix.wvu.edu>2017-10-08 16:38:35 -0300
committerBenjamin J. Culkin <bjculkin@mix.wvu.edu>2017-10-08 16:38:35 -0300
commit054643900e7b857cafe123b0b4c03f10a95520ed (patch)
treec289fc397fe79ea0a6792e3f2f39a05ed1315936 /dice-lang/src/bjc/dicelang/DiceLangEngine.java
parentf40e5a873420d70d01ff7e01b77bdbd64faab00e (diff)
Update
Diffstat (limited to 'dice-lang/src/bjc/dicelang/DiceLangEngine.java')
-rw-r--r--dice-lang/src/bjc/dicelang/DiceLangEngine.java308
1 files changed, 107 insertions, 201 deletions
diff --git a/dice-lang/src/bjc/dicelang/DiceLangEngine.java b/dice-lang/src/bjc/dicelang/DiceLangEngine.java
index 0ac088e..158239e 100644
--- a/dice-lang/src/bjc/dicelang/DiceLangEngine.java
+++ b/dice-lang/src/bjc/dicelang/DiceLangEngine.java
@@ -13,6 +13,7 @@ import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -33,7 +34,7 @@ import bjc.utils.parserutils.splitter.ConfigurableTokenSplitter;
* @author Ben Culkin
*/
public class DiceLangEngine {
- public boolean debug = true;
+ private static final Logger LOG = Logger.getLogger(DiceLangEngine.class.getName());
/*
* The random fields that are package private instead of private-private
@@ -41,104 +42,69 @@ public class DiceLangEngine {
* them.
*/
- /*
- * Split tokens around operators with regex
- */
+ /* Split tokens around operators with regex */
ConfigurableTokenSplitter opExpander;
- /*
- * ID for generation.
- */
+ /* ID for generation. */
int nextLiteral;
- /*
- * Debug indicator.
- */
+ /* Debug indicator. */
public boolean debugMode;
- /*
- * Should we do shunting?
- */
+ /* Should we do shunting? */
private boolean postfixMode;
- /*
- * Should we reverse the token stream?
- */
+ /* Should we reverse the token stream? */
private boolean prefixMode;
- /*
- * Should we do step-by-step evaluation?
- */
+ /* Should we do step-by-step evaluation? */
private boolean stepEval;
- /*
- * Shunter for token shunting.
- */
+ /* Shunter for token shunting. */
Shunter shunt;
- /*
- * Tokenizer for tokenizing.
- */
+ /* Tokenizer for tokenizing. */
Tokenizer tokenzer;
- /*
- * Parser for tree construction.
- */
+ /* Parser for tree construction. */
Parser parsr;
- /*
- * Evaluator for evaluating.
- */
+ /* Evaluator for evaluating. */
Evaluator eval;
- /*
- * Tables for various things.
- */
+ /* Tables for various things. */
/**
* The symbol table.
*/
public final IMap<Integer, String> symTable;
+ /* String literal tables */
private final IMap<Integer, String> stringLits;
private final IMap<String, String> stringLiterals;
- /*
- * Lists of defns.
- */
+ /* Lists of defns. */
private final IList<Define> lineDefns;
private final IList<Define> tokenDefns;
- /*
- * Are defns sorted by priority?
- */
+ /* Are defns currently sorted by priority? */
private boolean defnsSorted;
- /*
- * Stream engine for processing streams.
- */
+ /* Stream engine for processing streams. */
StreamEngine streamEng;
/**
* Create a new DiceLang engine.
*/
public DiceLangEngine() {
- /*
- * Initialize defns.
- */
+ /* Initialize defns. */
lineDefns = new FunctionalList<>();
tokenDefns = new FunctionalList<>();
defnsSorted = true;
- /*
- * Initialize tables.
- */
+ /* Initialize tables. */
symTable = new FunctionalMap<>();
stringLits = new FunctionalMap<>();
stringLiterals = new FunctionalMap<>();
- /*
- * Initialize operator expansion list.
- */
+ /* Initialize operator expander. */
opExpander = new ConfigurableTokenSplitter(true);
-
opExpander.addMultiDelimiters("(", ")");
opExpander.addMultiDelimiters("[", "]");
opExpander.addMultiDelimiters("{", "}");
-
opExpander.addSimpleDelimiters(":=");
opExpander.addSimpleDelimiters("=>");
opExpander.addSimpleDelimiters("//");
@@ -150,22 +116,16 @@ public class DiceLangEngine {
opExpander.addSimpleDelimiters("/");
opExpander.compile();
- /*
- * Initialize literal IDs
- */
+ /* Initialize literal IDs */
nextLiteral = 1;
- /*
- * Initial mode settings.
- */
+ /* Initial mode settings. */
debugMode = true;
postfixMode = false;
prefixMode = false;
stepEval = false;
- /*
- * Create components.
- */
+ /* Create components. */
streamEng = new StreamEngine(this);
shunt = new Shunter();
tokenzer = new Tokenizer(this);
@@ -251,9 +211,7 @@ public class DiceLangEngine {
return stepEval;
}
- /*
- * Matches double-angle bracketed strings.
- */
+ /* Matches double-angle bracketed strings. */
private final Pattern nonExpandPattern =
Pattern.compile("<<([^\\>]*(?:\\>(?:[^\\>])*)*)>>");
@@ -266,66 +224,44 @@ public class DiceLangEngine {
* @return Whether or not the command ran successfully
*/
public boolean runCommand(final String command) {
- /*
- * Preprocess the command into tokens
- */
+ /* Preprocess the command into tokens */
final IList<String> preprocessedTokens = preprocessCommand(command);
-
if (preprocessedTokens == null) return false;
- /*
- * Lex the string tokens into token-tokens
- */
+ /* Lex the string tokens into token-tokens */
final IList<Token> lexedTokens = lexTokens(preprocessedTokens);
-
if (lexedTokens == null) return false;
- /*
- * Parse the tokens into an AST forest
- */
+ /* Parse the tokens into an AST forest */
final IList<ITree<Node>> astForest = new FunctionalList<>();
final boolean succ = Parser.parseTokens(lexedTokens, astForest);
-
if (!succ) return false;
- /*
- * Evaluate the AST forest
- */
+ /* Evaluate the AST forest */
evaluateForest(astForest);
-
return true;
}
- /*
- * Lex string tokens into token-tokens
- */
+ /* Lex string tokens into token-tokens */
private IList<Token> lexTokens(final IList<String> preprocessedTokens) {
final IList<Token> lexedTokens = new FunctionalList<>();
for (final String token : preprocessedTokens) {
String newTok = token;
- /*
- * Apply token defns
- */
+ /* Apply token defns */
for (final Define dfn : tokenDefns.toIterable()) {
newTok = dfn.apply(newTok);
}
- /*
- * Lex the token
- */
+ /* Lex the token */
final Token tk = tokenzer.lexToken(token, stringLiterals);
-
+ if(debugMode) LOG.finer(String.format("lexed token: %s\n", tk));
if (tk == null) {
- /*
- * Ignore blank tokens
- */
+ /* Ignore blank tokens */
continue;
} else if (tk == Token.NIL_TOKEN)
- /*
- * Fail on bad tokens
- */
+ /* Fail on bad tokens */
return null;
else {
lexedTokens.add(tk);
@@ -333,56 +269,58 @@ public class DiceLangEngine {
}
if (debugMode) {
- System.out.printf("\tCommand after tokenization: %s\n", lexedTokens.toString());
+ String msg = String.format("\tCommand after tokenization: %s\n", lexedTokens.toString());
+ LOG.fine(msg);
+ System.out.print(msg);
}
- /*
- * Preshunt preshunt-marked groups of tokens
- */
+ /* Preshunt preshunt-marked groups of tokens */
IList<Token> shuntedTokens = lexedTokens;
final IList<Token> preparedTokens = new FunctionalList<>();
boolean succ = removePreshuntTokens(lexedTokens, preparedTokens);
-
if (!succ) return null;
if (debugMode && !postfixMode) {
- System.out.printf("\tCommand after pre-shunter removal: %s\n", preparedTokens.toString());
+ String msg = String.format("\tCommand after pre-shunter removal: %s\n", preparedTokens.toString());
+ LOG.fine(msg);
+ System.out.print(msg);
}
if (!postfixMode && !prefixMode) {
- /*
- * Shunt the tokens
- */
+ /* Shunt the tokens */
shuntedTokens = new FunctionalList<>();
succ = shunt.shuntTokens(preparedTokens, shuntedTokens);
if (!succ) return null;
} else if (prefixMode) {
- /*
- * Reverse directional tokens
- */
+ /* Reverse directional tokens */
preparedTokens.reverse();
shuntedTokens = preparedTokens.map(this::reverseToken);
}
if (debugMode && !postfixMode) {
- System.out.printf("\tCommand after shunting: %s\n", shuntedTokens.toString());
+ String msg = String.format("\tCommand after shunting: %s\n", shuntedTokens.toString());
+ LOG.fine(msg);
+ System.out.print(msg);
}
- /*
- * Expand token groups
- */
+ /* Expand token groups */
final IList<Token> readyTokens = shuntedTokens.flatMap(tk -> {
- if (tk.type == Token.Type.TOKGROUP)
- return tk.tokenValues;
- else if (tk.type == Token.Type.TAGOP || tk.type == Token.Type.TAGOPR)
+ if (tk.type == Token.Type.TOKGROUP ||
+ tk.type == Token.Type.TAGOP ||
+ tk.type == Token.Type.TAGOPR ) {
+ LOG.finer(String.format("Expanding token group to: %s\n", tk.tokenValues.toString()));
return tk.tokenValues;
- else return new FunctionalList<>(tk);
+ } else {
+ return new FunctionalList<>(tk);
+ }
});
if (debugMode && !postfixMode) {
- System.out.printf("\tCommand after re-preshunting: %s\n", readyTokens.toString());
+ String msg = String.format("\tCommand after re-preshunting: %s\n", readyTokens.toString());
+ LOG.fine(msg);
+ System.out.print(msg);
}
return readyTokens;
@@ -397,53 +335,40 @@ public class DiceLangEngine {
switch (tk.type) {
case OBRACE:
return new Token(CBRACE, tk.intValue);
-
case OPAREN:
return new Token(CPAREN, tk.intValue);
-
case OBRACKET:
return new Token(CBRACKET, tk.intValue);
-
case CBRACE:
return new Token(OBRACE, tk.intValue);
-
case CPAREN:
return new Token(OPAREN, tk.intValue);
-
case CBRACKET:
return new Token(OBRACKET, tk.intValue);
-
default:
return tk;
}
}
- /*
- * Preprocess a command into a list of string tokens.
- */
+ /* Preprocess a command into a list of string tokens. */
private IList<String> preprocessCommand(final String command) {
- /*
- * Sort the defines if they aren't sorted
- */
+ /* Sort the defines if they aren't sorted */
if (!defnsSorted) {
sortDefns();
}
- /*
- * Run the tokens through the stream engine
- */
+ /* Run the tokens through the stream engine */
final IList<String> streamToks = new FunctionalList<>();
final boolean succ = streamEng.doStreams(command.split(" "), streamToks);
-
if (!succ) return null;
- /*
- * Apply line defns
- */
+ /* Apply line defns */
String newComm = ListUtils.collapseTokens(streamToks, " ");
if (debugMode) {
- System.out.println("\tCommand after stream commands: " + newComm);
+ String msg = String.format("\tCommand after stream commands: %s\n", newComm);
+ LOG.fine(msg);
+ System.out.print(msg);
}
for (final Define dfn : lineDefns.toIterable()) {
@@ -451,23 +376,19 @@ public class DiceLangEngine {
}
if (debugMode) {
- System.out.println("\tCommand after line defines: " + newComm);
+ String msg = String.format("\tCommand after line defines: %s\n", newComm);
+ LOG.fine(msg);
+ System.out.print(msg);
}
- /*
- * Remove string literals.
- */
+ /* Remove string literals. */
final List<String> destringedParts = TokenUtils.removeDQuotedStrings(newComm);
final StringBuffer destringedCommand = new StringBuffer();
for (final String part : destringedParts) {
- /*
- * Handle string literals
- */
+ /* Handle string literals */
if (part.startsWith("\"") && part.endsWith("\"")) {
- /*
- * Get the actual string.
- */
+ /* Get the actual string. */
final String litName = "stringLiteral" + nextLiteral;
final String litVal = part.substring(1, part.length() - 1);
@@ -475,12 +396,14 @@ public class DiceLangEngine {
* Insert the string with its escape sequences
* interpreted.
*/
- stringLiterals.put(litName, TokenUtils.descapeString(litVal));
+ final String descVal = TokenUtils.descapeString(litVal);
+ stringLiterals.put(litName, descVal);
+ if(debugMode)
+ LOG.finer(String.format("Replaced string literal '%s' with literal no. %d",
+ descVal, nextLiteral));
nextLiteral += 1;
- /*
- * Place a ref. to the string in the command
- */
+ /* Place a ref. to the string in the command */
destringedCommand.append(" " + litName + " ");
} else {
destringedCommand.append(part);
@@ -488,11 +411,11 @@ public class DiceLangEngine {
}
if (debugMode) {
- System.out.println("\tCommand after destringing: " + destringedCommand);
+ String msg = String.format("\tCommand after destringing: %s\n", destringedCommand);
+ LOG.fine(msg);
+ System.out.print(msg);
- /*
- * Print the string table if it exists.
- */
+ /* Print the string table if it exists. */
if (stringLiterals.size() > 0) {
System.out.println("\tString literals in table");
@@ -502,15 +425,11 @@ public class DiceLangEngine {
}
}
- /*
- * Split the command into tokens
- */
+ /* Split the command into tokens */
final String strang = destringedCommand.toString();
IList<String> tokens = FunctionalStringTokenizer.fromString(strang).toList();
- /*
- * Temporarily remove non-expanding tokens
- */
+ /* Temporarily remove non-expanding tokens */
final IMap<String, String> nonExpandedTokens = new FunctionalMap<>();
tokens = tokens.map(tk -> {
final Matcher nonExpandMatcher = nonExpandPattern.matcher(tk);
@@ -519,6 +438,7 @@ public class DiceLangEngine {
final String tkName = "nonExpandToken" + nextLiteral++;
nonExpandedTokens.put(tkName, nonExpandMatcher.group(1));
+ LOG.finer(String.format("Pulled non-expander '%s' to '%s'", nonExpandMatcher.group(1), tkName));
return tkName;
}
@@ -526,18 +446,20 @@ public class DiceLangEngine {
});
if (debugMode) {
- System.out.printf("\tCommand after removal of non-expanders: %s\n", tokens.toString());
+ String msg = String.format("\tCommand after removal of non-expanders: %s\n", tokens.toString());
+ LOG.fine(msg);
+ System.out.print(msg);
}
- /*
- * Expand tokens
- */
+ /* Expand tokens */
IList<String> fullyExpandedTokens = tokens.flatMap(opExpander::split);
- System.out.println("\tCommand after token expansion: " + fullyExpandedTokens.toString());
+ if(debugMode) {
+ String msg = String.format("\tCommand after token expansion: %s\n", fullyExpandedTokens.toString());
+ LOG.fine(msg);
+ System.out.print(msg);
+ }
- /*
- * Reinsert non-expanded tokens
- */
+ /* Reinsert non-expanded tokens */
fullyExpandedTokens = fullyExpandedTokens.map(tk -> {
if (tk.startsWith("nonExpandToken")) return nonExpandedTokens.get(tk);
@@ -545,18 +467,17 @@ public class DiceLangEngine {
});
if (debugMode) {
- System.out.printf("\tCommand after non-expander reinsertion: %s\n",
- fullyExpandedTokens.toString());
+ String msg = String.format("\tCommand after non-expander reinsertion: %s\n",
+ fullyExpandedTokens.toString());
+ LOG.fine(msg);
+ System.out.print(msg);
}
return fullyExpandedTokens;
}
+ /* Evaluate a forest of AST nodes. */
private void evaluateForest(final IList<ITree<Node>> astForest) {
- if (debugMode) {
- System.out.println("\tParsed forest of asts");
- }
-
int treeNo = 1;
for (final ITree<Node> ast : astForest) {
@@ -565,19 +486,16 @@ public class DiceLangEngine {
}
if (debugMode && stepEval) {
+ /* @TODO fix stepEval */
int step = 1;
- /*
- * Evaluate it step by step
- */
+ /* Evaluate it step by step */
for (final Iterator<ITree<Node>> itr = eval.stepDebug(ast); itr.hasNext();) {
final ITree<Node> nodeStep = itr.next();
System.out.printf("\t\tStep %d: Node is %s", step, nodeStep);
- /*
- * Don't evaluate null steps
- */
+ /* Don't evaluate null steps */
if (nodeStep == null) {
System.out.println();
@@ -585,9 +503,7 @@ public class DiceLangEngine {
continue;
}
- /*
- * Print out details for results
- */
+ /* Print out details for results */
if (nodeStep.getHead().type == Node.Type.RESULT) {
final EvaluatorResult res = nodeStep.getHead().resultVal;
@@ -611,9 +527,7 @@ public class DiceLangEngine {
step += 1;
}
} else {
- /*
- * Evaluate it normally
- */
+ /* Evaluate it normally */
final EvaluatorResult res = eval.evaluate(ast);
if (debugMode) {
@@ -631,27 +545,19 @@ public class DiceLangEngine {
}
}
- /*
- * Preshunt preshunt-marked groups of tokens.
- */
+ /* Preshunt preshunt-marked groups of tokens. */
private boolean removePreshuntTokens(final IList<Token> lexedTokens,
final IList<Token> preparedTokens) {
- /*
- * Current nesting level of tokens.
- */
+ /* Current nesting level of tokens. */
int curBraceCount = 0;
- /*
- * Data storage.
- */
+ /* Data storage. */
final Deque<IList<Token>> bracedTokens = new LinkedList<>();
IList<Token> curBracedTokens = new FunctionalList<>();
for (final Token tk : lexedTokens) {
if (tk.type == Token.Type.OBRACE && tk.intValue == 2) {
- /*
- * Open a preshunt group.
- */
+ /* Open a preshunt group. */
curBraceCount += 1;
if (curBraceCount != 1) {