diff options
Diffstat (limited to 'base/src/bjc/dicelang/DiceLangEngine.java')
| -rw-r--r-- | base/src/bjc/dicelang/DiceLangEngine.java | 172 |
1 files changed, 94 insertions, 78 deletions
diff --git a/base/src/bjc/dicelang/DiceLangEngine.java b/base/src/bjc/dicelang/DiceLangEngine.java index f8fc5c6..2aafcd5 100644 --- a/base/src/bjc/dicelang/DiceLangEngine.java +++ b/base/src/bjc/dicelang/DiceLangEngine.java @@ -13,6 +13,7 @@ import bjc.dicelang.eval.Evaluator; import bjc.dicelang.eval.EvaluatorResult; import bjc.dicelang.eval.FailureEvaluatorResult; import bjc.dicelang.scl.StreamEngine; +import bjc.dicelang.tokens.Token; import bjc.utils.data.ITree; import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalMap; @@ -24,7 +25,7 @@ import bjc.utils.parserutils.TokenUtils; import bjc.utils.parserutils.splitter.ConfigurableTokenSplitter; import static bjc.dicelang.Errors.ErrorKey.*; -import static bjc.dicelang.Token.Type.*; +import static bjc.dicelang.tokens.Token.Type.*; /** * Implements the orchestration necessary for processing DiceLang commands. @@ -36,8 +37,9 @@ public class DiceLangEngine { private static final Logger LOG = Logger.getLogger(DiceLangEngine.class.getName()); /* - * The random fields that are package private instead of private-private are for - * the benefit of the tweaker, so that it can mess around with them. + * The random fields that are package private instead of private-private + * are for the benefit of the tweaker, so that it can mess around with + * them. */ /* Split tokens around operators with regex */ @@ -144,7 +146,7 @@ public class DiceLangEngine { * Add a defn that's applied to lines. * * @param dfn - * The defn to add. + * The defn to add. */ public void addLineDefine(final Define dfn) { lineDefns.add(dfn); @@ -156,7 +158,7 @@ public class DiceLangEngine { * Add a defn that's applied to tokens. * * @param dfn - * The defn to add. + * The defn to add. */ public void addTokenDefine(final Define dfn) { tokenDefns.add(dfn); @@ -215,7 +217,7 @@ public class DiceLangEngine { * Run a command to completion. * * @param command - * The command to run + * The command to run * * @return Whether or not the command ran successfully */ @@ -224,18 +226,19 @@ public class DiceLangEngine { /* * @NOTE * - * Instead of strings, this should maybe use a RawToken class or something. + * Instead of strings, this should maybe use a RawToken class or + * something. */ final IList<String> preprocessedTokens = preprocessCommand(command); - if (preprocessedTokens == null) { + if(preprocessedTokens == null) { return false; } /* Lex the string tokens into token-tokens */ final IList<Token> lexedTokens = lexTokens(preprocessedTokens); - if (lexedTokens == null) { + if(lexedTokens == null) { return false; } @@ -243,7 +246,7 @@ public class DiceLangEngine { final IList<ITree<Node>> astForest = new FunctionalList<>(); final boolean succ = Parser.parseTokens(lexedTokens, astForest); - if (!succ) { + if(!succ) { return false; } @@ -256,14 +259,14 @@ public class DiceLangEngine { private IList<Token> lexTokens(final IList<String> preprocessedTokens) { final IList<Token> lexedTokens = new FunctionalList<>(); - for (final String token : preprocessedTokens) { + for(final String token : preprocessedTokens) { String newTok = token; /* Apply token defns */ - for (final Define dfn : tokenDefns.toIterable()) { + for(final Define dfn : tokenDefns.toIterable()) { /* - * @NOTE What happens with a define that produces multiple tokens from one - * token? + * @NOTE What happens with a define that + * produces multiple tokens from one token? */ newTok = dfn.apply(newTok); } @@ -271,14 +274,14 @@ public class DiceLangEngine { /* Lex the token */ final Token tk = tokenzer.lexToken(token, stringLiterals); - if (debugMode) { + if(debugMode) { LOG.finer(String.format("lexed token: %s\n", tk)); } - if (tk == null) { + if(tk == null) { /* Ignore blank tokens */ continue; - } else if (tk == Token.NIL_TOKEN) { + } else if(tk == Token.NIL_TOKEN) { /* Fail on bad tokens */ return null; } else { @@ -286,7 +289,7 @@ public class DiceLangEngine { } } - if (debugMode) { + if(debugMode) { String msg = String.format("\tCommand after tokenization: %s\n", lexedTokens.toString()); LOG.fine(msg); System.out.print(msg); @@ -298,35 +301,37 @@ public class DiceLangEngine { boolean succ = removePreshuntTokens(lexedTokens, preparedTokens); - if (!succ) { + if(!succ) { return null; } - if (debugMode && !postfixMode) { - String msg = String.format("\tCommand after pre-shunter removal: %s\n", preparedTokens.toString()); + if(debugMode && !postfixMode) { + String msg = String.format("\tCommand after pre-shunter removal: %s\n", + preparedTokens.toString()); LOG.fine(msg); System.out.print(msg); } /* Only shunt if we're not in a special mode. */ - if (!postfixMode && !prefixMode) { + if(!postfixMode && !prefixMode) { /* Shunt the tokens */ shuntedTokens = new FunctionalList<>(); succ = shunt.shuntTokens(preparedTokens, shuntedTokens); - if (!succ) { + if(!succ) { return null; } - } else if (prefixMode) { + } else if(prefixMode) { /* Reverse directional tokens */ /* - * @NOTE Merge these two operations into one iteration over the list? + * @NOTE Merge these two operations into one iteration + * over the list? */ preparedTokens.reverse(); shuntedTokens = preparedTokens.map(this::reverseToken); } - if (debugMode && !postfixMode) { + if(debugMode && !postfixMode) { String msg = String.format("\tCommand after shunting: %s\n", shuntedTokens.toString()); LOG.fine(msg); System.out.print(msg); @@ -334,7 +339,8 @@ public class DiceLangEngine { /* Expand token groups */ final IList<Token> readyTokens = shuntedTokens.flatMap(tk -> { - if (tk.type == Token.Type.TOKGROUP || 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 { @@ -342,7 +348,7 @@ public class DiceLangEngine { } }); - if (debugMode && !postfixMode) { + if(debugMode && !postfixMode) { String msg = String.format("\tCommand after re-preshunting: %s\n", readyTokens.toString()); LOG.fine(msg); System.out.print(msg); @@ -357,7 +363,7 @@ public class DiceLangEngine { * These are things like (, {, and [ */ private Token reverseToken(final Token tk) { - switch (tk.type) { + switch(tk.type) { case OBRACE: return new Token(CBRACE, tk.intValue); case OPAREN: @@ -378,7 +384,7 @@ public class DiceLangEngine { /* Preprocess a command into a list of string tokens. */ private IList<String> preprocessCommand(final String command) { /* Sort the defines if they aren't sorted */ - if (!defnsSorted) { + if(!defnsSorted) { sortDefns(); } @@ -386,24 +392,24 @@ public class DiceLangEngine { final IList<String> streamToks = new FunctionalList<>(); final boolean succ = streamEng.doStreams(command.split(" "), streamToks); - if (!succ) { + if(!succ) { return null; } String newComm = ListUtils.collapseTokens(streamToks, " "); - if (debugMode) { + if(debugMode) { String msg = String.format("\tCommand after stream commands: %s\n", newComm); LOG.fine(msg); System.out.print(msg); } /* Apply line defns */ - for (final Define dfn : lineDefns.toIterable()) { + for(final Define dfn : lineDefns.toIterable()) { newComm = dfn.apply(newComm); } - if (debugMode) { + if(debugMode) { String msg = String.format("\tCommand after line defines: %s\n", newComm); LOG.fine(msg); System.out.print(msg); @@ -413,21 +419,23 @@ public class DiceLangEngine { final List<String> destringedParts = TokenUtils.removeDQuotedStrings(newComm); final StringBuffer destringedCommand = new StringBuffer(); - for (final String part : destringedParts) { + for(final String part : destringedParts) { /* Handle string literals */ - if (part.startsWith("\"") && part.endsWith("\"")) { + if(part.startsWith("\"") && part.endsWith("\"")) { /* Get the actual string. */ final String litName = "stringLiteral" + nextLiteral; final String litVal = part.substring(1, part.length() - 1); /* - * Insert the string with its escape sequences interpreted. + * Insert the string with its escape sequences + * interpreted. */ 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)); + if(debugMode) + LOG.finer(String.format("Replaced string literal '%s' with literal no. %d", + descVal, nextLiteral)); nextLiteral += 1; @@ -438,13 +446,13 @@ public class DiceLangEngine { } } - if (debugMode) { + if(debugMode) { String msg = String.format("\tCommand after destringing: %s\n", destringedCommand); LOG.fine(msg); System.out.print(msg); /* Print the string table if it exists. */ - if (stringLiterals.size() > 0) { + if(stringLiterals.size() > 0) { System.out.println("\tString literals in table"); stringLiterals.forEach((key, val) -> { @@ -462,18 +470,19 @@ public class DiceLangEngine { tokens = tokens.map(tk -> { final Matcher nonExpandMatcher = nonExpandPattern.matcher(tk); - if (nonExpandMatcher.matches()) { + if(nonExpandMatcher.matches()) { 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)); + LOG.finer(String.format("Pulled non-expander '%s' to '%s'", nonExpandMatcher.group(1), + tkName)); return tkName; } return tk; }); - if (debugMode) { + if(debugMode) { String msg = String.format("\tCommand after removal of non-expanders: %s\n", tokens.toString()); LOG.fine(msg); System.out.print(msg); @@ -482,21 +491,21 @@ public class DiceLangEngine { /* Expand tokens */ IList<String> fullyExpandedTokens = tokens.flatMap(opExpander::split); - if (debugMode) { - String msg = String.format("\tCommand after token expansion: %s\n", 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 */ fullyExpandedTokens = fullyExpandedTokens.map(tk -> { - if (tk.startsWith("nonExpandToken")) - return nonExpandedTokens.get(tk); + if(tk.startsWith("nonExpandToken")) return nonExpandedTokens.get(tk); return tk; }); - if (debugMode) { + if(debugMode) { String msg = String.format("\tCommand after non-expander reinsertion: %s\n", fullyExpandedTokens.toString()); LOG.fine(msg); @@ -510,25 +519,26 @@ public class DiceLangEngine { private void evaluateForest(final IList<ITree<Node>> astForest) { int treeNo = 1; - for (final ITree<Node> ast : astForest) { - if (debugMode) { + for(final ITree<Node> ast : astForest) { + if(debugMode) { System.out.printf("\t\tTree %d in forest:\n%s\n", treeNo, ast.toString()); } - if (debugMode && stepEval) { + if(debugMode && stepEval) { /* - * @NOTE This is broken until stepwise top-down tree transforms are fixed. + * @NOTE This is broken until stepwise top-down + * tree transforms are fixed. */ int step = 1; /* Evaluate it step by step */ - for (final Iterator<ITree<Node>> itr = eval.stepDebug(ast); itr.hasNext();) { + 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 */ - if (nodeStep == null) { + if(nodeStep == null) { System.out.println(); step += 1; @@ -536,18 +546,18 @@ public class DiceLangEngine { } /* Print out details for results */ - if (nodeStep.getHead().type == Node.Type.RESULT) { + if(nodeStep.getHead().type == Node.Type.RESULT) { final EvaluatorResult res = nodeStep.getHead().resultVal; System.out.printf(" (result is %s", res); - if (res.type == EvaluatorResult.Type.DICE) { + if(res.type == EvaluatorResult.Type.DICE) { String value = ((DiceEvaluatorResult) res).diceVal.value(); System.out.printf(" (sample roll %s)", value); } - if (res.type == EvaluatorResult.Type.FAILURE) { + if(res.type == EvaluatorResult.Type.FAILURE) { ITree<Node> otree = ((FailureEvaluatorResult) res).origVal; System.out.printf(" (original tree is %s)", otree); @@ -564,10 +574,10 @@ public class DiceLangEngine { /* Evaluate it normally */ final EvaluatorResult res = eval.evaluate(ast); - if (debugMode) { + if(debugMode) { System.out.printf("\t\tEvaluates to %s", res); - if (res.type == EvaluatorResult.Type.DICE) { + if(res.type == EvaluatorResult.Type.DICE) { String value = ((DiceEvaluatorResult) res).diceVal.value(); System.out.println("\t\t (sample roll " + value + ")"); @@ -590,24 +600,26 @@ public class DiceLangEngine { 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) { + for(final Token tk : lexedTokens) { + if(tk.type == Token.Type.OBRACE && tk.intValue == 2) { /* Open a preshunt group. */ curBraceCount += 1; - if (curBraceCount != 1) { + if(curBraceCount != 1) { /* - * Push the old group onto the group stack. + * Push the old group onto the group + * stack. */ bracedTokens.push(curBracedTokens); } curBracedTokens = new FunctionalList<>(); - } else if (tk.type == Token.Type.CBRACE && tk.intValue == 2) { + } else if(tk.type == Token.Type.CBRACE && tk.intValue == 2) { /* Close a preshunt group. */ - if (curBraceCount == 0) { + if(curBraceCount == 0) { /* - * Error if there couldn't have been an opening. + * Error if there couldn't have been an + * opening. */ Errors.inst.printError(EK_ENG_NOOPENING); return false; @@ -620,32 +632,36 @@ public class DiceLangEngine { /* Shunt preshunt group. */ final boolean success = shunt.shuntTokens(curBracedTokens, preshuntTokens); - if (debugMode) { - System.out.println("\t\tPreshunted " + curBracedTokens + " into " + preshuntTokens); + if(debugMode) { + System.out.println("\t\tPreshunted " + curBracedTokens + " into " + + preshuntTokens); } - if (!success) { + if(!success) { return false; } - if (curBraceCount >= 1) { + if(curBraceCount >= 1) { /* - * Add the preshunt group to the previous group. + * Add the preshunt group to the + * previous group. */ curBracedTokens = bracedTokens.pop(); curBracedTokens.add(new Token(Token.Type.TOKGROUP, preshuntTokens)); } else { /* - * Add the preshunt group to the token stream. + * Add the preshunt group to the token + * stream. */ preparedTokens.add(new Token(Token.Type.TOKGROUP, preshuntTokens)); } } else { /* - * Add the token to the active preshunt group, if there is one.. + * Add the token to the active preshunt group, + * if there is one.. */ - if (curBraceCount >= 1) { + if(curBraceCount >= 1) { curBracedTokens.add(tk); } else { preparedTokens.add(tk); @@ -653,7 +669,7 @@ public class DiceLangEngine { } } - if (curBraceCount > 0) { + if(curBraceCount > 0) { /* There was an unclosed group. */ Errors.inst.printError(EK_ENG_NOCLOSING); return false; @@ -671,8 +687,8 @@ public class DiceLangEngine { /* * @NOTE * - * The string literal table should be abstracted into some kind of auto-numbered - * map thing. + * The string literal table should be abstracted into some kind of + * auto-numbered map thing. */ void addStringLiteral(final int key, final String val) { stringLits.put(key, val); |
