diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-08 16:38:35 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-08 16:38:35 -0300 |
| commit | 054643900e7b857cafe123b0b4c03f10a95520ed (patch) | |
| tree | c289fc397fe79ea0a6792e3f2f39a05ed1315936 /dice-lang/src/bjc/dicelang/DiceLangEngine.java | |
| parent | f40e5a873420d70d01ff7e01b77bdbd64faab00e (diff) | |
Update
Diffstat (limited to 'dice-lang/src/bjc/dicelang/DiceLangEngine.java')
| -rw-r--r-- | dice-lang/src/bjc/dicelang/DiceLangEngine.java | 308 |
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) { |
