summaryrefslogtreecommitdiff
path: root/dice-lang/src
diff options
context:
space:
mode:
Diffstat (limited to 'dice-lang/src')
-rw-r--r--dice-lang/src/bjc/dicelang/CLIArgsParser.java42
-rw-r--r--dice-lang/src/bjc/dicelang/CompilerTweaker.java4
-rw-r--r--dice-lang/src/bjc/dicelang/Define.java23
-rw-r--r--dice-lang/src/bjc/dicelang/DiceLangConsole.java72
-rw-r--r--dice-lang/src/bjc/dicelang/DiceLangEngine.java30
-rw-r--r--dice-lang/src/bjc/dicelang/Errors.java82
-rw-r--r--dice-lang/src/bjc/dicelang/Evaluator.java91
-rw-r--r--dice-lang/src/bjc/dicelang/EvaluatorResult.java13
-rw-r--r--dice-lang/src/bjc/dicelang/Node.java13
-rw-r--r--dice-lang/src/bjc/dicelang/Parser.java22
-rw-r--r--dice-lang/src/bjc/dicelang/Shunter.java21
-rw-r--r--dice-lang/src/bjc/dicelang/Token.java6
-rw-r--r--dice-lang/src/bjc/dicelang/Tokenizer.java16
-rw-r--r--dice-lang/src/bjc/dicelang/dice/CompoundDie.java4
-rw-r--r--dice-lang/src/bjc/dicelang/dice/CompoundingDie.java4
-rw-r--r--dice-lang/src/bjc/dicelang/dice/DiceBox.java53
-rw-r--r--dice-lang/src/bjc/dicelang/dice/DieExpression.java4
-rw-r--r--dice-lang/src/bjc/dicelang/dice/ExplodingDice.java14
-rw-r--r--dice-lang/src/bjc/dicelang/dice/MathDie.java10
-rw-r--r--dice-lang/src/bjc/dicelang/dice/SimpleDie.java4
-rw-r--r--dice-lang/src/bjc/dicelang/dice/SimpleDieList.java4
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Parser.java9
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Shunter.java1
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Token.java7
-rw-r--r--dice-lang/src/bjc/dicelang/expr/TokenType.java4
-rw-r--r--dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java65
-rw-r--r--dice-lang/src/bjc/dicelang/scl/StreamEngine.java20
27 files changed, 503 insertions, 135 deletions
diff --git a/dice-lang/src/bjc/dicelang/CLIArgsParser.java b/dice-lang/src/bjc/dicelang/CLIArgsParser.java
index e324e67..7f21b63 100644
--- a/dice-lang/src/bjc/dicelang/CLIArgsParser.java
+++ b/dice-lang/src/bjc/dicelang/CLIArgsParser.java
@@ -51,64 +51,87 @@ public class CLIArgsParser {
if (!eng.toggleDebug()) {
eng.toggleDebug();
}
+
break;
+
case "-nd":
case "--no-debug":
if (eng.toggleDebug()) {
eng.toggleDebug();
}
+
break;
+
case "-po":
case "--postfix":
if (!eng.togglePostfix()) {
eng.togglePostfix();
}
+
break;
+
case "-npo":
case "--no-postfix":
if (eng.togglePostfix()) {
eng.togglePostfix();
}
+
break;
+
case "-pr":
case "--prefix":
if (!eng.togglePrefix()) {
eng.togglePrefix();
}
+
break;
+
case "-npr":
case "--no-prefix":
if (eng.togglePrefix()) {
eng.togglePrefix();
}
+
break;
+
case "-se":
case "--stepeval":
if (!eng.toggleStepEval()) {
eng.toggleStepEval();
}
+
break;
+
case "-nse":
case "--no-stepeval":
if (eng.toggleStepEval()) {
eng.toggleStepEval();
}
+
break;
+
case "-D":
case "--define":
i = simpleDefine(i, args, eng);
+
if (i == -1) return false;
+
break;
+
case "-df":
case "--define-file":
i = defineFile(i, args, eng);
+
if (i == -1) return false;
+
break;
+
case "-ctf":
case "--compiler-tweak-file":
- /*
- * @TODO not yet implemented
- */
+
+ /*
+ * @TODO not yet implemented
+ */
default:
Errors.inst.printError(EK_CLI_UNARG, arg);
return false;
@@ -118,14 +141,16 @@ public class CLIArgsParser {
return true;
}
- private static int simpleDefine(final int i, final String[] args, final DiceLangEngine eng) {
+ private static int simpleDefine(final int i, final String[] args,
+ final DiceLangEngine eng) {
if (i >= args.length - 1) {
Errors.inst.printError(EK_CLI_MISARG, "define");
return -1;
}
if (i >= args.length - 2) {
- final Define dfn = new Define(5, false, false, false, null, args[i + 1], Arrays.asList(""));
+ final Define dfn = new Define(5, false, false, false, null, args[i + 1],
+ Arrays.asList(""));
if (dfn.inError) return -1;
@@ -133,7 +158,8 @@ public class CLIArgsParser {
return i + 1;
}
- final Define dfn = new Define(5, false, false, false, null, args[i + 1], Arrays.asList(args[i + 2]));
+ final Define dfn = new Define(5, false, false, false, null, args[i + 1],
+ Arrays.asList(args[i + 2]));
if (dfn.inError) return -1;
@@ -141,7 +167,8 @@ public class CLIArgsParser {
return i + 2;
}
- private static int defineFile(final int i, final String[] args, final DiceLangEngine eng) {
+ private static int defineFile(final int i, final String[] args,
+ final DiceLangEngine eng) {
if (i >= args.length - 1) {
Errors.inst.printError(EK_CLI_MISARG, "define-file");
return -1;
@@ -155,6 +182,7 @@ public class CLIArgsParser {
final String ln = scan.nextLine();
final Define dfn = parseDefine(ln.substring(ln.indexOf(' ')));
+
if (dfn == null || dfn.inError) return -1;
if (ln.startsWith("line")) {
diff --git a/dice-lang/src/bjc/dicelang/CompilerTweaker.java b/dice-lang/src/bjc/dicelang/CompilerTweaker.java
index 68c50dd..bb5cbde 100644
--- a/dice-lang/src/bjc/dicelang/CompilerTweaker.java
+++ b/dice-lang/src/bjc/dicelang/CompilerTweaker.java
@@ -11,8 +11,8 @@ public class CompilerTweaker {
/*
* Bits of the compiler necessary
*/
- private final DiceLangEngine eng;
- private final ConfigurableTokenSplitter opExpander;
+ private final DiceLangEngine eng;
+ private final ConfigurableTokenSplitter opExpander;
/**
* Create a new compiler tweaker.
diff --git a/dice-lang/src/bjc/dicelang/Define.java b/dice-lang/src/bjc/dicelang/Define.java
index 94708fd..a008e0c 100644
--- a/dice-lang/src/bjc/dicelang/Define.java
+++ b/dice-lang/src/bjc/dicelang/Define.java
@@ -44,20 +44,20 @@ public class Define implements UnaryOperator<String>, Comparable<Define> {
/**
* The priority of this definition.
*/
- public final int priority;
+ public final int priority;
/**
* Whether or not this definition is in error.
*/
- public final boolean inError;
+ public final boolean inError;
- private boolean doRecur;
- private boolean subType;
+ private boolean doRecur;
+ private boolean subType;
- private Pattern predicate;
- private Pattern searcher;
+ private Pattern predicate;
+ private Pattern searcher;
- private Iterator<String> replacers;
- private String replacer;
+ private Iterator<String> replacers;
+ private String replacer;
/**
* Create a new define.
@@ -83,8 +83,9 @@ public class Define implements UnaryOperator<String>, Comparable<Define> {
* @param replacrs
* The source for replacement strings.
*/
- public Define(final int priorty, final boolean isSub, final boolean recur, final boolean isCircular,
- final String predicte, final String searchr, final Iterable<String> replacrs) {
+ public Define(final int priorty, final boolean isSub, final boolean recur,
+ final boolean isCircular,
+ final String predicte, final String searchr, final Iterable<String> replacrs) {
priority = priorty;
doRecur = recur;
subType = isSub;
@@ -114,6 +115,7 @@ public class Define implements UnaryOperator<String>, Comparable<Define> {
}
inError = false;
+
/*
* Check whether or not we do sub-replacements
*/
@@ -170,6 +172,7 @@ public class Define implements UnaryOperator<String>, Comparable<Define> {
if (subType) {
final StringBuffer sb = new StringBuffer();
+
while (searcherMatcher.find()) {
if (replacers == null) {
searcherMatcher.appendReplacement(sb, "");
diff --git a/dice-lang/src/bjc/dicelang/DiceLangConsole.java b/dice-lang/src/bjc/dicelang/DiceLangConsole.java
index e06cccb..bbf3db8 100644
--- a/dice-lang/src/bjc/dicelang/DiceLangConsole.java
+++ b/dice-lang/src/bjc/dicelang/DiceLangConsole.java
@@ -47,6 +47,9 @@ public class DiceLangConsole {
* Run the console.
*/
public void run() {
+ /*
+ * Set up console.
+ */
try {
read = new ConsoleReader();
} catch (final IOException ioex) {
@@ -58,6 +61,9 @@ public class DiceLangConsole {
String comm = null;
+ /*
+ * Read initial command.
+ */
try {
comm = read.readLine(String.format("(%d) dice-lang> ", commandNumber));
} catch (final IOException ioex) {
@@ -65,9 +71,15 @@ public class DiceLangConsole {
return;
}
+ /*
+ * Run commands.
+ */
while (!comm.equals("quit") && !comm.equals("exit")) {
if (comm.startsWith("pragma")) {
- final boolean success = handlePragma(comm.substring(7));
+ /*
+ * Run pragmas.
+ */
+ final boolean success = handlePragma(comm.substring(7));
if (success) {
System.out.println("Pragma completed succesfully");
@@ -75,7 +87,11 @@ public class DiceLangConsole {
System.out.println("Pragma execution failed");
}
} else {
- System.out.printf("\tRaw command: %s\n", comm);
+ /*
+ * Run commands.
+ */
+ if(eng.debugMode)
+ System.out.printf("\tRaw command: %s\n", comm);
final boolean success = eng.runCommand(comm);
@@ -98,33 +114,50 @@ public class DiceLangConsole {
}
private boolean handlePragma(final String pragma) {
- System.out.println("\tRaw pragma: " + pragma);
+ if(eng.debugMode)
+ System.out.println("\tRaw pragma: " + pragma);
+ /*
+ * Grab the name from the arguments.
+ */
String pragmaName = null;
final int firstIndex = pragma.indexOf(' ');
+
+ /*
+ * Handle argless pragmas.
+ */
if (firstIndex == -1) {
pragmaName = pragma;
} else {
pragmaName = pragma.substring(0, firstIndex);
}
+ /*
+ * Run pragmas.
+ */
switch (pragmaName) {
case "debug":
System.out.println("\tDebug mode is now " + eng.toggleDebug());
break;
+
case "postfix":
System.out.println("\tPostfix mode is now " + eng.togglePostfix());
break;
+
case "prefix":
System.out.println("\tPrefix mode is now " + eng.togglePrefix());
break;
+
case "stepeval":
System.out.println("\tStepeval mode is now" + eng.toggleStepEval());
break;
+
case "define":
return defineMode(pragma.substring(7));
+
case "help":
return helpMode(pragma.substring(5));
+
default:
Errors.inst.printError(EK_CONS_INVPRAG, pragma);
return false;
@@ -133,27 +166,36 @@ public class DiceLangConsole {
return true;
}
+ /*
+ * Run a help mode.
+ */
private static boolean helpMode(final String pragma) {
switch (pragma.trim()) {
case "help":
System.out.println("\tGet help on pragmas");
break;
+
case "debug":
System.out.println("\tToggle debug mode. (Output stage results)");
break;
+
case "postfix":
System.out.println("\tToggle postfix mode. (Don't shunt tokens)");
break;
+
case "prefix":
System.out.println("\tToggle prefix mode. (Reverse token order instead of shunting)");
break;
+
case "stepeval":
System.out.println("\tToggle stepeval mode. (Print out evaluation progress)");
break;
+
case "define":
System.out.println("\tAdd a macro rewrite directive.");
System.out.println("\tdefine <priority> <type> <recursion> <guard> <circular> <patterns>...");
break;
+
default:
System.out.println("\tNo help available for pragma " + pragma);
}
@@ -175,6 +217,9 @@ public class DiceLangConsole {
private final Pattern slashPattern = Pattern.compile("/((?:\\\\.|[^/\\\\])*)/");
private boolean defineMode(final String defineText) {
+ /*
+ * Grab all of the separator spaces.
+ */
final int firstIndex = defineText.indexOf(' ');
final int secondIndex = defineText.indexOf(' ', firstIndex + 1);
final int thirdIndex = defineText.indexOf(' ', secondIndex + 1);
@@ -182,6 +227,9 @@ public class DiceLangConsole {
final int fifthIndex = defineText.indexOf(' ', fourthIndex + 1);
final int sixthIndex = defineText.indexOf(' ', fifthIndex + 1);
+ /*
+ * Error if we got something we didn't need.
+ */
if (firstIndex == -1) {
Errors.inst.printError(EK_CONS_INVDEFINE, "(no priority)");
return false;
@@ -213,25 +261,32 @@ public class DiceLangConsole {
case "line":
type = Define.Type.LINE;
break;
+
case "token":
type = Define.Type.TOKEN;
break;
+
case "subline":
type = Define.Type.LINE;
subMode = true;
break;
+
case "subtoken":
type = Define.Type.TOKEN;
subMode = true;
break;
+
default:
Errors.inst.printError(EK_CONS_INVDEFINE, "(unknown type)");
return false;
}
- final boolean doRecur = defineText.substring(secondIndex + 1, thirdIndex).equalsIgnoreCase("true");
- final boolean hasGuard = defineText.substring(thirdIndex + 1, fourthIndex).equalsIgnoreCase("true");
- final boolean isCircular = defineText.substring(thirdIndex + 1, fourthIndex).equalsIgnoreCase("true");
+ final boolean doRecur = defineText.substring(secondIndex + 1,
+ thirdIndex).equalsIgnoreCase("true");
+ final boolean hasGuard = defineText.substring(thirdIndex + 1,
+ fourthIndex).equalsIgnoreCase("true");
+ final boolean isCircular = defineText.substring(thirdIndex + 1,
+ fourthIndex).equalsIgnoreCase("true");
final String pats = defineText.substring(fifthIndex + 1).trim();
final Matcher patMatcher = slashPattern.matcher(pats);
@@ -259,8 +314,9 @@ public class DiceLangConsole {
replacePatterns.add(patMatcher.group(1));
}
- final Define dfn = new Define(priority, subMode, doRecur, isCircular, guardPattern, searchPattern,
- replacePatterns);
+ final Define dfn = new Define(priority, subMode, doRecur, isCircular, guardPattern,
+ searchPattern,
+ replacePatterns);
if (dfn.inError) return false;
diff --git a/dice-lang/src/bjc/dicelang/DiceLangEngine.java b/dice-lang/src/bjc/dicelang/DiceLangEngine.java
index 7736db4..0ac088e 100644
--- a/dice-lang/src/bjc/dicelang/DiceLangEngine.java
+++ b/dice-lang/src/bjc/dicelang/DiceLangEngine.java
@@ -33,6 +33,8 @@ import bjc.utils.parserutils.splitter.ConfigurableTokenSplitter;
* @author Ben Culkin
*/
public class DiceLangEngine {
+ public boolean debug = true;
+
/*
* 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
@@ -52,7 +54,7 @@ public class DiceLangEngine {
/*
* Debug indicator.
*/
- private boolean debugMode;
+ public boolean debugMode;
/*
* Should we do shunting?
*/
@@ -91,14 +93,14 @@ public class DiceLangEngine {
*/
public final IMap<Integer, String> symTable;
- private final IMap<Integer, String> stringLits;
- private final IMap<String, String> stringLiterals;
+ private final IMap<Integer, String> stringLits;
+ private final IMap<String, String> stringLiterals;
/*
* Lists of defns.
*/
- private final IList<Define> lineDefns;
- private final IList<Define> tokenDefns;
+ private final IList<Define> lineDefns;
+ private final IList<Define> tokenDefns;
/*
* Are defns sorted by priority?
@@ -252,7 +254,8 @@ public class DiceLangEngine {
/*
* Matches double-angle bracketed strings.
*/
- private final Pattern nonExpandPattern = Pattern.compile("<<([^\\>]*(?:\\>(?:[^\\>])*)*)>>");
+ private final Pattern nonExpandPattern =
+ Pattern.compile("<<([^\\>]*(?:\\>(?:[^\\>])*)*)>>");
/**
* Run a command to completion.
@@ -394,16 +397,22 @@ 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;
}
@@ -537,7 +546,7 @@ public class DiceLangEngine {
if (debugMode) {
System.out.printf("\tCommand after non-expander reinsertion: %s\n",
- fullyExpandedTokens.toString());
+ fullyExpandedTokens.toString());
}
return fullyExpandedTokens;
@@ -625,7 +634,8 @@ public class DiceLangEngine {
/*
* Preshunt preshunt-marked groups of tokens.
*/
- private boolean removePreshuntTokens(final IList<Token> lexedTokens, final IList<Token> preparedTokens) {
+ private boolean removePreshuntTokens(final IList<Token> lexedTokens,
+ final IList<Token> preparedTokens) {
/*
* Current nesting level of tokens.
*/
@@ -677,7 +687,7 @@ public class DiceLangEngine {
if (debugMode) {
System.out.println("\t\tPreshunted " + curBracedTokens + " into "
- + preshuntTokens);
+ + preshuntTokens);
}
if (!success) return false;
@@ -728,4 +738,4 @@ public class DiceLangEngine {
void addStringLiteral(final int key, final String val) {
stringLits.put(key, val);
}
-} \ No newline at end of file
+}
diff --git a/dice-lang/src/bjc/dicelang/Errors.java b/dice-lang/src/bjc/dicelang/Errors.java
index f5ced44..31d57b5 100644
--- a/dice-lang/src/bjc/dicelang/Errors.java
+++ b/dice-lang/src/bjc/dicelang/Errors.java
@@ -277,10 +277,13 @@ public class Errors {
} else {
System.out.println("\t? " + key.ordinal());
}
+
break;
+
case DEV:
devError(key, args);
break;
+
default:
System.out.println("\tERROR ERROR: Unknown error mode " + mode);
}
@@ -291,158 +294,209 @@ public class Errors {
case EK_DFN_PREDSYN:
System.out.printf("\tERROR: Incorrect define guard syntax %s\n", args[0]);
break;
+
case EK_DFN_SRCSYN:
System.out.printf("\tERROR: Incorrect define match syntax %s\n", args[0]);
break;
+
case EK_DFN_RECUR:
System.out.printf(
- "\tERROR: Recursive define didn't converge after %s iterations."
- + " Original string was %s, last iteration was %s\n",
- args[0], args[1], args[2]);
+ "\tERROR: Recursive define didn't converge after %s iterations."
+ + " Original string was %s, last iteration was %s\n",
+ args[0], args[1], args[2]);
break;
+
case EK_CONS_INVPRAG:
System.out.printf("\tERROR: Unknown pragma %s\n", args[0]);
break;
+
case EK_CONS_INVDEFINE:
System.out.printf("\tERROR: Improperly formatted define %s\n", args[0]);
break;
+
case EK_ENG_NOOPENING:
System.out.printf("\tERROR: Encountered closing doublebrace without"
- + " matching opening doublebrace\n");
+ + " matching opening doublebrace\n");
break;
+
case EK_ENG_NOCLOSING:
System.out.printf("\tERROR: Reached end of string before closing doublebrace was found\n");
break;
+
case EK_TOK_UNGROUP:
System.out.printf("\tERROR: Unrecognized grouping token %s\n", args[0]);
break;
+
case EK_TOK_INVBASE:
System.out.printf("\tERROR: Invalid flexadecimal base %s\n", args[0]);
break;
+
case EK_TOK_INVFLEX:
- System.out.printf("\tERROR: Invalid flexadecimal number %s in base %s\n", args[0], args[1]);
+ System.out.printf("\tERROR: Invalid flexadecimal number %s in base %s\n", args[0],
+ args[1]);
break;
+
case EK_EVAL_INVNODE:
System.out.printf("\tERROR: Unknown node in evaluator: %s\n", args[0]);
break;
+
case EK_EVAL_INVBIN:
System.out.printf("\tERROR: Binary operators take 2 operands, not %s\n"
- + "\tProblem node is %s\n", args[0], args[1]);
+ + "\tProblem node is %s\n", args[0], args[1]);
break;
+
case EK_EVAL_UNBIN:
System.out.printf("\tERROR: Unknown binary operator %s\n", args[0]);
break;
+
case EK_EVAL_STRINGMATH:
System.out.printf("\tERROR: Math operators don't work on strings\n");
break;
+
case EK_EVAL_DIVZERO:
System.out.printf("\tERROR: Attempted divide by zero\n");
break;
+
case EK_EVAL_DIVDICE:
System.out.printf("\tERROR: Dice cannot be divided\n");
break;
+
case EK_EVAL_UNMATH:
System.out.printf("\tERROR: Unknown math binary operator: %s\n", args[0]);
break;
+
case EK_EVAL_UNTOK:
System.out.printf("\tERROR: Unknown token ref %s\n", args[0]);
break;
+
case EK_EVAL_UNDICE:
System.out.printf("\tERROR: Unknown dice operator %s\n", args[0]);
break;
+
case EK_EVAL_INVDCREATE:
- System.out.printf("\tERROR: Dice creation operator expects integers," + " not %s\n", args[0]);
+ System.out.printf("\tERROR: Dice creation operator expects integers," + " not %s\n",
+ args[0]);
break;
+
case EK_EVAL_INVDGROUP:
- System.out.printf("\tERROR: Dice group operator expects scalar dice or integers," + " not %s\n",
- args[0]);
+ System.out.printf("\tERROR: Dice group operator expects scalar dice or integers," +
+ " not %s\n",
+ args[0]);
break;
+
case EK_EVAL_INVDICE:
System.out.printf("\tERROR: Dice operators expect scalar dice, not %s\n", args[0]);
break;
+
case EK_EVAL_MISMATH:
System.out.printf("\tERROR: Math operators expect two operands of the same type\n");
break;
+
case EK_EVAL_INVSTRING:
System.out.printf("\tERROR: Incorrect type %s to string operator\n", args[0]);
break;
+
case EK_EVAL_UNSTRING:
System.out.printf("\tERROR: Unknown string operator %s\n", args[0]);
break;
+
case EK_PARSE_NOCLOSE:
System.out.printf("\tERROR: Group closing with no possible group opener\n");
break;
+
case EK_PARSE_UNCLOSE:
System.out.printf("\tERROR: Found group closer without opener: (closing was %s"
- + ", expected %s)\n", args[0], args[1]);
+ + ", expected %s)\n", args[0], args[1]);
break;
+
case EK_PARSE_BINARY:
System.out.printf("\tERROR: Expected at least two operands\n");
break;
+
case EK_PARSE_UNOPERAND:
System.out.printf("\tERROR: Operator %s expected more operands than provided\n", args[0]);
break;
+
case EK_PARSE_INVTOKEN:
System.out.printf("\tERROR: Unrecognized token type in parsing: %s\n", args[0]);
break;
+
case EK_SHUNT_NOTADV:
System.out.printf("\tERROR: Unary operator %s is an adjective, not an adverb. It can't be"
- + " applied to the operator %s\n", args[0], args[1]);
+ + " applied to the operator %s\n", args[0], args[1]);
break;
+
case EK_SHUNT_NOTADJ:
System.out.printf("\tERROR: Unary operator %s is an adjective, not an adverb. It can't be"
- + " applied to the operator %s\n", args[0], args[1]);
+ + " applied to the operator %s\n", args[0], args[1]);
break;
+
case EK_SHUNT_NOOP:
System.out.printf("\tERROR: Unary operator %s is an adverb, but there is no operator"
- + " to apply it to\n", args[0]);
+ + " to apply it to\n", args[0]);
break;
+
case EK_SHUNT_NOGROUP:
System.out.printf("\tERROR: Couldn't find matching grouping %s (expected %s)\n", args[0],
- args[1]);
+ args[1]);
break;
+
case EK_SHUNT_NOTASSOC:
System.out.printf("\tERROR: Attempted to chain non-associative operator %s\n", args[0]);
break;
+
case EK_SHUNT_INVSEP:
System.out.printf("\tERROR: Couldn't find grouper for group seperator to attach to\n");
break;
+
case EK_STRM_NONEX:
System.out.printf("\tERROR: Attempted to switch to non-existent stream\n");
break;
+
case EK_STRM_LAST:
System.out.printf("\tERROR: Cannot delete last stream\n");
break;
+
case EK_STRM_INVCOM:
System.out.printf("\tERROR: Unknown stream control command %s\n", args[0]);
break;
+
case EK_SCL_INVTOKEN:
System.out.printf("\tERROR: Unknown SCL token %s\n", args[0]);
break;
+
case EK_SCL_MMQUOTE:
System.out.printf("\tERROR: Mismatched delimiter in SCL command\n");
break;
+
case EK_SCL_SUNDERFLOW:
System.out.printf("\tERROR: Not enough items in stack for word %s\n", args[0]);
break;
+
case EK_SCL_UNWORD:
System.out.printf("\tERROR: Unknown word %s\n", args[0]);
break;
+
case EK_CLI_UNARG:
System.out.printf("\tERROR: Unknown argument %s\n", args[0]);
break;
+
case EK_CLI_MISARG:
System.out.printf("\tERROR: Missing subargument to command %s", args[0]);
break;
+
case EK_CLI_INVDFNTYPE:
System.out.printf("\tERROR: Invalid define type %s\n", args[0]);
break;
+
case EK_MISC_IOEX:
System.out.printf("\tERROR: I/O problem with file\n");
break;
+
case EK_MISC_NOFILE:
System.out.printf("\tERROR: No such file %s\n", args[0]);
break;
+
default:
System.out.printf("\tERROR ERROR: Unknown error key %s\n", key);
}
diff --git a/dice-lang/src/bjc/dicelang/Evaluator.java b/dice-lang/src/bjc/dicelang/Evaluator.java
index 5260bab..b1a1ebd 100644
--- a/dice-lang/src/bjc/dicelang/Evaluator.java
+++ b/dice-lang/src/bjc/dicelang/Evaluator.java
@@ -74,7 +74,8 @@ public class Evaluator {
}
private static Node FAIL(final EvaluatorResult res) {
- return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE, new Node(Node.Type.RESULT, res)));
+ return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE, new Node(Node.Type.RESULT,
+ res)));
}
private final DiceLangEngine eng;
@@ -114,7 +115,7 @@ public class Evaluator {
};
final ITree<Node> res = comm.topDownTransform(this::pickEvaluationType,
- node -> this.evaluateNode(node, ctx));
+ node -> this.evaluateNode(node, ctx));
return res.getHead().resultVal;
}
@@ -139,9 +140,11 @@ public class Evaluator {
switch (nd.operatorType) {
case COERCE:
return TopDownTransformResult.RTRANSFORM;
+
default:
return TopDownTransformResult.PUSHDOWN;
}
+
default:
return TopDownTransformResult.PUSHDOWN;
}
@@ -151,14 +154,19 @@ public class Evaluator {
switch (ast.getHead().type) {
case UNARYOP:
return evaluateUnaryOp(ast, ctx);
+
case BINOP:
return evaluateBinaryOp(ast, ctx);
+
case TOKREF:
return evaluateTokenRef(ast.getHead().tokenVal, ctx);
+
case ROOT:
return ast.getChild(ast.getChildrenCount() - 1);
+
case RESULT:
return ast;
+
default:
Errors.inst.printError(EK_EVAL_INVNODE, ast.getHead().type.toString());
return new Tree<>(FAIL(ast));
@@ -222,6 +230,7 @@ public class Evaluator {
if (curLevel == CoerceSteps.DOUBLE) {
nd.resultVal = new EvaluatorResult(FLOAT, (double) res.intVal);
}
+
default:
/*
* Do nothing
@@ -233,6 +242,7 @@ public class Evaluator {
}
return retVal;
+
case DICESCALAR:
final EvaluatorResult opr = ast.getChild(0).getHead().resultVal;
@@ -241,7 +251,8 @@ public class Evaluator {
}
return new Tree<>(new Node(Node.Type.RESULT,
- new EvaluatorResult(DICE, new ScalarDie(opr.intVal))));
+ new EvaluatorResult(DICE, new ScalarDie(opr.intVal))));
+
case DICEFUDGE:
final EvaluatorResult oprn = ast.getChild(0).getHead().resultVal;
@@ -250,7 +261,8 @@ public class Evaluator {
}
return new Tree<>(new Node(Node.Type.RESULT,
- new EvaluatorResult(DICE, new FudgeDie(oprn.intVal))));
+ new EvaluatorResult(DICE, new FudgeDie(oprn.intVal))));
+
default:
Errors.inst.printError(EK_EVAL_INVUNARY, ast.getHead().operatorType.toString());
return new Tree<>(FAIL(ast));
@@ -262,7 +274,7 @@ public class Evaluator {
if (ast.getChildrenCount() != 2) {
Errors.inst.printError(EK_EVAL_INVBIN, Integer.toString(ast.getChildrenCount()),
- ast.toString());
+ ast.toString());
return new Tree<>(FAIL(ast));
}
@@ -276,22 +288,29 @@ public class Evaluator {
case MULTIPLY:
case DIVIDE:
case IDIVIDE:
- return evaluateMathBinary(binOp, left.getHead().resultVal, right.getHead().resultVal, ctx);
+ return evaluateMathBinary(binOp, left.getHead().resultVal, right.getHead().resultVal,
+ ctx);
+
case DICEGROUP:
case DICECONCAT:
case DICELIST:
- return evaluateDiceBinary(binOp, left.getHead().resultVal, right.getHead().resultVal, ctx);
+ return evaluateDiceBinary(binOp, left.getHead().resultVal, right.getHead().resultVal,
+ ctx);
+
case STRCAT:
case STRREP:
- return evaluateStringBinary(binOp, left.getHead().resultVal, right.getHead().resultVal, ctx);
+ return evaluateStringBinary(binOp, left.getHead().resultVal, right.getHead().resultVal,
+ ctx);
+
default:
Errors.inst.printError(EK_EVAL_UNBIN, binOp.toString());
return new Tree<>(FAIL(ast));
}
}
- private static ITree<Node> evaluateStringBinary(final Token.Type op, final EvaluatorResult left,
- final EvaluatorResult right, final Context ctx) {
+ private static ITree<Node> evaluateStringBinary(final Token.Type op,
+ final EvaluatorResult left,
+ final EvaluatorResult right, final Context ctx) {
if (left.type != STRING) {
Errors.inst.printError(EK_EVAL_INVSTRING, left.type.toString());
return new Tree<>(FAIL(left));
@@ -307,7 +326,9 @@ public class Evaluator {
}
final String strung = right.stringVal;
- return new Tree<>(new Node(Node.Type.RESULT, new EvaluatorResult(STRING, strang + strung)));
+ return new Tree<>(new Node(Node.Type.RESULT, new EvaluatorResult(STRING,
+ strang + strung)));
+
case STRREP:
if (right.type != INT) {
Errors.inst.printError(EK_EVAL_INVSTRING, right.type.toString());
@@ -316,18 +337,22 @@ public class Evaluator {
String res = strang;
final long count = right.intVal;
+
for (long i = 1; i < count; i++) {
res += strang;
}
+
return new Tree<>(new Node(Node.Type.RESULT, new EvaluatorResult(STRING, res)));
+
default:
Errors.inst.printError(EK_EVAL_UNSTRING, op.toString());
return new Tree<>(FAIL());
}
}
- private static ITree<Node> evaluateDiceBinary(final Token.Type op, final EvaluatorResult left,
- final EvaluatorResult right, final Context ctx) {
+ private static ITree<Node> evaluateDiceBinary(final Token.Type op,
+ final EvaluatorResult left,
+ final EvaluatorResult right, final Context ctx) {
EvaluatorResult res = null;
switch (op) {
@@ -335,10 +360,10 @@ public class Evaluator {
if (left.type == DICE && !left.diceVal.isList) {
if (right.type == DICE && !right.diceVal.isList) {
res = new EvaluatorResult(DICE,
- new SimpleDie(left.diceVal.scalar, right.diceVal.scalar));
+ new SimpleDie(left.diceVal.scalar, right.diceVal.scalar));
} else if (right.type == INT) {
res = new EvaluatorResult(DICE,
- new SimpleDie(left.diceVal.scalar, right.intVal));
+ new SimpleDie(left.diceVal.scalar, right.intVal));
} else {
Errors.inst.printError(EK_EVAL_INVDGROUP, right.type.toString());
return new Tree<>(FAIL(right));
@@ -346,7 +371,7 @@ public class Evaluator {
} else if (left.type == INT) {
if (right.type == DICE && !right.diceVal.isList) {
res = new EvaluatorResult(DICE,
- new SimpleDie(left.intVal, right.diceVal.scalar));
+ new SimpleDie(left.intVal, right.diceVal.scalar));
} else if (right.type == INT) {
res = new EvaluatorResult(DICE, new SimpleDie(left.intVal, right.intVal));
} else {
@@ -357,6 +382,7 @@ public class Evaluator {
Errors.inst.printError(EK_EVAL_INVDGROUP, left.type.toString());
return new Tree<>(FAIL(left));
}
+
case DICECONCAT:
if (left.type != DICE || left.diceVal.isList) {
Errors.inst.printError(EK_EVAL_INVDICE, left.type.toString());
@@ -366,9 +392,11 @@ public class Evaluator {
return new Tree<>(FAIL(right));
} else {
res = new EvaluatorResult(DICE,
- new CompoundDie(left.diceVal.scalar, right.diceVal.scalar));
+ new CompoundDie(left.diceVal.scalar, right.diceVal.scalar));
}
+
break;
+
case DICELIST:
if (left.type != DICE || left.diceVal.isList) {
Errors.inst.printError(EK_EVAL_INVDICE, left.type.toString());
@@ -378,9 +406,11 @@ public class Evaluator {
return new Tree<>(FAIL(right));
} else {
res = new EvaluatorResult(DICE,
- new SimpleDieList(left.diceVal.scalar, right.diceVal.scalar));
+ new SimpleDieList(left.diceVal.scalar, right.diceVal.scalar));
}
+
break;
+
default:
Errors.inst.printError(EK_EVAL_UNDICE, op.toString());
return new Tree<>(FAIL());
@@ -389,8 +419,9 @@ public class Evaluator {
return new Tree<>(new Node(Node.Type.RESULT, res));
}
- private static ITree<Node> evaluateMathBinary(final Token.Type op, final EvaluatorResult left,
- final EvaluatorResult right, final Context ctx) {
+ private static ITree<Node> evaluateMathBinary(final Token.Type op,
+ final EvaluatorResult left,
+ final EvaluatorResult right, final Context ctx) {
if (left.type == STRING || right.type == STRING) {
Errors.inst.printError(EK_EVAL_STRINGMATH);
return new Tree<>(FAIL());
@@ -432,11 +463,13 @@ public class Evaluator {
}
res = new EvaluatorResult(DICE, new MathDie(MathDie.MathOp.ADD, left.diceVal.scalar,
- right.diceVal.scalar));
+ right.diceVal.scalar));
} else {
res = new EvaluatorResult(FLOAT, left.floatVal + right.floatVal);
}
+
break;
+
case SUBTRACT:
if (left.type == INT) {
res = new EvaluatorResult(INT, left.intVal - right.intVal);
@@ -450,11 +483,13 @@ public class Evaluator {
}
res = new EvaluatorResult(DICE, new MathDie(MathDie.MathOp.SUBTRACT,
- left.diceVal.scalar, right.diceVal.scalar));
+ left.diceVal.scalar, right.diceVal.scalar));
} else {
res = new EvaluatorResult(FLOAT, left.floatVal - right.floatVal);
}
+
break;
+
case MULTIPLY:
if (left.type == INT) {
res = new EvaluatorResult(INT, left.intVal * right.intVal);
@@ -468,11 +503,13 @@ public class Evaluator {
}
res = new EvaluatorResult(DICE, new MathDie(MathDie.MathOp.MULTIPLY,
- left.diceVal.scalar, right.diceVal.scalar));
+ left.diceVal.scalar, right.diceVal.scalar));
} else {
res = new EvaluatorResult(FLOAT, left.floatVal * right.floatVal);
}
+
break;
+
case DIVIDE:
if (left.type == INT) {
if (right.intVal == 0) {
@@ -492,7 +529,9 @@ public class Evaluator {
Errors.inst.printError(EK_EVAL_DIVDICE);
return new Tree<>(FAIL());
}
+
break;
+
case IDIVIDE:
if (left.type == INT) {
if (right.intVal == 0) {
@@ -512,7 +551,9 @@ public class Evaluator {
Errors.inst.printError(EK_EVAL_DIVDICE);
return new Tree<>(FAIL());
}
+
break;
+
default:
Errors.inst.printError(EK_EVAL_UNMATH, op.toString());
return new Tree<>(FAIL());
@@ -528,15 +569,19 @@ public class Evaluator {
case INT_LIT:
res = new EvaluatorResult(INT, tk.intValue);
break;
+
case FLOAT_LIT:
res = new EvaluatorResult(FLOAT, tk.floatValue);
break;
+
case DICE_LIT:
res = new EvaluatorResult(DICE, tk.diceValue);
break;
+
case STRING_LIT:
res = new EvaluatorResult(STRING, eng.getStringLiteral((int) tk.intValue));
break;
+
default:
Errors.inst.printError(EK_EVAL_UNTOK, tk.type.toString());
res = new EvaluatorResult(FAILURE);
diff --git a/dice-lang/src/bjc/dicelang/EvaluatorResult.java b/dice-lang/src/bjc/dicelang/EvaluatorResult.java
index d81612f..75bbb3f 100644
--- a/dice-lang/src/bjc/dicelang/EvaluatorResult.java
+++ b/dice-lang/src/bjc/dicelang/EvaluatorResult.java
@@ -52,19 +52,19 @@ public class EvaluatorResult {
/**
* The integer value of the result.
*/
- public long intVal;
+ public long intVal;
/**
* The float value of the result.
*/
- public double floatVal;
+ public double floatVal;
/**
* The dice value of the result.
*/
- public DieExpression diceVal;
+ public DieExpression diceVal;
/**
* The string value of the result.
*/
- public String stringVal;
+ public String stringVal;
/**
* Original node data
@@ -196,14 +196,19 @@ public class EvaluatorResult {
switch (type) {
case INT:
return type.toString() + "(" + intVal + ")";
+
case FLOAT:
return type.toString() + "(" + floatVal + ")";
+
case DICE:
return type.toString() + "(" + diceVal + ")";
+
case STRING:
return type.toString() + "(" + stringVal + ")";
+
case FAILURE:
return type.toString();
+
default:
return "Unknown result type " + type.toString();
}
diff --git a/dice-lang/src/bjc/dicelang/Node.java b/dice-lang/src/bjc/dicelang/Node.java
index af26870..af69c8c 100644
--- a/dice-lang/src/bjc/dicelang/Node.java
+++ b/dice-lang/src/bjc/dicelang/Node.java
@@ -13,10 +13,10 @@ public class Node {
public final Type type;
// These can have or not have values based of the node type
- public Token tokenVal;
- public Token.Type operatorType;
- public GroupType groupType;
- public EvaluatorResult resultVal;
+ public Token tokenVal;
+ public Token.Type operatorType;
+ public GroupType groupType;
+ public EvaluatorResult resultVal;
public Node(final Type typ) {
type = typ;
@@ -52,13 +52,17 @@ public class Node {
case UNARYOP:
case BINOP:
return "(" + type.name() + " : " + operatorType + ")";
+
case OGROUP:
case TOKREF:
return "(" + type.name() + " : " + tokenVal + ")";
+
case GROUP:
return "(" + type.name() + " : " + groupType + ")";
+
case RESULT:
return "(" + type.name() + " : " + resultVal + ")";
+
default:
return "Unknown node type " + type;
}
@@ -75,6 +79,7 @@ public class Node {
switch (type) {
case OGROUP:
return tokenVal.equals(otk.tokenVal);
+
default:
return true;
}
diff --git a/dice-lang/src/bjc/dicelang/Parser.java b/dice-lang/src/bjc/dicelang/Parser.java
index 1029943..7e48f43 100644
--- a/dice-lang/src/bjc/dicelang/Parser.java
+++ b/dice-lang/src/bjc/dicelang/Parser.java
@@ -45,7 +45,8 @@ public class Parser {
*
* @return Whether or not the parse was successful.
*/
- public static boolean parseTokens(final IList<Token> tokens, final IList<ITree<Node>> results) {
+ public static boolean parseTokens(final IList<Token> tokens,
+ final IList<ITree<Node>> results) {
final Deque<ITree<Node>> working = new LinkedList<>();
for (final Token tk : tokens) {
@@ -54,11 +55,15 @@ public class Parser {
case OBRACE:
working.push(new Tree<>(new Node(OGROUP, tk)));
break;
+
case CBRACKET:
case CBRACE:
final boolean sc = parseClosingGrouper(working, tk);
+
if (!sc) return false;
+
break;
+
case MULTIPLY:
case DIVIDE:
case IDIVIDE:
@@ -76,6 +81,7 @@ public class Parser {
handleBinaryNode(working, tk);
break;
+
case ADD:
case SUBTRACT:
if (working.size() == 0) {
@@ -92,7 +98,9 @@ public class Parser {
} else {
handleBinaryNode(working, tk);
}
+
break;
+
case COERCE:
case DICESCALAR:
case DICEFUDGE:
@@ -106,7 +114,9 @@ public class Parser {
working.push(opNode);
}
+
break;
+
case INT_LIT:
case FLOAT_LIT:
case STRING_LIT:
@@ -114,6 +124,7 @@ public class Parser {
case DICE_LIT:
working.push(new Tree<>(new Node(TOKREF, tk)));
break;
+
default:
Errors.inst.printError(EK_PARSE_INVTOKEN, tk.type.toString());
return false;
@@ -139,26 +150,31 @@ public class Parser {
working.push(opNode);
}
- private static boolean parseClosingGrouper(final Deque<ITree<Node>> working, final Token tk) {
+ private static boolean parseClosingGrouper(final Deque<ITree<Node>> working,
+ final Token tk) {
if (working.size() == 0) {
Errors.inst.printError(EK_PARSE_NOCLOSE);
return false;
}
ITree<Node> groupNode = null;
+
switch (tk.type) {
case CBRACE:
groupNode = new Tree<>(new Node(GROUP, Node.GroupType.CODE));
break;
+
case CBRACKET:
groupNode = new Tree<>(new Node(GROUP, Node.GroupType.ARRAY));
break;
+
default:
Errors.inst.printError(EK_PARSE_UNCLOSE, tk.type.toString());
return false;
}
Token matching = null;
+
if (tk.type == CBRACKET) {
matching = new Token(Token.Type.OBRACKET, tk.intValue);
} else if (tk.type == CBRACE) {
@@ -166,12 +182,14 @@ public class Parser {
}
final ITree<Node> matchNode = new Tree<>(new Node(OGROUP, matching));
+
if (!working.contains(matchNode)) {
Errors.inst.printError(EK_PARSE_UNCLOSE, tk.toString(), matchNode.toString());
System.out.println("\tCurrent forest is: ");
int treeNo = 1;
+
for (final ITree<Node> ast : working) {
System.out.println("Tree " + treeNo++ + ": " + ast.toString());
}
diff --git a/dice-lang/src/bjc/dicelang/Shunter.java b/dice-lang/src/bjc/dicelang/Shunter.java
index ffe730b..d9025c1 100644
--- a/dice-lang/src/bjc/dicelang/Shunter.java
+++ b/dice-lang/src/bjc/dicelang/Shunter.java
@@ -73,19 +73,19 @@ public class Shunter {
/**
* Precedence for math operators.
*/
- public final int MATH_PREC = 30;
+ public final int MATH_PREC = 30;
/**
* Precedence for dice operators.
*/
- public final int DICE_PREC = 20;
+ public final int DICE_PREC = 20;
/**
* Precedence for string operators.
*/
- public final int STR_PREC = 10;
+ public final int STR_PREC = 10;
/**
* Precedence for expression operators.
*/
- public final int EXPR_PREC = 0;
+ public final int EXPR_PREC = 0;
/**
* Create a new shunter.
@@ -168,8 +168,9 @@ public class Shunter {
return true;
}
- private boolean shuntToken(final Token tk, final Deque<Token> opStack, final Deque<Token> unaryStack,
- final Deque<Token> currReturned, final Deque<Token> feed) {
+ private boolean shuntToken(final Token tk, final Deque<Token> opStack,
+ final Deque<Token> unaryStack,
+ final Deque<Token> currReturned, final Deque<Token> feed) {
if (unaryStack.size() != 0) {
if (isUnary(tk)) {
unaryStack.add(tk);
@@ -247,9 +248,11 @@ public class Shunter {
case CPAREN:
matching = new Token(OPAREN, tk.intValue);
break;
+
case CBRACE:
matching = new Token(OBRACE, tk.intValue);
break;
+
default:
Errors.inst.printError(EK_SHUNT_NOGROUP);
return false;
@@ -330,9 +333,13 @@ public class Shunter {
final Token.Type ty = tk.type;
if (ops.containsKey(ty)) return true;
+
if (unaryAdjectives.contains(ty)) return true;
+
if (unaryAdverbs.contains(ty)) return true;
+
if (unaryGerunds.contains(ty)) return true;
+
if (ty == TAGOPR) return true;
return false;
@@ -342,7 +349,9 @@ public class Shunter {
final Token.Type ty = tk.type;
if (unaryAdjectives.contains(ty)) return true;
+
if (unaryAdverbs.contains(ty)) return true;
+
if (unaryGerunds.contains(ty)) return true;
return false;
diff --git a/dice-lang/src/bjc/dicelang/Token.java b/dice-lang/src/bjc/dicelang/Token.java
index 22df90b..8b6d12b 100644
--- a/dice-lang/src/bjc/dicelang/Token.java
+++ b/dice-lang/src/bjc/dicelang/Token.java
@@ -86,14 +86,18 @@ public class Token {
case OBRACE:
case CBRACE:
return type.toString() + "(" + intValue + ")";
+
case FLOAT_LIT:
return type.toString() + "(" + floatValue + ")";
+
case DICE_LIT:
return type.toString() + "(" + diceValue + ")";
+
case TAGOP:
case TAGOPR:
case TOKGROUP:
return type.toString() + "(" + tokenValues + ")";
+
default:
return type.toString();
}
@@ -111,6 +115,7 @@ public class Token {
case OBRACE:
case OBRACKET:
return intValue == otk.intValue;
+
default:
return true;
}
@@ -122,6 +127,7 @@ public class Token {
case OBRACE:
case OBRACKET:
return true;
+
default:
return false;
}
diff --git a/dice-lang/src/bjc/dicelang/Tokenizer.java b/dice-lang/src/bjc/dicelang/Tokenizer.java
index 3ca9a94..259661d 100644
--- a/dice-lang/src/bjc/dicelang/Tokenizer.java
+++ b/dice-lang/src/bjc/dicelang/Tokenizer.java
@@ -89,6 +89,7 @@ public class Tokenizer {
case '}':
tk = tokenizeGrouping(token);
break;
+
default:
tk = tokenizeLiteral(token, stringLts);
}
@@ -105,21 +106,27 @@ public class Tokenizer {
case '(':
tk = new Token(OPAREN, token.length());
break;
+
case ')':
tk = new Token(CPAREN, token.length());
break;
+
case '[':
tk = new Token(OBRACKET, token.length());
break;
+
case ']':
tk = new Token(CBRACKET, token.length());
break;
+
case '{':
tk = new Token(OBRACE, token.length());
break;
+
case '}':
tk = new Token(CBRACE, token.length());
break;
+
default:
Errors.inst.printError(EK_TOK_UNGROUP, token);
break;
@@ -129,9 +136,12 @@ public class Tokenizer {
return tk;
}
- private final Pattern hexadecimalMatcher = Pattern.compile("\\A[\\-\\+]?0x[0-9A-Fa-f]+\\Z");
- private final Pattern flexadecimalMatcher = Pattern.compile("\\A[\\-\\+]?[0-9][0-9A-Za-z]+B\\d{1,2}\\Z");
- private final Pattern stringLitMatcher = Pattern.compile("\\AstringLiteral(\\d+)\\Z");
+ private final Pattern hexadecimalMatcher =
+ Pattern.compile("\\A[\\-\\+]?0x[0-9A-Fa-f]+\\Z");
+ private final Pattern flexadecimalMatcher =
+ Pattern.compile("\\A[\\-\\+]?[0-9][0-9A-Za-z]+B\\d{1,2}\\Z");
+ private final Pattern stringLitMatcher =
+ Pattern.compile("\\AstringLiteral(\\d+)\\Z");
private Token tokenizeLiteral(final String token, final IMap<String, String> stringLts) {
Token tk = Token.NIL_TOKEN;
diff --git a/dice-lang/src/bjc/dicelang/dice/CompoundDie.java b/dice-lang/src/bjc/dicelang/dice/CompoundDie.java
index 7cd8fcf..a81322c 100644
--- a/dice-lang/src/bjc/dicelang/dice/CompoundDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/CompoundDie.java
@@ -9,8 +9,8 @@ public class CompoundDie implements Die {
/*
* The dice that form this die
*/
- private final Die left;
- private final Die right;
+ private final Die left;
+ private final Die right;
/**
* Create a new compound die.
diff --git a/dice-lang/src/bjc/dicelang/dice/CompoundingDie.java b/dice-lang/src/bjc/dicelang/dice/CompoundingDie.java
index 73d910a..1bd478f 100644
--- a/dice-lang/src/bjc/dicelang/dice/CompoundingDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/CompoundingDie.java
@@ -13,8 +13,8 @@ import java.util.function.Predicate;
public class CompoundingDie implements Die {
private final Die source;
- private final Predicate<Long> compoundOn;
- private final String compoundPattern;
+ private final Predicate<Long> compoundOn;
+ private final String compoundPattern;
/**
* Create a new compounding die with no pattern.
diff --git a/dice-lang/src/bjc/dicelang/dice/DiceBox.java b/dice-lang/src/bjc/dicelang/dice/DiceBox.java
index c956977..afb2ea3 100644
--- a/dice-lang/src/bjc/dicelang/dice/DiceBox.java
+++ b/dice-lang/src/bjc/dicelang/dice/DiceBox.java
@@ -41,6 +41,7 @@ public class DiceBox {
final String[] dieParts = expString.split("d");
final long right = Long.parseLong(dieParts[1]);
+
if (dieParts[0].equals("")) {
/*
* Handle short-form expressions.
@@ -131,16 +132,18 @@ public class DiceBox {
*
* This is just a number.
*/
- private static final String scalarDie = "[\\+\\-]?\\d+sd";
- private static final Pattern scalarDiePattern = Pattern.compile("\\A" + scalarDie + "\\Z");
+ private static final String scalarDie = "[\\+\\-]?\\d+sd";
+ private static final Pattern scalarDiePattern = Pattern.compile("\\A" +
+ scalarDie + "\\Z");
/*
* Defines a simple die.
*
* This is a group of one or more dice of the same size.
*/
- private static final String simpleDie = "(?:\\d+)?d\\d+";
- private static final Pattern simpleDiePattern = Pattern.compile("\\A" + simpleDie + "\\Z");
+ private static final String simpleDie = "(?:\\d+)?d\\d+";
+ private static final Pattern simpleDiePattern = Pattern.compile("\\A" +
+ simpleDie + "\\Z");
/*
* Defines a fudge die.
@@ -148,24 +151,28 @@ public class DiceBox {
* This is like a simple die, but all the die give -1, 0, or 1 as
* results.
*/
- private static final String fudgeDie = "(?:\\d+)?dF";
- private static final Pattern fudgeDiePattern = Pattern.compile("\\A" + fudgeDie + "\\Z");
+ private static final String fudgeDie = "(?:\\d+)?dF";
+ private static final Pattern fudgeDiePattern = Pattern.compile("\\A" + fudgeDie +
+ "\\Z");
/*
* Defines a compound die.
*
* This is like using two d10's to simulate a d100
*/
- private static final String compoundDie = simpleDie + "c(?:(?:" + simpleDie + ")|(?:\\d+))";
- private static final Pattern compoundDiePattern = Pattern.compile("\\A" + compoundDie + "\\Z");
+ private static final String compoundDie = simpleDie + "c(?:(?:" +
+ simpleDie + ")|(?:\\d+))";
+ private static final Pattern compoundDiePattern = Pattern.compile("\\A" +
+ compoundDie + "\\Z");
/*
* Defines a compound group.
*
* This is used for forming die list type expressions.
*/
- private static final String compoundGroup = "(?:(?:" + scalarDie + ")|(?:" + simpleDie + ")|(?:" + compoundDie
- + ")|(?:" + fudgeDie + "))";
+ private static final String compoundGroup = "(?:(?:" + scalarDie + ")|(?:" + simpleDie +
+ ")|(?:" + compoundDie
+ + ")|(?:" + fudgeDie + "))";
/*
* Defines a compounding die.
@@ -173,8 +180,10 @@ public class DiceBox {
* This is like an exploding die, but is a single die, not a group of
* them.
*/
- private static final String compoundingDie = compoundGroup + "!!" + comparePoint;
- private static final Pattern compoundingDiePattern = Pattern.compile("\\A" + compoundingDie + "\\Z");
+ private static final String compoundingDie = compoundGroup + "!!" +
+ comparePoint;
+ private static final Pattern compoundingDiePattern = Pattern.compile("\\A" +
+ compoundingDie + "\\Z");
/*
* Defines an exploding die.
@@ -182,8 +191,10 @@ public class DiceBox {
* This is a die that you reroll the component of if it meets a certain
* condition.
*/
- private static final String explodingDie = compoundGroup + "!" + comparePoint;
- private static final Pattern explodingDiePattern = Pattern.compile("\\A" + explodingDie + "\\Z");
+ private static final String explodingDie = compoundGroup + "!" +
+ comparePoint;
+ private static final Pattern explodingDiePattern = Pattern.compile("\\A" +
+ explodingDie + "\\Z");
/*
* Defines a penetrating die.
@@ -191,16 +202,19 @@ public class DiceBox {
* This is like an exploding die, but the exploded result gets a -1
* penalty.
*/
- private static final String penetratingDie = compoundGroup + "!" + comparePoint;
- private static final Pattern penetratingDiePattern = Pattern.compile("\\A" + penetratingDie + "\\Z");
+ private static final String penetratingDie = compoundGroup + "!" +
+ comparePoint;
+ private static final Pattern penetratingDiePattern = Pattern.compile("\\A" +
+ penetratingDie + "\\Z");
/*
* Defines a die list.
*
* This is an array of dice of the specified size.
*/
- private static final String diceList = compoundGroup + "dl" + compoundGroup;
- private static final Pattern diceListPattern = Pattern.compile("\\A" + diceList + "\\Z");
+ private static final String diceList = compoundGroup + "dl" + compoundGroup;
+ private static final Pattern diceListPattern = Pattern.compile("\\A" + diceList +
+ "\\Z");
/**
* Check if a given string is a valid die expression.
@@ -239,10 +253,13 @@ public class DiceBox {
switch (patt.charAt(0)) {
case '<':
return (roll) -> roll < num;
+
case '=':
return (roll) -> roll == num;
+
case '>':
return (roll) -> roll > num;
+
default:
return (roll) -> false;
}
diff --git a/dice-lang/src/bjc/dicelang/dice/DieExpression.java b/dice-lang/src/bjc/dicelang/dice/DieExpression.java
index b114da6..edf7684 100644
--- a/dice-lang/src/bjc/dicelang/dice/DieExpression.java
+++ b/dice-lang/src/bjc/dicelang/dice/DieExpression.java
@@ -16,11 +16,11 @@ public class DieExpression {
/**
* The scalar value in this expression, if there is one.
*/
- public Die scalar;
+ public Die scalar;
/**
* The list value in this expression, if there is one.
*/
- public DieList list;
+ public DieList list;
/**
* Create a scalar die expression.
diff --git a/dice-lang/src/bjc/dicelang/dice/ExplodingDice.java b/dice-lang/src/bjc/dicelang/dice/ExplodingDice.java
index 15d6572..7036f32 100644
--- a/dice-lang/src/bjc/dicelang/dice/ExplodingDice.java
+++ b/dice-lang/src/bjc/dicelang/dice/ExplodingDice.java
@@ -21,9 +21,9 @@ public class ExplodingDice implements DieList {
/*
* The conditions for exploding.
*/
- private final Predicate<Long> explodeOn;
- private final String explodePattern;
- private final boolean explodePenetrates;
+ private final Predicate<Long> explodeOn;
+ private final String explodePattern;
+ private final boolean explodePenetrates;
/**
* Create a new exploding die.
@@ -48,7 +48,8 @@ public class ExplodingDice implements DieList {
* Whether or not for explosions to penetrate (-1 to
* exploded die).
*/
- public ExplodingDice(final Die src, final Predicate<Long> explode, final boolean penetrate) {
+ public ExplodingDice(final Die src, final Predicate<Long> explode,
+ final boolean penetrate) {
this(src, explode, null, penetrate);
}
@@ -65,7 +66,8 @@ public class ExplodingDice implements DieList {
* @param patt
* The string the condition came from, for printing.
*/
- public ExplodingDice(final Die src, final Predicate<Long> explode, final String patt, final boolean penetrate) {
+ public ExplodingDice(final Die src, final Predicate<Long> explode, final String patt,
+ final boolean penetrate) {
source = src;
explodeOn = explode;
explodePattern = patt;
@@ -95,6 +97,7 @@ public class ExplodingDice implements DieList {
if (explodePenetrates) {
oldRes -= 1;
}
+
resList.add(oldRes);
}
@@ -102,6 +105,7 @@ public class ExplodingDice implements DieList {
newRes[0] = res;
int i = 1;
+
for (final long rll : resList) {
newRes[i] = rll;
i += 1;
diff --git a/dice-lang/src/bjc/dicelang/dice/MathDie.java b/dice-lang/src/bjc/dicelang/dice/MathDie.java
index 5feb193..1984581 100644
--- a/dice-lang/src/bjc/dicelang/dice/MathDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/MathDie.java
@@ -32,10 +32,13 @@ public class MathDie implements Die {
switch (this) {
case ADD:
return "+";
+
case SUBTRACT:
return "-";
+
case MULTIPLY:
return "*";
+
default:
return this.name();
}
@@ -44,8 +47,8 @@ public class MathDie implements Die {
private final MathDie.MathOp type;
- private final Die left;
- private final Die right;
+ private final Die left;
+ private final Die right;
/**
* Create a new math die.
@@ -75,10 +78,13 @@ public class MathDie implements Die {
switch (type) {
case ADD:
return lft + rght;
+
case SUBTRACT:
return lft - rght;
+
case MULTIPLY:
return lft * rght;
+
default:
return 0;
}
diff --git a/dice-lang/src/bjc/dicelang/dice/SimpleDie.java b/dice-lang/src/bjc/dicelang/dice/SimpleDie.java
index 5610535..60c5d53 100644
--- a/dice-lang/src/bjc/dicelang/dice/SimpleDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/SimpleDie.java
@@ -7,8 +7,8 @@ package bjc.dicelang.dice;
*
*/
public class SimpleDie implements Die {
- private final Die numDice;
- private final Die diceSize;
+ private final Die numDice;
+ private final Die diceSize;
/**
* Create a new dice group.
diff --git a/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java b/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java
index f382361..84896ea 100644
--- a/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java
+++ b/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java
@@ -7,8 +7,8 @@ package bjc.dicelang.dice;
*
*/
public class SimpleDieList implements DieList {
- private final Die numDice;
- private final Die size;
+ private final Die numDice;
+ private final Die size;
/**
* Create a new list of dice.
diff --git a/dice-lang/src/bjc/dicelang/expr/Parser.java b/dice-lang/src/bjc/dicelang/expr/Parser.java
index 90a6b38..b3f83a4 100644
--- a/dice-lang/src/bjc/dicelang/expr/Parser.java
+++ b/dice-lang/src/bjc/dicelang/expr/Parser.java
@@ -52,6 +52,7 @@ public class Parser {
*/
final Token[] infixTokens = lex.lexString(ln, toks);
System.out.println("Lexed tokens: ");
+
for (final Token tok : infixTokens) {
System.out.println("\t" + tok);
}
@@ -60,9 +61,11 @@ public class Parser {
* Print out infix expression.
*/
System.out.print("Lexed expression: ");
+
for (final Token tok : infixTokens) {
System.out.print(tok.toExpr() + " ");
}
+
System.out.println();
System.out.println();
@@ -71,6 +74,7 @@ public class Parser {
*/
final Token[] postfixTokens = Shunter.shuntTokens(infixTokens);
System.out.println("Lexed tokens: ");
+
for (final Token tok : postfixTokens) {
System.out.println("\t" + tok);
}
@@ -79,14 +83,17 @@ public class Parser {
* Print out postfix tokens.
*/
System.out.print("Shunted expression: ");
+
for (final Token tok : postfixTokens) {
System.out.print(tok.toExpr() + " ");
}
+
System.out.println();
System.out.println();
final FunctionalList<Token> tokList = new FunctionalList<>(Arrays.asList(postfixTokens));
- final ITree<Token> ast = TreeConstructor.constructTree(tokList, tok -> tok.typ.isOperator);
+ final ITree<Token> ast = TreeConstructor.constructTree(tokList,
+ tok -> tok.typ.isOperator);
/*
* Print the tree, then the canonical expression for it.
diff --git a/dice-lang/src/bjc/dicelang/expr/Shunter.java b/dice-lang/src/bjc/dicelang/expr/Shunter.java
index 19b30c3..3e49356 100644
--- a/dice-lang/src/bjc/dicelang/expr/Shunter.java
+++ b/dice-lang/src/bjc/dicelang/expr/Shunter.java
@@ -41,6 +41,7 @@ public class Shunter {
int leftPriority = tok.typ.operatorPriority;
int rightPriority;
+
if (curOp == null) {
rightPriority = 0;
} else {
diff --git a/dice-lang/src/bjc/dicelang/expr/Token.java b/dice-lang/src/bjc/dicelang/expr/Token.java
index d7fc0e2..1a506bf 100644
--- a/dice-lang/src/bjc/dicelang/expr/Token.java
+++ b/dice-lang/src/bjc/dicelang/expr/Token.java
@@ -70,18 +70,25 @@ public class Token {
switch (typ) {
case ADD:
return "+";
+
case SUBTRACT:
return "-";
+
case MULTIPLY:
return "*";
+
case DIVIDE:
return "/";
+
case VREF:
return tks.symbolTable.get(intValue);
+
case OPAREN:
return "(";
+
case CPAREN:
return ")";
+
default:
return "???";
}
diff --git a/dice-lang/src/bjc/dicelang/expr/TokenType.java b/dice-lang/src/bjc/dicelang/expr/TokenType.java
index fa20813..d88283e 100644
--- a/dice-lang/src/bjc/dicelang/expr/TokenType.java
+++ b/dice-lang/src/bjc/dicelang/expr/TokenType.java
@@ -44,11 +44,11 @@ public enum TokenType {
/**
* Whether or not this type of token is an operator.
*/
- public final boolean isOperator;
+ public final boolean isOperator;
/**
* The priority of this operator, if it is one.
*/
- public final int operatorPriority;
+ public final int operatorPriority;
private TokenType(final int num, final boolean isOp, final int priority) {
nVal = num;
diff --git a/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java b/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java
index ac9e880..b490217 100644
--- a/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java
+++ b/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java
@@ -174,8 +174,8 @@ public class StreamControlEngine {
}
}
- private static final Map<String, Token.Type> litTokens;
- private static final Map<String, Token.Type> builtinWords;
+ private static final Map<String, Token.Type> litTokens;
+ private static final Map<String, Token.Type> builtinWords;
static {
litTokens = new HashMap<>();
@@ -242,21 +242,31 @@ public class StreamControlEngine {
switch (tok.type) {
case SQUOTE:
i = handleSingleQuote(i, tokens);
+
if (i == -1) return false;
+
break;
+
case OBRACKET:
i = handleDelim(i, tokens, "]");
+
if (i == -1) return false;
+
break;
+
case OBRACE:
i = handleDelim(i, tokens, "}");
+
if (i == -1) return false;
+
final Token brak = curStack.pop();
curStack.push(new Token(ARRAY, brak.tokenVals));
break;
+
case WORD:
handleWord(tok);
break;
+
default:
curStack.push(tok);
break;
@@ -273,51 +283,80 @@ public class StreamControlEngine {
case NEWSTREAM:
eng.newStream();
break;
+
case LEFTSTREAM:
succ = eng.leftStream();
+
if (!succ) return false;
+
break;
+
case RIGHTSTREAM:
succ = eng.rightStream();
+
if (!succ) return false;
+
break;
+
case DELETESTREAM:
succ = eng.deleteStream();
+
if (!succ) return false;
+
break;
+
case MERGESTREAM:
succ = eng.mergeStream();
+
if (!succ) return false;
+
break;
+
case MAKEARRAY:
succ = makeArray();
+
if (!succ) return false;
+
break;
+
case MAKEEXEC:
succ = toggleExec(true);
+
if (!succ) return false;
+
break;
+
case MAKEUNEXEC:
succ = toggleExec(false);
+
if (!succ) return false;
+
break;
+
case STACKCOUNT:
curStack.push(new Token(ILIT, curStack.size()));
break;
+
case STACKEMPTY:
curStack.push(new Token(BLIT, curStack.empty()));
break;
+
case DROP:
if (curStack.size() == 0) {
Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.tokenVal.type.toString());
return false;
}
+
curStack.drop();
break;
+
case NDROP:
succ = handleNDrop();
+
if (!succ) return false;
+
break;
+
case NIP:
if (curStack.size() < 2) {
Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.tokenVal.type.toString());
@@ -326,10 +365,14 @@ public class StreamControlEngine {
curStack.nip();
break;
+
case NNIP:
succ = handleNNip();
+
if (!succ) return false;
+
break;
+
default:
Errors.inst.printError(EK_SCL_UNWORD, tk.tokenVal.type.toString());
return false;
@@ -420,10 +463,12 @@ public class StreamControlEngine {
final IList<Token> toks = new FunctionalList<>();
int n = i + 1;
+
if (n >= tokens.length) {
Errors.inst.printError(EK_SCL_MMQUOTE);
return -1;
}
+
String tok = tokens[n];
while (!tok.equals(delim)) {
@@ -432,31 +477,43 @@ public class StreamControlEngine {
switch (ntok.type) {
case SQUOTE:
n = handleSingleQuote(n, tokens);
+
if (n == -1) return -1;
+
toks.add(curStack.pop());
break;
+
case OBRACKET:
n = handleDelim(n, tokens, "]");
+
if (n == -1) return -1;
+
toks.add(curStack.pop());
break;
+
case OBRACE:
n = handleDelim(i, tokens, "}");
+
if (n == -1) return -1;
+
final Token brak = curStack.pop();
toks.add(new Token(ARRAY, brak.tokenVals));
break;
+
default:
toks.add(ntok);
}
+
/*
* Move to the next token
*/
n += 1;
+
if (n >= tokens.length) {
Errors.inst.printError(EK_SCL_MMQUOTE);
return -1;
}
+
tok = tokens[n];
}
@@ -474,10 +531,12 @@ public class StreamControlEngine {
final StringBuilder sb = new StringBuilder();
int n = i + 1;
+
if (n >= tokens.length) {
Errors.inst.printError(EK_SCL_MMQUOTE);
return -1;
}
+
String tok = tokens[n];
while (!tok.equals("'")) {
@@ -494,10 +553,12 @@ public class StreamControlEngine {
* Move to the next token
*/
n += 1;
+
if (n >= tokens.length) {
Errors.inst.printError(EK_SCL_MMQUOTE);
return -1;
}
+
tok = tokens[n];
}
diff --git a/dice-lang/src/bjc/dicelang/scl/StreamEngine.java b/dice-lang/src/bjc/dicelang/scl/StreamEngine.java
index 4717eaa..f1abbdc 100644
--- a/dice-lang/src/bjc/dicelang/scl/StreamEngine.java
+++ b/dice-lang/src/bjc/dicelang/scl/StreamEngine.java
@@ -31,8 +31,8 @@ public class StreamEngine {
/*
* Our streams.
*/
- Tape<IList<String>> streams;
- IList<String> currStream;
+ Tape<IList<String>> streams;
+ IList<String> currStream;
/*
* Saved streams
@@ -210,26 +210,42 @@ public class StreamEngine {
case '+':
newStream();
break;
+
case '>':
succ = rightStream();
+
if (!succ) return false;
+
break;
+
case '<':
succ = leftStream();
+
if (!succ) return false;
+
break;
+
case '-':
succ = deleteStream();
+
if (!succ) return false;
+
break;
+
case 'M':
succ = mergeStream();
+
if (!succ) return false;
+
break;
+
case 'L':
succ = scleng.runProgram(currStream.toArray(new String[0]));
+
if (!succ) return false;
+
break;
+
default:
Errors.inst.printError(EK_STRM_INVCOM, tk);
return false;