summaryrefslogtreecommitdiff
path: root/dice-lang
diff options
context:
space:
mode:
authorbjculkin <bjculkin@mix.wvu.edu>2017-04-11 17:51:13 -0400
committerbjculkin <bjculkin@mix.wvu.edu>2017-04-11 17:51:13 -0400
commit40858cee415643769ee5f6216b0cd4335996ff2f (patch)
tree86b1c334fa2e5b79cddc16984f5ad43c3c72e41f /dice-lang
parent767ca1b248da19b754d42a814b71b43ef16090be (diff)
General cleanup and fixes
Diffstat (limited to 'dice-lang')
-rw-r--r--dice-lang/src/bjc/dicelang/CLIArgsParser.java7
-rw-r--r--dice-lang/src/bjc/dicelang/CompilerTweaker.java194
-rw-r--r--dice-lang/src/bjc/dicelang/Define.java54
-rw-r--r--dice-lang/src/bjc/dicelang/DiceLangConsole.java27
-rw-r--r--dice-lang/src/bjc/dicelang/DiceLangEngine.java48
-rw-r--r--dice-lang/src/bjc/dicelang/Errors.java247
-rw-r--r--dice-lang/src/bjc/dicelang/Evaluator.java63
-rw-r--r--dice-lang/src/bjc/dicelang/EvaluatorResult.java306
-rw-r--r--dice-lang/src/bjc/dicelang/Node.java6
-rw-r--r--dice-lang/src/bjc/dicelang/Parser.java23
-rw-r--r--dice-lang/src/bjc/dicelang/Shunter.java37
-rw-r--r--dice-lang/src/bjc/dicelang/Token.java9
-rw-r--r--dice-lang/src/bjc/dicelang/Tokenizer.java317
-rw-r--r--dice-lang/src/bjc/dicelang/dice/DiceBox.java66
-rw-r--r--dice-lang/src/bjc/dicelang/dice/DieExpression.java130
-rw-r--r--dice-lang/src/bjc/dicelang/dice/DieList.java63
-rw-r--r--dice-lang/src/bjc/dicelang/dice/FudgeDie.java110
-rw-r--r--dice-lang/src/bjc/dicelang/dice/MathDie.java193
-rw-r--r--dice-lang/src/bjc/dicelang/dice/ScalarDie.java78
-rw-r--r--dice-lang/src/bjc/dicelang/dice/SimpleDie.java173
-rw-r--r--dice-lang/src/bjc/dicelang/dice/SimpleDieList.java115
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Lexer.java23
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Parser.java4
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Shunter.java18
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Token.java4
-rw-r--r--dice-lang/src/bjc/dicelang/expr/Tokens.java4
-rw-r--r--dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java11
-rw-r--r--dice-lang/src/bjc/dicelang/scl/StreamEngine.java26
-rw-r--r--dice-lang/src/bjc/dicelang/util/ResourceLoader.java83
29 files changed, 1520 insertions, 919 deletions
diff --git a/dice-lang/src/bjc/dicelang/CLIArgsParser.java b/dice-lang/src/bjc/dicelang/CLIArgsParser.java
index 4ecb91b..91917a0 100644
--- a/dice-lang/src/bjc/dicelang/CLIArgsParser.java
+++ b/dice-lang/src/bjc/dicelang/CLIArgsParser.java
@@ -34,15 +34,13 @@ public class CLIArgsParser {
for(String lne : ResourceLoader.loadHelpFile("cli")) {
System.out.println(lne);
}
-
+
System.exit(0);
}
for(int i = 0; i < args.length; i++) {
String arg = args[i];
- boolean succ = true;
-
switch(arg) {
case "-d":
case "--debug":
@@ -139,6 +137,7 @@ public class CLIArgsParser {
return i + 2;
}
+ @SuppressWarnings("unused")
private static int defineFile(int i, String[] args, DiceLangEngine eng) {
if(i >= args.length - 1) {
Errors.inst.printError(EK_CLI_MISARG, "define-file");
@@ -178,7 +177,7 @@ public class CLIArgsParser {
return i + 1;
}
- private static Define parseDefine(String ln) {
+ private static Define parseDefine(@SuppressWarnings("unused") String ln) {
Define res = null;
// @TODO move this functionality from DiceLangConsole to some
diff --git a/dice-lang/src/bjc/dicelang/CompilerTweaker.java b/dice-lang/src/bjc/dicelang/CompilerTweaker.java
index e04f054..f622518 100644
--- a/dice-lang/src/bjc/dicelang/CompilerTweaker.java
+++ b/dice-lang/src/bjc/dicelang/CompilerTweaker.java
@@ -1,94 +1,100 @@
-package bjc.dicelang;
-
-import bjc.utils.parserutils.splitter.SimpleTokenSplitter;
-
-/**
- * Contains methods for customizing the DiceLang and SCL compilers.
- *
- * @author Ben Culkin
- */
-public class CompilerTweaker {
- /*
- * Bits of the compiler necessary
- */
- private DiceLangEngine eng;
- private SimpleTokenSplitter opExpander;
-
- public CompilerTweaker(DiceLangEngine eng) {
- this.eng = eng;
-
- this.opExpander = eng.opExpander;
- }
-
- /**
- * Add a string literal to the compiler's internal banks.
- *
- * @param val
- * The string literal to add.
- *
- * @return The key into the string literal table for this string.
- */
- public int addStringLiteral(String val) {
- eng.addStringLiteral(eng.nextLiteral, val);
-
- eng.nextLiteral += 1;
- return eng.nextLiteral;
- }
-
- /**
- * Add a line defn to the compiler.
- *
- * @param dfn
- * The defn to add.
- */
- public void addLineDefine(Define dfn) {
- eng.addLineDefine(dfn);
- }
-
- /**
- * Add a token defn to the compiler.
- *
- * @param dfn
- * The defn to add.
- */
- public void addTokenDefine(Define dfn) {
- eng.addTokenDefine(dfn);
- }
-
- /**
- * Adds a delimiter that is expanded from tokens.
- *
- * @param delim
- * The delimiter to expand on.
- */
- public void addDelimiter(String delim) {
- opExpander.addDelimiter(delim);
- }
-
- /**
- * Adds a multi-character delimiter that is expanded from tokens.
- *
- * @param delim
- * The multi-character delimiter to expand on.
- */
- public void addMultiDelimiter(String delim) {
- opExpander.addMultiDelimiter(delim);
- }
-
- /**
- * Make delimiter changes visible to the compiler.
- */
- public void compile() {
- opExpander.compile();
- }
-
- /**
- * Change the max no. of times defines are allowed to recur.
- *
- * @param times
- * The number of times to allow defines to recur.
- */
- public static void setDefineRecurLimit(int times) {
- Define.MAX_RECURS = times;
- }
-}
+package bjc.dicelang;
+
+import bjc.utils.parserutils.splitter.ConfigurableTokenSplitter;
+
+/**
+ * Contains methods for customizing the DiceLang and SCL compilers.
+ *
+ * @author Ben Culkin
+ */
+public class CompilerTweaker {
+ /*
+ * Bits of the compiler necessary
+ */
+ private DiceLangEngine eng;
+ private ConfigurableTokenSplitter opExpander;
+
+ /**
+ * Create a new compiler tweaker.
+ *
+ * @param eng
+ * The engine to tweak.
+ */
+ public CompilerTweaker(DiceLangEngine eng) {
+ this.eng = eng;
+
+ this.opExpander = eng.opExpander;
+ }
+
+ /**
+ * Add a string literal to the compiler's internal banks.
+ *
+ * @param val
+ * The string literal to add.
+ *
+ * @return The key into the string literal table for this string.
+ */
+ public int addStringLiteral(String val) {
+ eng.addStringLiteral(eng.nextLiteral, val);
+
+ eng.nextLiteral += 1;
+ return eng.nextLiteral;
+ }
+
+ /**
+ * Add a line defn to the compiler.
+ *
+ * @param dfn
+ * The defn to add.
+ */
+ public void addLineDefine(Define dfn) {
+ eng.addLineDefine(dfn);
+ }
+
+ /**
+ * Add a token defn to the compiler.
+ *
+ * @param dfn
+ * The defn to add.
+ */
+ public void addTokenDefine(Define dfn) {
+ eng.addTokenDefine(dfn);
+ }
+
+ /**
+ * Adds delimiters that are expanded from tokens.
+ *
+ * @param delims
+ * The delimiters to expand on.
+ */
+ public void addDelimiter(String... delims) {
+ opExpander.addSimpleDelimiters(delims);
+ }
+
+ /**
+ * Adds multi-character delimiters that are expanded from tokens.
+ *
+ * @param delims
+ * The multi-character delimiters to expand on.
+ */
+ public void addMultiDelimiter(String... delims) {
+ opExpander.addMultiDelimiters(delims);
+ }
+
+ /**
+ * Make delimiter changes visible to the compiler.
+ */
+ public void compile() {
+ opExpander.compile();
+ }
+
+ /**
+ * Change the max no. of times defines are allowed to recur.
+ *
+ * @param times
+ * The number of times to allow defines to recur.
+ */
+ public static void setDefineRecurLimit(int times) {
+ Define.MAX_RECURS = times;
+ }
+}
diff --git a/dice-lang/src/bjc/dicelang/Define.java b/dice-lang/src/bjc/dicelang/Define.java
index d9e1f84..dbc349d 100644
--- a/dice-lang/src/bjc/dicelang/Define.java
+++ b/dice-lang/src/bjc/dicelang/Define.java
@@ -12,14 +12,42 @@ import static bjc.dicelang.Errors.ErrorKey.EK_DFN_PREDSYN;
import static bjc.dicelang.Errors.ErrorKey.EK_DFN_RECUR;
import static bjc.dicelang.Errors.ErrorKey.EK_DFN_SRCSYN;
+/**
+ * A regular expression based pre-processor define.
+ *
+ * @author EVE
+ *
+ */
public class Define implements UnaryOperator<String>, Comparable<Define> {
+ /**
+ * The define type.
+ *
+ * @author EVE
+ *
+ */
public static enum Type {
- LINE, TOKEN
+ /**
+ * Match on lines.
+ */
+ LINE,
+ /**
+ * Match on tokens.
+ */
+ TOKEN
}
+ /**
+ * The max amount of times to recur on expansions.
+ */
public static int MAX_RECURS = 10;
+ /**
+ * The priority of this definition.
+ */
public final int priority;
+ /**
+ * Whether or not this definition is in error.
+ */
public final boolean inError;
private boolean doRecur;
@@ -31,6 +59,30 @@ public class Define implements UnaryOperator<String>, Comparable<Define> {
private Iterator<String> replacers;
private String replacer;
+ /**
+ * Create a new define.
+ *
+ * @param priorty
+ * The priority of the define.
+ *
+ * @param isSub
+ * Whether or not this is a 'sub-define'
+ *
+ * @param recur
+ * Whether this define is recursive or not.
+ *
+ * @param isCircular
+ * Whether this define is circular or not.
+ *
+ * @param predicte
+ * The string to use as a predicate.
+ *
+ * @param searchr
+ * The string to use as a search.
+ *
+ * @param replacrs
+ * The source for replacement strings.
+ */
public Define(int priorty, boolean isSub, boolean recur, boolean isCircular, String predicte, String searchr,
Iterable<String> replacrs) {
priority = priorty;
diff --git a/dice-lang/src/bjc/dicelang/DiceLangConsole.java b/dice-lang/src/bjc/dicelang/DiceLangConsole.java
index 3a53322..c45d772 100644
--- a/dice-lang/src/bjc/dicelang/DiceLangConsole.java
+++ b/dice-lang/src/bjc/dicelang/DiceLangConsole.java
@@ -12,6 +12,12 @@ import static bjc.dicelang.Errors.ErrorKey.EK_CONS_INVPRAG;
import jline.ConsoleReader;
import jline.Terminal;
+/**
+ * CLI interface to DiceLang
+ *
+ * @author EVE
+ *
+ */
public class DiceLangConsole {
private int commandNumber;
@@ -19,6 +25,12 @@ public class DiceLangConsole {
private ConsoleReader read;
+ /**
+ * Create a new console.
+ *
+ * @param args
+ * The CLI args for the console.
+ */
public DiceLangConsole(String[] args) {
commandNumber = 0;
@@ -31,10 +43,13 @@ public class DiceLangConsole {
Terminal.setupTerminal();
}
+ /**
+ * Run the console.
+ */
public void run() {
try {
read = new ConsoleReader();
- } catch(IOException ioex) {
+ } catch(@SuppressWarnings("unused") IOException ioex) {
System.out.println("ERROR: Console init failed");
return;
}
@@ -45,7 +60,7 @@ public class DiceLangConsole {
try {
comm = read.readLine(String.format("(%d) dice-lang> ", commandNumber));
- } catch(IOException ioex) {
+ } catch(@SuppressWarnings("unused") IOException ioex) {
System.out.println("ERROR: I/O failed");
return;
}
@@ -75,7 +90,7 @@ public class DiceLangConsole {
try {
comm = read.readLine(String.format("(%d) dice-lang> ", commandNumber));
- } catch(IOException ioex) {
+ } catch(@SuppressWarnings("unused") IOException ioex) {
System.out.println("ERROR: I/O failed");
return;
}
@@ -258,6 +273,12 @@ public class DiceLangConsole {
return true;
}
+ /**
+ * Main method.
+ *
+ * @param args
+ * CLI arguments.
+ */
public static void main(String[] args) {
DiceLangConsole console = new DiceLangConsole(args);
diff --git a/dice-lang/src/bjc/dicelang/DiceLangEngine.java b/dice-lang/src/bjc/dicelang/DiceLangEngine.java
index dfd14d5..d37332d 100644
--- a/dice-lang/src/bjc/dicelang/DiceLangEngine.java
+++ b/dice-lang/src/bjc/dicelang/DiceLangEngine.java
@@ -9,7 +9,7 @@ import bjc.utils.funcdata.IList;
import bjc.utils.funcdata.IMap;
import bjc.utils.funcutils.ListUtils;
import bjc.utils.parserutils.TokenUtils;
-import bjc.utils.parserutils.splitter.SimpleTokenSplitter;
+import bjc.utils.parserutils.splitter.ConfigurableTokenSplitter;
import java.util.Deque;
import java.util.Iterator;
@@ -37,7 +37,7 @@ public class DiceLangEngine {
/*
* Split tokens around operators with regex
*/
- SimpleTokenSplitter opExpander;
+ ConfigurableTokenSplitter opExpander;
/*
* ID for generation.
@@ -81,6 +81,9 @@ public class DiceLangEngine {
/*
* Tables for various things.
*/
+ /**
+ * The symbol table.
+ */
public final IMap<Integer, String> symTable;
private IMap<Integer, String> stringLits;
@@ -102,6 +105,9 @@ public class DiceLangEngine {
*/
StreamEngine streamEng;
+ /**
+ * Create a new DiceLang engine.
+ */
public DiceLangEngine() {
/*
* Initialize defns.
@@ -111,7 +117,7 @@ public class DiceLangEngine {
defnsSorted = true;
/*
- * Init tables.
+ * Initialize tables.
*/
symTable = new FunctionalMap<>();
stringLits = new FunctionalMap<>();
@@ -120,22 +126,21 @@ public class DiceLangEngine {
/*
* Initialize operator expansion list.
*/
- opExpander = new SimpleTokenSplitter();
- opExpander.addMultiDelimiter("\\(");
- opExpander.addMultiDelimiter("\\)");
- opExpander.addMultiDelimiter("\\[");
- opExpander.addMultiDelimiter("\\]");
- opExpander.addMultiDelimiter("\\{");
- opExpander.addMultiDelimiter("\\}");
- opExpander.addDelimiter(":=");
- opExpander.addDelimiter("=>");
- opExpander.addDelimiter("//");
- opExpander.addDelimiter(".+.");
- opExpander.addDelimiter(".*.");
- opExpander.addDelimiter("+");
- opExpander.addDelimiter("-");
- opExpander.addDelimiter("*");
- opExpander.addDelimiter("/");
+ opExpander = new ConfigurableTokenSplitter(true);
+
+ opExpander.addMultiDelimiters("(", ")");
+ opExpander.addMultiDelimiters("[", "]");
+ opExpander.addMultiDelimiters("{", "}");
+
+ opExpander.addSimpleDelimiters(":=");
+ opExpander.addSimpleDelimiters("=>");
+ opExpander.addSimpleDelimiters("//");
+ opExpander.addSimpleDelimiters(".+.");
+ opExpander.addSimpleDelimiters(".*.");
+ opExpander.addSimpleDelimiters("+");
+ opExpander.addSimpleDelimiters("-");
+ opExpander.addSimpleDelimiters("*");
+ opExpander.addSimpleDelimiters("/");
opExpander.compile();
/*
@@ -513,8 +518,7 @@ public class DiceLangEngine {
/*
* Expand tokens
*/
- IList<String> fullyExpandedTokens = tokens
- .flatMap((token) -> new FunctionalList<>(opExpander.split(token)));
+ IList<String> fullyExpandedTokens = tokens.flatMap(opExpander::split);
System.out.println("\tCommand after token expansion: " + fullyExpandedTokens.toString());
/*
@@ -627,7 +631,7 @@ public class DiceLangEngine {
* Data storage.
*/
Deque<IList<Token>> bracedTokens = new LinkedList<>();
- IList<Token> curBracedTokens = null;
+ IList<Token> curBracedTokens = new FunctionalList<>();
for(Token tk : lexedTokens) {
if(tk.type == Token.Type.OBRACE && tk.intValue == 2) {
diff --git a/dice-lang/src/bjc/dicelang/Errors.java b/dice-lang/src/bjc/dicelang/Errors.java
index 6fa8072..7d85242 100644
--- a/dice-lang/src/bjc/dicelang/Errors.java
+++ b/dice-lang/src/bjc/dicelang/Errors.java
@@ -1,138 +1,274 @@
package bjc.dicelang;
+/**
+ * Repository for error messages.
+ *
+ * @author EVE
+ *
+ */
public class Errors {
+ /**
+ * The types of error message.
+ *
+ * @author EVE
+ *
+ */
public static enum ErrorKey {
// Define Errors
- // Incorrect define guard syntax
+ /**
+ * Incorrect define guard syntax
+ */
EK_DFN_PREDSYN,
- // Incorrect define search syntax
+ /**
+ * Incorrect define search syntax
+ */
EK_DFN_SRCSYN,
- // Recursive define recursed too many times
+ /**
+ * Recursive define recursed too many times
+ */
EK_DFN_RECUR,
// Console Errors
- // Unknown console pragma
+ /**
+ * Unknown console pragma
+ */
EK_CONS_INVPRAG,
- // Improperly formatted define
+ /**
+ * Improperly formatted define
+ */
EK_CONS_INVDEFINE,
// Language Engine Errors
- // Found closing doublebrace w/out opening doublebrace
+ /**
+ * Found closing double-brace w/out opening double-brace
+ */
EK_ENG_NOOPENING,
- // Reached end of command w/out balanced doublebraces
+ /**
+ * Reached end of command w/out balanced double-braces
+ */
EK_ENG_NOCLOSING,
// Tokenizer Errors
- // Found an unexpected grouping token
+ /**
+ * Found an unexpected grouping token
+ */
EK_TOK_UNGROUP,
- // Invalid base for a flexadecimal number
+ /**
+ * Invalid base for a flexadecimal number
+ */
EK_TOK_INVBASE,
- // Invalid flexadecimal number in a given base
+ /**
+ * Invalid flexadecimal number in a given base
+ */
EK_TOK_INVFLEX,
// Evaluator Errors
- // Unknown node type
+ /**
+ * Unknown node type
+ */
EK_EVAL_INVNODE,
- // Incorrect # of args to binary operator
+ /**
+ * Incorrect # of args to binary operator
+ */
EK_EVAL_INVBIN,
- // Incorrect # of args to unary operator
+ /**
+ * Incorrect # of args to unary operator
+ */
EK_EVAL_INVUNARY,
- // Unknown binary operator
+ /**
+ * Unknown binary operator
+ */
EK_EVAL_UNBIN,
- // Unknown unary operator
+ /**
+ * Unknown unary operator
+ */
EK_EVAL_UNUNARY,
- // Math on strings doesn't work
+ /**
+ * Math on strings doesn't work
+ */
EK_EVAL_STRINGMATH,
- // Attempted divide by zero
+ /**
+ * Attempted divide by zero
+ */
EK_EVAL_DIVZERO,
- // Attempted to divide dice
+ /**
+ * Attempted to divide dice
+ */
EK_EVAL_DIVDICE,
- // Unknown math operator
+ /**
+ * Unknown math operator
+ */
EK_EVAL_UNMATH,
- // Unknown token reference
+ /**
+ * Unknown token reference
+ */
EK_EVAL_UNTOK,
- // Unknown dice operator
+ /**
+ * Unknown dice operator
+ */
EK_EVAL_UNDICE,
- // Incorrect type to dice group operator
+ /**
+ * Incorrect type to dice group operator
+ */
EK_EVAL_INVDGROUP,
- // Incorrect type to dice creation operator
+ /**
+ * Incorrect type to dice creation operator
+ */
EK_EVAL_INVDCREATE,
- // Incorrect type to other dice operator
+ /**
+ * Incorrect type to other dice operator
+ */
EK_EVAL_INVDICE,
- // Mismatched types to math operator
+ /**
+ * Mismatched types to math operator
+ */
EK_EVAL_MISMATH,
- // Incorrect type to string operator
+ /**
+ * Incorrect type to string operator
+ */
EK_EVAL_INVSTRING,
- // Unknown string operator
+ /**
+ * Unknown string operator
+ */
EK_EVAL_UNSTRING,
// Parser Error
- // Group closing where there couldn't be an opener
+ /**
+ * Group closing where there couldn't be an opener
+ */
EK_PARSE_NOCLOSE,
- // Group closing without group opener
+ /**
+ * Group closing without group opener
+ */
EK_PARSE_UNCLOSE,
- // Incorrect # of arguments to binary operator
+ /**
+ * Incorrect # of arguments to binary operator
+ */
EK_PARSE_BINARY,
- // Not enough operands to binary operator
+ /**
+ * Not enough operands to binary operator
+ */
EK_PARSE_UNOPERAND,
- // Unrecognized token type
+ /**
+ * Unrecognized token type
+ */
EK_PARSE_INVTOKEN,
// Shunter Error
- // Unary operator expected a operand, but got an operator
+ /**
+ * Unary operator expected a operand, but got an operator
+ */
EK_SHUNT_NOTADV,
- // Unary operator expected an operator, but got an operand
+ /**
+ * Unary operator expected an operator, but got an operand
+ */
EK_SHUNT_NOTADJ,
- // Unary operator expected an operator, but didn't find one
+ /**
+ * Unary operator expected an operator, but didn't find one
+ */
EK_SHUNT_NOOP,
- // Asked for opening grouping operator, but couldn't find one
+ /**
+ * Asked for opening grouping operator, but couldn't find one
+ */
EK_SHUNT_NOGROUP,
- // No group for group seperator to attach to
+ /**
+ * No group for group seperator to attach to
+ */
EK_SHUNT_INVSEP,
- // Attempted to chain non-associative operator
+ /**
+ * Attempted to chain non-associative operator
+ */
EK_SHUNT_NOTASSOC,
// Stream Errors
- // Attempted to switch to a non-existant stream
+ /**
+ * Attempted to switch to a non-existant stream
+ */
EK_STRM_NONEX,
- // Can't delete the last stream
+ /**
+ * Can't delete the last stream
+ */
EK_STRM_LAST,
- // Unknown stream command
+ /**
+ * Unknown stream command
+ */
EK_STRM_INVCOM,
// SCL Errors
- // Unknown SCL token
+ /**
+ * Unknown SCL token
+ */
EK_SCL_INVTOKEN,
- // Mismatched quote in SCL command
+ /**
+ * Mismatched quote in SCL command
+ */
EK_SCL_MMQUOTE,
- // Stack underflow in SCL command
+ /**
+ * Stack underflow in SCL command
+ */
EK_SCL_SUNDERFLOW,
- // Unknown word in SCL command
+ /**
+ * Unknown word in SCL command
+ */
EK_SCL_UNWORD,
- // Invalid argument to SCL command
+ /**
+ * Invalid argument to SCL command
+ */
EK_SCL_INVARG,
- // CLI Argument Erros
- // Unknown CLI argument
+ // CLI Argument Errors
+ /**
+ * Unknown CLI argument
+ */
EK_CLI_UNARG,
- // Missing subargument to argument
+ /**
+ * Missing sub-argument to argument
+ */
EK_CLI_MISARG,
- // Invalid define type
+ /**
+ * Invalid define type
+ */
EK_CLI_INVDFNTYPE,
- // Misc. errors
- // Unknown I/O problem
+ // Miscellaneous errors
+ /**
+ * Unknown I/O problem
+ */
EK_MISC_IOEX,
- // File not found
+ /**
+ * File not found
+ */
EK_MISC_NOFILE,
}
+ /**
+ * The mode for the type of error messages to print out.
+ *
+ * @author EVE
+ *
+ */
public static enum ErrorMode {
- WIZARD, DEV
+ /**
+ * Output error messages for wizards.
+ */
+ WIZARD,
+ /**
+ * Output error messages for developers.
+ */
+ DEV
}
private ErrorMode mode;
+ /**
+ * Print an error.
+ *
+ * @param key
+ * The key of the error.
+ *
+ * @param args
+ * The arguments for the error.
+ */
public void printError(ErrorKey key, String... args) {
switch(mode) {
case WIZARD:
@@ -312,6 +448,9 @@ public class Errors {
}
}
+ /**
+ * The instance of the errors.
+ */
public final static Errors inst;
static {
diff --git a/dice-lang/src/bjc/dicelang/Evaluator.java b/dice-lang/src/bjc/dicelang/Evaluator.java
index 190e911..87c2153 100644
--- a/dice-lang/src/bjc/dicelang/Evaluator.java
+++ b/dice-lang/src/bjc/dicelang/Evaluator.java
@@ -20,6 +20,12 @@ import java.util.function.Consumer;
import static bjc.dicelang.Errors.ErrorKey.*;
import static bjc.dicelang.EvaluatorResult.Type.*;
+/**
+ * Evaluate DiceLang ASTs
+ *
+ * @author EVE
+ *
+ */
public class Evaluator {
private static enum CoerceSteps {
INTEGER, FLOAT;
@@ -39,6 +45,7 @@ public class Evaluator {
return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE, orig));
}
+ @SuppressWarnings("unused")
private static Node FAIL(Node orig) {
return new Node(Node.Type.RESULT, new EvaluatorResult(FAILURE, orig));
}
@@ -49,29 +56,48 @@ public class Evaluator {
private DiceLangEngine eng;
+ /**
+ * Create a new evaluator.
+ *
+ * @param en
+ * The engine.
+ */
public Evaluator(DiceLangEngine en) {
eng = en;
}
+ /**
+ * Evaluate a AST.
+ *
+ * @param comm
+ * The AST to evaluate.
+ *
+ * @return The result of the tree.
+ */
public EvaluatorResult evaluate(ITree<Node> comm) {
Context ctx = new Context();
ctx.isDebug = false;
ctx.thunk = (itr) -> {
- // Deliberately finish the iterator, but ignore results.
- // It's only for stepwise evaluation
- // but we don't know if stepping the iterator causes
- // something to happen
+ /**
+ * Deliberately finish the iterator, but ignore results.
+ * It's only for stepwise evaluation but we don't know
+ * if stepping the iterator causes something to happen.
+ *
+ */
while(itr.hasNext()) {
itr.next();
}
};
- return comm.topDownTransform(this::pickEvaluationType, (node) -> this.evaluateNode(node, ctx))
- .getHead().resultVal;
+ ITree<Node> res = comm.topDownTransform(this::pickEvaluationType,
+ (node) -> this.evaluateNode(node, ctx));
+
+ return res.getHead().resultVal;
}
- // @FIXME Something's broken with step evaluation
+ // FIXME Something's broken with step evaluation
+ @SuppressWarnings("javadoc")
public Iterator<ITree<Node>> stepDebug(ITree<Node> comm) {
Context ctx = new Context();
@@ -124,7 +150,7 @@ public class Evaluator {
switch(ast.getHead().operatorType) {
/*
- * @TODO move coercing to its own class
+ * TODO move coercing to its own class
*/
case COERCE:
ITree<Node> toCoerce = ast.getChild(0);
@@ -146,9 +172,12 @@ public class Evaluator {
} else {
nChild = new Tree<>(new Node(Node.Type.RESULT, evaluate(child)));
- if(nChild != null) {
- ctx.thunk.accept(new SingleIterator<>(nChild));
- }
+ ctx.thunk.accept(new SingleIterator<>(nChild));
+ }
+
+ if(nChild == null) {
+ Errors.inst.printError(EK_EVAL_INVNODE);
+ return new Tree<>(FAIL(ast));
}
Node childNode = nChild.getHead();
@@ -171,7 +200,9 @@ public class Evaluator {
nd.resultVal = new EvaluatorResult(FLOAT, (double) res.intVal);
}
default:
- // Do nothing
+ /*
+ * Do nothing
+ */
break;
}
@@ -237,7 +268,7 @@ public class Evaluator {
}
private ITree<Node> evaluateStringBinary(Token.Type op, EvaluatorResult left, EvaluatorResult right,
- Context ctx) {
+ @SuppressWarnings("unused") Context ctx) {
if(left.type != STRING) {
Errors.inst.printError(EK_EVAL_INVSTRING, left.type.toString());
return new Tree<>(FAIL(left));
@@ -274,7 +305,7 @@ public class Evaluator {
}
private ITree<Node> evaluateDiceBinary(Token.Type op, EvaluatorResult left, EvaluatorResult right,
- Context ctx) {
+ @SuppressWarnings("unused") Context ctx) {
EvaluatorResult res = null;
switch(op) {
@@ -337,7 +368,7 @@ public class Evaluator {
}
private ITree<Node> evaluateMathBinary(Token.Type op, EvaluatorResult left, EvaluatorResult right,
- Context ctx) {
+ @SuppressWarnings("unused") Context ctx) {
if(left.type == STRING || right.type == STRING) {
Errors.inst.printError(EK_EVAL_STRINGMATH);
return new Tree<>(FAIL());
@@ -468,7 +499,7 @@ public class Evaluator {
return new Tree<>(new Node(Node.Type.RESULT, res));
}
- private ITree<Node> evaluateTokenRef(Token tk, Context ctx) {
+ private ITree<Node> evaluateTokenRef(Token tk, @SuppressWarnings("unused") Context ctx) {
EvaluatorResult res = null;
switch(tk.type) {
diff --git a/dice-lang/src/bjc/dicelang/EvaluatorResult.java b/dice-lang/src/bjc/dicelang/EvaluatorResult.java
index 276e801..09d7687 100644
--- a/dice-lang/src/bjc/dicelang/EvaluatorResult.java
+++ b/dice-lang/src/bjc/dicelang/EvaluatorResult.java
@@ -1,97 +1,211 @@
-package bjc.dicelang;
-
-import bjc.dicelang.dice.Die;
-import bjc.dicelang.dice.DieExpression;
-import bjc.dicelang.dice.DieList;
-import bjc.utils.data.ITree;
-import bjc.utils.data.Tree;
-
-public class EvaluatorResult {
- public static enum Type {
- FAILURE, INT, FLOAT, DICE, STRING
- }
-
- public final EvaluatorResult.Type type;
-
- // These may or may not have values based
- // off of the result type
- public long intVal;
- public double floatVal;
- public DieExpression diceVal;
- public String stringVal;
-
- // Original node data
- public ITree<Node> origVal;
-
- public EvaluatorResult(EvaluatorResult.Type typ) {
- type = typ;
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, ITree<Node> orig) {
- this(typ);
-
- origVal = orig;
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, Node orig) {
- this(typ, new Tree<>(orig));
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, EvaluatorResult orig) {
- this(typ, new Node(Node.Type.RESULT, orig));
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, long iVal) {
- this(typ);
-
- intVal = iVal;
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, double dVal) {
- this(typ);
-
- floatVal = dVal;
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, DieExpression dVal) {
- this(typ);
-
- diceVal = dVal;
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, Die dVal) {
- this(typ);
-
- diceVal = new DieExpression(dVal);
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, DieList dVal) {
- this(typ);
-
- diceVal = new DieExpression(dVal);
- }
-
- public EvaluatorResult(EvaluatorResult.Type typ, String strang) {
- this(typ);
-
- stringVal = strang;
- }
-
- @Override
- public String toString() {
- 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();
- }
- }
+package bjc.dicelang;
+
+import bjc.dicelang.dice.Die;
+import bjc.dicelang.dice.DieExpression;
+import bjc.dicelang.dice.DieList;
+import bjc.utils.data.ITree;
+import bjc.utils.data.Tree;
+
+/**
+ * The result from the evaluator.
+ *
+ * @author EVE
+ *
+ */
+public class EvaluatorResult {
+ /**
+ * The type of the result.
+ *
+ * @author EVE
+ *
+ */
+ public static enum Type {
+ /**
+ * The type of a failure.
+ */
+ FAILURE,
+ /**
+ * The type of an integer.
+ */
+ INT,
+ /**
+ * The type of a float.
+ */
+ FLOAT,
+ /**
+ * The type of a dice.
+ */
+ DICE,
+ /**
+ * The type of a string.
+ */
+ STRING
+ }
+
+ /**
+ * The type of the result.
+ */
+ public final EvaluatorResult.Type type;
+
+ // These may or may not have values based
+ // off of the result type
+ /**
+ * The integer value of the result.
+ */
+ public long intVal;
+ /**
+ * The float value of the result.
+ */
+ public double floatVal;
+ /**
+ * The dice value of the result.
+ */
+ public DieExpression diceVal;
+ /**
+ * The string value of the result.
+ */
+ public String stringVal;
+
+ /**
+ * Original node data
+ */
+ public ITree<Node> origVal;
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * The type of the result.
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ) {
+ type = typ;
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * The type of the result.
+ *
+ * @param orig
+ * The original value of the result.
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, ITree<Node> orig) {
+ this(typ);
+
+ origVal = orig;
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * The type of the result.
+ *
+ * @param orig
+ * The original value of the result.
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, Node orig) {
+ this(typ, new Tree<>(orig));
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * @param orig
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, EvaluatorResult orig) {
+ this(typ, new Node(Node.Type.RESULT, orig));
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * @param iVal
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, long iVal) {
+ this(typ);
+
+ intVal = iVal;
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * @param dVal
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, double dVal) {
+ this(typ);
+
+ floatVal = dVal;
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * @param dVal
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, DieExpression dVal) {
+ this(typ);
+
+ diceVal = dVal;
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * @param dVal
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, Die dVal) {
+ this(typ);
+
+ diceVal = new DieExpression(dVal);
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * @param dVal
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, DieList dVal) {
+ this(typ);
+
+ diceVal = new DieExpression(dVal);
+ }
+
+ /**
+ * Create a new result.
+ *
+ * @param typ
+ * @param strang
+ */
+ public EvaluatorResult(EvaluatorResult.Type typ, String strang) {
+ this(typ);
+
+ stringVal = strang;
+ }
+
+ @Override
+ public String toString() {
+ 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();
+ }
+ }
} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/Node.java b/dice-lang/src/bjc/dicelang/Node.java
index df966ba..f58cb14 100644
--- a/dice-lang/src/bjc/dicelang/Node.java
+++ b/dice-lang/src/bjc/dicelang/Node.java
@@ -1,5 +1,6 @@
package bjc.dicelang;
+@SuppressWarnings("javadoc")
public class Node {
public static enum Type {
ROOT, TOKREF, UNARYOP, BINOP, GROUP, OGROUP, RESULT
@@ -78,4 +79,9 @@ public class Node {
return true;
}
}
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
}
diff --git a/dice-lang/src/bjc/dicelang/Parser.java b/dice-lang/src/bjc/dicelang/Parser.java
index bfb7a03..bef4072 100644
--- a/dice-lang/src/bjc/dicelang/Parser.java
+++ b/dice-lang/src/bjc/dicelang/Parser.java
@@ -12,11 +12,31 @@ import static bjc.dicelang.Node.Type.*;
import static bjc.dicelang.Token.Type.CBRACE;
import static bjc.dicelang.Token.Type.CBRACKET;
+/**
+ * Parse a series of tree into tokens.
+ *
+ * @author EVE
+ *
+ */
public class Parser {
+ /**
+ * Create a new parser.
+ */
public Parser() {
}
+ /**
+ * Parse a series of tokens to a forest of ASTs.
+ *
+ * @param tokens
+ * The list of tokens to parse.
+ *
+ * @param results
+ * The place to set results.
+ *
+ * @return Whether or not the parse was successful.
+ */
public boolean parseTokens(IList<Token> tokens, IList<ITree<Node>> results) {
Deque<ITree<Node>> working = new LinkedList<>();
@@ -130,7 +150,8 @@ public class Parser {
groupNode = new Tree<>(new Node(GROUP, Node.GroupType.ARRAY));
break;
default:
- break;
+ Errors.inst.printError(EK_PARSE_UNCLOSE, tk.type.toString());
+ return false;
}
Token matching = null;
diff --git a/dice-lang/src/bjc/dicelang/Shunter.java b/dice-lang/src/bjc/dicelang/Shunter.java
index 4faabb1..3adfd5b 100644
--- a/dice-lang/src/bjc/dicelang/Shunter.java
+++ b/dice-lang/src/bjc/dicelang/Shunter.java
@@ -13,6 +13,12 @@ import java.util.Set;
import static bjc.dicelang.Errors.ErrorKey.*;
import static bjc.dicelang.Token.Type.*;
+/**
+ * Shunt a set of infix tokens to postfix tokens.
+ *
+ * @author EVE
+ *
+ */
public class Shunter {
// The binary operators and their
// priorities
@@ -40,11 +46,26 @@ public class Shunter {
// applied to operator tokens and yield data tokens
Set<Token.Type> unaryGerunds;
+ /**
+ * Precedence for math operators.
+ */
public final int MATH_PREC = 30;
+ /**
+ * Precedence for dice operators.
+ */
public final int DICE_PREC = 20;
+ /**
+ * Precedence for string operators.
+ */
public final int STR_PREC = 10;
+ /**
+ * Precedence for expression operators.
+ */
public final int EXPR_PREC = 0;
+ /**
+ * Create a new shunter.
+ */
public Shunter() {
ops = new FunctionalMap<>();
@@ -78,6 +99,17 @@ public class Shunter {
ops.put(BIND, 1 + EXPR_PREC);
}
+ /**
+ * Shunt a set of tokens from infix to postfix.
+ *
+ * @param tks
+ * The tokens to input.
+ *
+ * @param returned
+ * The postfix tokens.
+ *
+ * @return Whether or not the shunt succeeded.
+ */
public boolean shuntTokens(IList<Token> tks, IList<Token> returned) {
Deque<Token> opStack = new LinkedList<>();
Deque<Token> unaryOps = new LinkedList<>();
@@ -113,7 +145,7 @@ public class Shunter {
}
private boolean shuntToken(Token tk, Deque<Token> opStack, Deque<Token> unaryStack, Deque<Token> currReturned,
- Deque<Token> feed) {
+ @SuppressWarnings("unused") Deque<Token> feed) {
if(unaryStack.size() != 0) {
if(isUnary(tk)) {
unaryStack.add(tk);
@@ -195,7 +227,8 @@ public class Shunter {
matching = new Token(OBRACE, tk.intValue);
break;
default:
- break;
+ Errors.inst.printError(EK_SHUNT_NOGROUP);
+ return false;
}
if(!opStack.contains(matching)) {
diff --git a/dice-lang/src/bjc/dicelang/Token.java b/dice-lang/src/bjc/dicelang/Token.java
index 71968a7..1e5f356 100644
--- a/dice-lang/src/bjc/dicelang/Token.java
+++ b/dice-lang/src/bjc/dicelang/Token.java
@@ -4,8 +4,9 @@ import bjc.dicelang.dice.DieExpression;
import bjc.utils.funcdata.IList;
/**
- * Lexer token
+ * Lexer token.
*/
+@SuppressWarnings("javadoc")
public class Token {
public final static Token NIL_TOKEN = new Token(Type.NIL);
@@ -125,4 +126,10 @@ public class Token {
return false;
}
}
+
+ @Override
+ public int hashCode() {
+ // TODO Auto-generated method stub
+ return super.hashCode();
+ }
}
diff --git a/dice-lang/src/bjc/dicelang/Tokenizer.java b/dice-lang/src/bjc/dicelang/Tokenizer.java
index 2208f00..8c1d53b 100644
--- a/dice-lang/src/bjc/dicelang/Tokenizer.java
+++ b/dice-lang/src/bjc/dicelang/Tokenizer.java
@@ -1,158 +1,159 @@
-package bjc.dicelang;
-
-import bjc.dicelang.dice.DiceBox;
-import bjc.utils.funcdata.FunctionalMap;
-import bjc.utils.funcdata.IMap;
-import bjc.utils.funcutils.StringUtils;
-import bjc.utils.parserutils.TokenUtils;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static bjc.dicelang.Errors.ErrorKey.EK_TOK_INVBASE;
-import static bjc.dicelang.Errors.ErrorKey.EK_TOK_INVFLEX;
-import static bjc.dicelang.Errors.ErrorKey.EK_TOK_UNGROUP;
-import static bjc.dicelang.Token.Type.*;
-
-public class Tokenizer {
- // Literal tokens for tokenization
- private IMap<String, Token.Type> litTokens;
-
- private DiceLangEngine eng;
-
- private int nextSym = 0;
-
- public Tokenizer(DiceLangEngine engine) {
- eng = engine;
-
- litTokens = new FunctionalMap<>();
-
- litTokens.put("+", ADD);
- litTokens.put("-", SUBTRACT);
- litTokens.put("*", MULTIPLY);
- litTokens.put("/", DIVIDE);
- litTokens.put("//", IDIVIDE);
- litTokens.put("sd", DICESCALAR);
- litTokens.put("df", DICEFUDGE);
- litTokens.put("dg", DICEGROUP);
- litTokens.put("dc", DICECONCAT);
- litTokens.put("dl", DICELIST);
- litTokens.put("=>", LET);
- litTokens.put(":=", BIND);
- litTokens.put(".+.", STRCAT);
- litTokens.put(".*.", STRREP);
- litTokens.put(",", GROUPSEP);
- litTokens.put("crc", COERCE);
- }
-
- public Token lexToken(String token, IMap<String, String> stringLts) {
- if(token.equals("")) return null;
-
- Token tk = Token.NIL_TOKEN;
-
- if(litTokens.containsKey(token)) {
- tk = new Token(litTokens.get(token));
- } else {
- switch(token.charAt(0)) {
- case '(':
- case ')':
- case '[':
- case ']':
- case '{':
- case '}':
- tk = tokenizeGrouping(token);
- break;
- default:
- tk = tokenizeLiteral(token, stringLts);
- }
- }
-
- return tk;
- }
-
- private Token tokenizeGrouping(String token) {
- Token tk = Token.NIL_TOKEN;
-
- if(StringUtils.containsOnly(token, "\\" + token.charAt(0))) {
- switch(token.charAt(0)) {
- 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;
- }
- }
-
- return tk;
- }
-
- private Pattern hexadecimalMatcher = Pattern.compile("\\A[\\-\\+]?0x[0-9A-Fa-f]+\\Z");
- private Pattern flexadecimalMatcher = Pattern.compile("\\A[\\-\\+]?[0-9][0-9A-Za-z]+B\\d{1,2}\\Z");
- private Pattern stringLitMatcher = Pattern.compile("\\AstringLiteral(\\d+)\\Z");
-
- private Token tokenizeLiteral(String token, IMap<String, String> stringLts) {
- Token tk = Token.NIL_TOKEN;
-
- if(TokenUtils.isInt(token)) {
- tk = new Token(INT_LIT, Long.parseLong(token));
- } else if(hexadecimalMatcher.matcher(token).matches()) {
- String newToken = token.substring(0, 1) + token.substring(token.indexOf('x'));
-
- tk = new Token(INT_LIT, Long.parseLong(newToken.substring(2).toUpperCase(), 16));
- } else if(flexadecimalMatcher.matcher(token).matches()) {
- int parseBase = Integer.parseInt(token.substring(token.lastIndexOf('B') + 1));
-
- if(parseBase < Character.MIN_RADIX || parseBase > Character.MAX_RADIX) {
- Errors.inst.printError(EK_TOK_INVBASE, Integer.toString(parseBase));
- return Token.NIL_TOKEN;
- }
-
- String flexNum = token.substring(0, token.lastIndexOf('B'));
-
- try {
- tk = new Token(INT_LIT, Long.parseLong(flexNum, parseBase));
- } catch(NumberFormatException nfex) {
- Errors.inst.printError(EK_TOK_INVFLEX, flexNum, Integer.toString(parseBase));
- return Token.NIL_TOKEN;
- }
- } else if(TokenUtils.isDouble(token)) {
- tk = new Token(FLOAT_LIT, Double.parseDouble(token));
- } else if(DiceBox.isValidExpression(token)) {
- tk = new Token(DICE_LIT, DiceBox.parseExpression(token));
- } else {
- Matcher stringLit = stringLitMatcher.matcher(token);
-
- if(stringLit.matches()) {
- int litNum = Integer.parseInt(stringLit.group(1));
-
- eng.addStringLiteral(litNum, stringLts.get(token));
- tk = new Token(STRING_LIT, litNum);
- } else {
- /*
- * Everything else is a symbol
- */
- eng.symTable.put(nextSym++, token);
-
- tk = new Token(VREF, nextSym - 1);
- }
- }
-
- return tk;
- }
-}
+package bjc.dicelang;
+
+import bjc.dicelang.dice.DiceBox;
+import bjc.utils.funcdata.FunctionalMap;
+import bjc.utils.funcdata.IMap;
+import bjc.utils.funcutils.StringUtils;
+import bjc.utils.parserutils.TokenUtils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static bjc.dicelang.Errors.ErrorKey.EK_TOK_INVBASE;
+import static bjc.dicelang.Errors.ErrorKey.EK_TOK_INVFLEX;
+import static bjc.dicelang.Errors.ErrorKey.EK_TOK_UNGROUP;
+import static bjc.dicelang.Token.Type.*;
+
+@SuppressWarnings("javadoc")
+public class Tokenizer {
+ // Literal tokens for tokenization
+ private IMap<String, Token.Type> litTokens;
+
+ private DiceLangEngine eng;
+
+ private int nextSym = 0;
+
+ public Tokenizer(DiceLangEngine engine) {
+ eng = engine;
+
+ litTokens = new FunctionalMap<>();
+
+ litTokens.put("+", ADD);
+ litTokens.put("-", SUBTRACT);
+ litTokens.put("*", MULTIPLY);
+ litTokens.put("/", DIVIDE);
+ litTokens.put("//", IDIVIDE);
+ litTokens.put("sd", DICESCALAR);
+ litTokens.put("df", DICEFUDGE);
+ litTokens.put("dg", DICEGROUP);
+ litTokens.put("dc", DICECONCAT);
+ litTokens.put("dl", DICELIST);
+ litTokens.put("=>", LET);
+ litTokens.put(":=", BIND);
+ litTokens.put(".+.", STRCAT);
+ litTokens.put(".*.", STRREP);
+ litTokens.put(",", GROUPSEP);
+ litTokens.put("crc", COERCE);
+ }
+
+ public Token lexToken(String token, IMap<String, String> stringLts) {
+ if(token.equals("")) return null;
+
+ Token tk = Token.NIL_TOKEN;
+
+ if(litTokens.containsKey(token)) {
+ tk = new Token(litTokens.get(token));
+ } else {
+ switch(token.charAt(0)) {
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ tk = tokenizeGrouping(token);
+ break;
+ default:
+ tk = tokenizeLiteral(token, stringLts);
+ }
+ }
+
+ return tk;
+ }
+
+ private Token tokenizeGrouping(String token) {
+ Token tk = Token.NIL_TOKEN;
+
+ if(StringUtils.containsOnly(token, "\\" + token.charAt(0))) {
+ switch(token.charAt(0)) {
+ 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;
+ }
+ }
+
+ return tk;
+ }
+
+ private Pattern hexadecimalMatcher = Pattern.compile("\\A[\\-\\+]?0x[0-9A-Fa-f]+\\Z");
+ private Pattern flexadecimalMatcher = Pattern.compile("\\A[\\-\\+]?[0-9][0-9A-Za-z]+B\\d{1,2}\\Z");
+ private Pattern stringLitMatcher = Pattern.compile("\\AstringLiteral(\\d+)\\Z");
+
+ private Token tokenizeLiteral(String token, IMap<String, String> stringLts) {
+ Token tk = Token.NIL_TOKEN;
+
+ if(TokenUtils.isInt(token)) {
+ tk = new Token(INT_LIT, Long.parseLong(token));
+ } else if(hexadecimalMatcher.matcher(token).matches()) {
+ String newToken = token.substring(0, 1) + token.substring(token.indexOf('x'));
+
+ tk = new Token(INT_LIT, Long.parseLong(newToken.substring(2).toUpperCase(), 16));
+ } else if(flexadecimalMatcher.matcher(token).matches()) {
+ int parseBase = Integer.parseInt(token.substring(token.lastIndexOf('B') + 1));
+
+ if(parseBase < Character.MIN_RADIX || parseBase > Character.MAX_RADIX) {
+ Errors.inst.printError(EK_TOK_INVBASE, Integer.toString(parseBase));
+ return Token.NIL_TOKEN;
+ }
+
+ String flexNum = token.substring(0, token.lastIndexOf('B'));
+
+ try {
+ tk = new Token(INT_LIT, Long.parseLong(flexNum, parseBase));
+ } catch(@SuppressWarnings("unused") NumberFormatException nfex) {
+ Errors.inst.printError(EK_TOK_INVFLEX, flexNum, Integer.toString(parseBase));
+ return Token.NIL_TOKEN;
+ }
+ } else if(TokenUtils.isDouble(token)) {
+ tk = new Token(FLOAT_LIT, Double.parseDouble(token));
+ } else if(DiceBox.isValidExpression(token)) {
+ tk = new Token(DICE_LIT, DiceBox.parseExpression(token));
+ } else {
+ Matcher stringLit = stringLitMatcher.matcher(token);
+
+ if(stringLit.matches()) {
+ int litNum = Integer.parseInt(stringLit.group(1));
+
+ eng.addStringLiteral(litNum, stringLts.get(token));
+ tk = new Token(STRING_LIT, litNum);
+ } else {
+ /*
+ * Everything else is a symbol
+ */
+ eng.symTable.put(nextSym++, token);
+
+ tk = new Token(VREF, nextSym - 1);
+ }
+ }
+
+ return tk;
+ }
+}
diff --git a/dice-lang/src/bjc/dicelang/dice/DiceBox.java b/dice-lang/src/bjc/dicelang/dice/DiceBox.java
index 7a7e7c4..2147a06 100644
--- a/dice-lang/src/bjc/dicelang/dice/DiceBox.java
+++ b/dice-lang/src/bjc/dicelang/dice/DiceBox.java
@@ -15,26 +15,30 @@ public class DiceBox {
/**
* Parse a die expression from a string.
*
+ * @param expString
+ * The string to parse.
+ *
* @return The die expression from the string, or null if it wasn't one
*/
- public static DieExpression parseExpression(String exp) {
+ public static DieExpression parseExpression(String expString) {
/*
- * Only bother will valid expressions
+ * Only bother with valid expressions.
*/
- if(!isValidExpression(exp)) return null;
+ if(!isValidExpression(expString)) return null;
- if(scalarDiePattern.matcher(exp).matches()) {
+ if(scalarDiePattern.matcher(expString).matches()) {
/*
- * Parse scalar die
+ * Parse scalar die.
*/
- Die scal = new ScalarDie(Long.parseLong(exp.substring(0, exp.indexOf('s'))));
+ String dieString = expString.substring(0, expString.indexOf('s'));
+ Die scal = new ScalarDie(Long.parseLong(dieString));
return new DieExpression(scal);
- } else if(simpleDiePattern.matcher(exp).matches()) {
+ } else if(simpleDiePattern.matcher(expString).matches()) {
/*
- * Parse simple die groups
+ * Parse simple die groups.
*/
- String[] dieParts = exp.split("d");
+ String[] dieParts = expString.split("d");
long right = Long.parseLong(dieParts[1]);
if(dieParts[0].equals("")) {
@@ -47,61 +51,61 @@ public class DiceBox {
Die scal = new SimpleDie(Long.parseLong(dieParts[0]), right);
return new DieExpression(scal);
}
- } else if(fudgeDiePattern.matcher(exp).matches()) {
+ } else if(fudgeDiePattern.matcher(expString).matches()) {
/*
- * Parse fudge dice
+ * Parse fudge dice.
*/
- String nDice = exp.substring(0, exp.indexOf('d'));
+ String nDice = expString.substring(0, expString.indexOf('d'));
return new DieExpression(new FudgeDie(Long.parseLong(nDice)));
- } else if(compoundDiePattern.matcher(exp).matches()) {
+ } else if(compoundDiePattern.matcher(expString).matches()) {
/*
- * Parse compound die expressions
+ * Parse compound die expressions.
*/
- String[] dieParts = exp.split("c");
+ String[] dieParts = expString.split("c");
DieExpression left = parseExpression(dieParts[0]);
DieExpression right = parseExpression(dieParts[1]);
return new DieExpression(new CompoundDie(left.scalar, right.scalar));
- } else if(compoundingDiePattern.matcher(exp).matches()) {
+ } else if(compoundingDiePattern.matcher(expString).matches()) {
/*
- * Parse compounding die expressions
+ * Parse compounding die expressions.
*/
- String[] dieParts = exp.split("!!");
+ String[] dieParts = expString.split("!!");
DieExpression left = parseExpression(dieParts[0]);
Predicate<Long> right = deriveCond(dieParts[1]);
Die scal = new CompoundingDie(left.scalar, right, dieParts[1]);
return new DieExpression(scal);
- } else if(explodingDiePattern.matcher(exp).matches()) {
+ } else if(explodingDiePattern.matcher(expString).matches()) {
/*
- * Parse exploding die expressions
+ * Parse exploding die expressions.
*/
- String[] dieParts = exp.split("!");
+ String[] dieParts = expString.split("!");
DieExpression left = parseExpression(dieParts[0]);
Predicate<Long> right = deriveCond(dieParts[1]);
DieList lst = new ExplodingDice(left.scalar, right, dieParts[1], false);
return new DieExpression(lst);
- } else if(penetratingDiePattern.matcher(exp).matches()) {
+ } else if(penetratingDiePattern.matcher(expString).matches()) {
/*
- * Parse penetrating die expressions
+ * Parse penetrating die expressions.
*/
- String[] dieParts = exp.split("p!");
+ String[] dieParts = expString.split("p!");
DieExpression left = parseExpression(dieParts[0]);
Predicate<Long> right = deriveCond(dieParts[1]);
DieList lst = new ExplodingDice(left.scalar, right, dieParts[1], true);
return new DieExpression(lst);
- } else if(diceListPattern.matcher(exp).matches()) {
+ } else if(diceListPattern.matcher(expString).matches()) {
/*
- * Parse simple die lists
+ * Parse simple die lists.
*/
- String[] dieParts = exp.split("dl");
+ String[] dieParts = expString.split("dl");
DieExpression left = parseExpression(dieParts[0]);
DieExpression right = parseExpression(dieParts[1]);
@@ -114,11 +118,11 @@ public class DiceBox {
}
/*
- * The strings and patterns used for matching
+ * The strings and patterns used for matching.
*/
/*
- * Defines a comparison predicate
+ * Defines a comparison predicate.
*/
private static final String comparePoint = "[<>=]\\d+";
@@ -193,7 +197,7 @@ public class DiceBox {
/*
* Defines a die list.
*
- * This is an array of dice of the specified size
+ * 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");
@@ -204,7 +208,7 @@ public class DiceBox {
* @param exp
* The string to check validity of.
*
- * @return Whether or not the string is a valid command
+ * @return Whether or not the string is a valid command.
*/
public static boolean isValidExpression(String exp) {
if(scalarDiePattern.matcher(exp).matches())
diff --git a/dice-lang/src/bjc/dicelang/dice/DieExpression.java b/dice-lang/src/bjc/dicelang/dice/DieExpression.java
index 576660d..92625eb 100644
--- a/dice-lang/src/bjc/dicelang/dice/DieExpression.java
+++ b/dice-lang/src/bjc/dicelang/dice/DieExpression.java
@@ -1,64 +1,66 @@
-package bjc.dicelang.dice;
-
-import java.util.Arrays;
-
-/**
- * Represents either a die or a die list
- *
- * @author Ben Culkin
- */
-public class DieExpression {
- /**
- * Is this expression a list?
- */
- public final boolean isList;
-
- /**
- * The scalar value in this expression, if there is one.
- */
- public Die scalar;
- /**
- * The list value in this expression, if there is one.
- */
- public DieList list;
-
- /**
- * Create a scalar die expression.
- *
- * @param scal
- * The scalar value of this expression.
- */
- public DieExpression(Die scal) {
- isList = false;
- scalar = scal;
- }
-
- /**
- * Create a list die expression.
- *
- * @param lst
- * The list value of this expression.
- */
- public DieExpression(DieList lst) {
- isList = true;
- list = lst;
- }
-
- @Override
- public String toString() {
- if(isList)
- return list.toString();
- else
- return scalar.toString();
- }
-
- /**
- * Get the value of this expression as a string.
- */
- public String value() {
- if(isList)
- return Arrays.toString(list.roll());
- else
- return Long.toString(scalar.roll());
- }
-}
+package bjc.dicelang.dice;
+
+import java.util.Arrays;
+
+/**
+ * Represents either a die or a die list.
+ *
+ * @author Ben Culkin
+ */
+public class DieExpression {
+ /**
+ * Is this expression a list?
+ */
+ public final boolean isList;
+
+ /**
+ * The scalar value in this expression, if there is one.
+ */
+ public Die scalar;
+ /**
+ * The list value in this expression, if there is one.
+ */
+ public DieList list;
+
+ /**
+ * Create a scalar die expression.
+ *
+ * @param scal
+ * The scalar value of this expression.
+ */
+ public DieExpression(Die scal) {
+ isList = false;
+ scalar = scal;
+ }
+
+ /**
+ * Create a list die expression.
+ *
+ * @param lst
+ * The list value of this expression.
+ */
+ public DieExpression(DieList lst) {
+ isList = true;
+ list = lst;
+ }
+
+ @Override
+ public String toString() {
+ if(isList)
+ return list.toString();
+ else
+ return scalar.toString();
+ }
+
+ /**
+ * Get the value of this expression as a string.
+ *
+ * @return The value of the expression as a string.
+ */
+ public String value() {
+ if(isList)
+ return Arrays.toString(list.roll());
+ else
+ return Long.toString(scalar.roll());
+ }
+}
diff --git a/dice-lang/src/bjc/dicelang/dice/DieList.java b/dice-lang/src/bjc/dicelang/dice/DieList.java
index 5cabc77..48006d4 100644
--- a/dice-lang/src/bjc/dicelang/dice/DieList.java
+++ b/dice-lang/src/bjc/dicelang/dice/DieList.java
@@ -1,32 +1,31 @@
-package bjc.dicelang.dice;
-
-/**
- * Represents a group of dice.
- *
- * @author Ben Culkin.
- */
-public interface DieList {
- /**
- * Can this list be optimized?
- *
- * @return Whether or not this list cna be optimized.
- */
- boolean canOptimize();
-
- /**
- * Optimize this list, if it can be done.
- *
- * Invoking this on unoptimizable expression is undefined.
- *
- * @return The optimized form of this list.
- */
- long[] optimize();
-
- /**
- * Roll this group of dice.
- *
- * @param A
- * possible roll of this group.
- */
- long[] roll();
-}
+package bjc.dicelang.dice;
+
+/**
+ * Represents a group of dice.
+ *
+ * @author Ben Culkin.
+ */
+public interface DieList {
+ /**
+ * Can this list be optimized?
+ *
+ * @return Whether or not this list can be optimized.
+ */
+ boolean canOptimize();
+
+ /**
+ * Optimize this list, if it can be done.
+ *
+ * Invoking this on unoptimizable expression is undefined.
+ *
+ * @return The optimized form of this list.
+ */
+ long[] optimize();
+
+ /**
+ * Roll this group of dice.
+ *
+ * @return A possible roll of this group.
+ */
+ long[] roll();
+}
diff --git a/dice-lang/src/bjc/dicelang/dice/FudgeDie.java b/dice-lang/src/bjc/dicelang/dice/FudgeDie.java
index 0385239..5e5125f 100644
--- a/dice-lang/src/bjc/dicelang/dice/FudgeDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/FudgeDie.java
@@ -1,46 +1,64 @@
-package bjc.dicelang.dice;
-
-public class FudgeDie implements Die {
- private Die numDice;
-
- public FudgeDie(long nDice) {
- numDice = new ScalarDie(nDice);
- }
-
- public FudgeDie(Die nDice) {
- numDice = nDice;
- }
-
- @Override
- public boolean canOptimize() {
- return numDice.canOptimize() && numDice.optimize() == 0;
- }
-
- @Override
- public long optimize() {
- return 0;
- }
-
- @Override
- public long roll() {
- long res = 0;
-
- long nDice = numDice.roll();
-
- for(int i = 0; i < nDice; i++) {
- res += rollSingle();
- }
-
- return res;
- }
-
- @Override
- public long rollSingle() {
- return DiceBox.rng.nextInt(3) - 1;
- }
-
- @Override
- public String toString() {
- return numDice + "dF";
- }
-}
+package bjc.dicelang.dice;
+
+/**
+ * A fudge die, one that has -1, 0 and 1 as its sides.
+ *
+ * @author EVE
+ *
+ */
+public class FudgeDie implements Die {
+ private Die numDice;
+
+ /**
+ * Create a new fudge die.
+ *
+ * @param nDice
+ * The number of dice to roll.
+ */
+ public FudgeDie(long nDice) {
+ numDice = new ScalarDie(nDice);
+ }
+
+ /**
+ * Create a new fudge die.
+ *
+ * @param nDice
+ * The number of dice to roll.
+ */
+ public FudgeDie(Die nDice) {
+ numDice = nDice;
+ }
+
+ @Override
+ public boolean canOptimize() {
+ return numDice.canOptimize() && numDice.optimize() == 0;
+ }
+
+ @Override
+ public long optimize() {
+ return 0;
+ }
+
+ @Override
+ public long roll() {
+ long res = 0;
+
+ long nDice = numDice.roll();
+
+ for(int i = 0; i < nDice; i++) {
+ res += rollSingle();
+ }
+
+ return res;
+ }
+
+ @Override
+ public long rollSingle() {
+ return DiceBox.rng.nextInt(3) - 1;
+ }
+
+ @Override
+ public String toString() {
+ return numDice + "dF";
+ }
+}
diff --git a/dice-lang/src/bjc/dicelang/dice/MathDie.java b/dice-lang/src/bjc/dicelang/dice/MathDie.java
index 1d6b2fa..aba58a3 100644
--- a/dice-lang/src/bjc/dicelang/dice/MathDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/MathDie.java
@@ -1,80 +1,115 @@
-package bjc.dicelang.dice;
-
-public class MathDie implements Die {
- public static enum MathOp {
- ADD, SUBTRACT, MULTIPLY;
-
- @Override
- public String toString() {
- switch(this) {
- case ADD:
- return "+";
- case SUBTRACT:
- return "-";
- case MULTIPLY:
- return "*";
- default:
- return this.name();
- }
- }
- }
-
- private MathDie.MathOp type;
-
- private Die left;
- private Die right;
-
- public MathDie(MathDie.MathOp op, Die lft, Die rght) {
- type = op;
-
- left = lft;
- right = rght;
- }
-
- @Override
- public boolean canOptimize() {
- return left.canOptimize() && right.canOptimize();
- }
-
- private long performOp(long lft, long rght) {
- switch(type) {
- case ADD:
- return lft + rght;
- case SUBTRACT:
- return lft - rght;
- case MULTIPLY:
- return lft * rght;
- default:
- return 0;
- }
- }
-
- @Override
- public long optimize() {
- long lft = left.optimize();
- long rght = right.optimize();
-
- return performOp(lft, rght);
- }
-
- @Override
- public long roll() {
- long lft = left.roll();
- long rght = right.roll();
-
- return performOp(lft, rght);
- }
-
- @Override
- public long rollSingle() {
- long lft = left.rollSingle();
- long rght = right.rollSingle();
-
- return performOp(lft, rght);
- }
-
- @Override
- public String toString() {
- return left.toString() + " " + type.toString() + " " + right.toString();
- }
+package bjc.dicelang.dice;
+
+/**
+ * A die that represents two dice with an applied math operator.
+ *
+ * @author EVE
+ *
+ */
+public class MathDie implements Die {
+ /**
+ * The types of a math operator.
+ *
+ * @author EVE
+ *
+ */
+ public static enum MathOp {
+ /**
+ * Add two dice.
+ */
+ ADD,
+ /**
+ * Subtract two dice.
+ */
+ SUBTRACT,
+ /**
+ * Multiply two dice.
+ */
+ MULTIPLY;
+
+ @Override
+ public String toString() {
+ switch(this) {
+ case ADD:
+ return "+";
+ case SUBTRACT:
+ return "-";
+ case MULTIPLY:
+ return "*";
+ default:
+ return this.name();
+ }
+ }
+ }
+
+ private MathDie.MathOp type;
+
+ private Die left;
+ private Die right;
+
+ /**
+ * Create a new math die.
+ *
+ * @param op
+ * The operator to apply.
+ *
+ * @param lft
+ * The left operand.
+ *
+ * @param rght
+ * The right operand.
+ */
+ public MathDie(MathDie.MathOp op, Die lft, Die rght) {
+ type = op;
+
+ left = lft;
+ right = rght;
+ }
+
+ @Override
+ public boolean canOptimize() {
+ return left.canOptimize() && right.canOptimize();
+ }
+
+ private long performOp(long lft, long rght) {
+ switch(type) {
+ case ADD:
+ return lft + rght;
+ case SUBTRACT:
+ return lft - rght;
+ case MULTIPLY:
+ return lft * rght;
+ default:
+ return 0;
+ }
+ }
+
+ @Override
+ public long optimize() {
+ long lft = left.optimize();
+ long rght = right.optimize();
+
+ return performOp(lft, rght);
+ }
+
+ @Override
+ public long roll() {
+ long lft = left.roll();
+ long rght = right.roll();
+
+ return performOp(lft, rght);
+ }
+
+ @Override
+ public long rollSingle() {
+ long lft = left.rollSingle();
+ long rght = right.rollSingle();
+
+ return performOp(lft, rght);
+ }
+
+ @Override
+ public String toString() {
+ return left.toString() + " " + type.toString() + " " + right.toString();
+ }
} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/dice/ScalarDie.java b/dice-lang/src/bjc/dicelang/dice/ScalarDie.java
index b9c3eba..0cb9af1 100644
--- a/dice-lang/src/bjc/dicelang/dice/ScalarDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/ScalarDie.java
@@ -1,34 +1,46 @@
-package bjc.dicelang.dice;
-
-public class ScalarDie implements Die {
- private long val;
-
- public ScalarDie(long vl) {
- val = vl;
- }
-
- @Override
- public boolean canOptimize() {
- return true;
- }
-
- @Override
- public long optimize() {
- return val;
- }
-
- @Override
- public long roll() {
- return val;
- }
-
- @Override
- public long rollSingle() {
- return val;
- }
-
- @Override
- public String toString() {
- return Long.toString(val);
- }
+package bjc.dicelang.dice;
+
+/**
+ * A scalar die, that always returns a given number.
+ *
+ * @author EVE
+ *
+ */
+public class ScalarDie implements Die {
+ private long val;
+
+ /**
+ * Create a new scalar die with a set value.
+ *
+ * @param vl
+ * The value to use.
+ */
+ public ScalarDie(long vl) {
+ val = vl;
+ }
+
+ @Override
+ public boolean canOptimize() {
+ return true;
+ }
+
+ @Override
+ public long optimize() {
+ return val;
+ }
+
+ @Override
+ public long roll() {
+ return val;
+ }
+
+ @Override
+ public long rollSingle() {
+ return val;
+ }
+
+ @Override
+ public String toString() {
+ return Long.toString(val);
+ }
} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/dice/SimpleDie.java b/dice-lang/src/bjc/dicelang/dice/SimpleDie.java
index f8dd945..68050e0 100644
--- a/dice-lang/src/bjc/dicelang/dice/SimpleDie.java
+++ b/dice-lang/src/bjc/dicelang/dice/SimpleDie.java
@@ -1,68 +1,107 @@
-package bjc.dicelang.dice;
-
-public class SimpleDie implements Die {
- private Die numDice;
- private Die diceSize;
-
- public SimpleDie(long nDice, long size) {
- numDice = new ScalarDie(nDice);
- diceSize = new ScalarDie(size);
- }
-
- public SimpleDie(Die nDice, long size) {
- numDice = nDice;
- diceSize = new ScalarDie(size);
- }
-
- public SimpleDie(long nDice, Die size) {
- numDice = new ScalarDie(nDice);
- diceSize = size;
- }
-
- public SimpleDie(Die nDice, Die size) {
- numDice = nDice;
- diceSize = size;
- }
-
- @Override
- public boolean canOptimize() {
- if(diceSize.canOptimize() && diceSize.optimize() <= 1)
- return numDice.canOptimize();
- else
- return false;
- }
-
- @Override
- public long optimize() {
- long optSize = diceSize.optimize();
-
- if(optSize == 0)
- return 0;
- else
- return numDice.optimize();
- }
-
- @Override
- public long roll() {
- long total = 0;
-
- long nDice = numDice.roll();
- long dSize = diceSize.roll();
-
- for(int i = 0; i < nDice; i++) {
- total += Math.abs(DiceBox.rng.nextLong()) % dSize + 1;
- }
-
- return total;
- }
-
- @Override
- public long rollSingle() {
- return Math.abs(DiceBox.rng.nextLong()) % diceSize.roll() + 1;
- }
-
- @Override
- public String toString() {
- return numDice + "d" + diceSize;
- }
+package bjc.dicelang.dice;
+
+/**
+ * A simple group of dice.
+ *
+ * @author EVE
+ *
+ */
+public class SimpleDie implements Die {
+ private Die numDice;
+ private Die diceSize;
+
+ /**
+ * Create a new dice group.
+ *
+ * @param nDice
+ * The number of dice.
+ *
+ * @param size
+ * The size of the dice.
+ */
+ public SimpleDie(long nDice, long size) {
+ this(new ScalarDie(nDice), new ScalarDie(size));
+ }
+
+ /**
+ * Create a new dice group.
+ *
+ * @param nDice
+ * The number of dice.
+ *
+ * @param size
+ * The size of the dice.
+ */
+ public SimpleDie(Die nDice, long size) {
+ this(nDice, new ScalarDie(size));
+ }
+
+ /**
+ * Create a new dice group.
+ *
+ * @param nDice
+ * The number of dice.
+ *
+ * @param size
+ * The size of the dice.
+ */
+ public SimpleDie(long nDice, Die size) {
+ this(new ScalarDie(nDice), size);
+ }
+
+ /**
+ * Create a new dice group.
+ *
+ * @param nDice
+ * The number of dice.
+ *
+ * @param size
+ * The size of the dice.
+ */
+ public SimpleDie(Die nDice, Die size) {
+ numDice = nDice;
+ diceSize = size;
+ }
+
+ @Override
+ public boolean canOptimize() {
+ if(diceSize.canOptimize() && diceSize.optimize() <= 1)
+ return numDice.canOptimize();
+ else
+ return false;
+ }
+
+ @Override
+ public long optimize() {
+ long optSize = diceSize.optimize();
+
+ if(optSize == 0)
+ return 0;
+ else
+ return numDice.optimize();
+ }
+
+ @Override
+ public long roll() {
+ long total = 0;
+
+ long nDice = numDice.roll();
+ long dSize = diceSize.roll();
+
+ for(int i = 0; i < nDice; i++) {
+ total += Math.abs(DiceBox.rng.nextLong()) % dSize + 1;
+ }
+
+ return total;
+ }
+
+ @Override
+ public long rollSingle() {
+ return Math.abs(DiceBox.rng.nextLong()) % diceSize.roll() + 1;
+ }
+
+ @Override
+ public String toString() {
+ return numDice + "d" + diceSize;
+ }
} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java b/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java
index 54f8e7a..d5d8364 100644
--- a/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java
+++ b/dice-lang/src/bjc/dicelang/dice/SimpleDieList.java
@@ -1,51 +1,66 @@
-package bjc.dicelang.dice;
-
-public class SimpleDieList implements DieList {
- private Die numDice;
- private Die size;
-
- public SimpleDieList(Die nDice, Die sze) {
- numDice = nDice;
- size = sze;
- }
-
- @Override
- public boolean canOptimize() {
- if(size.canOptimize() && size.optimize() <= 1)
- return numDice.canOptimize();
- else
- return false;
- }
-
- @Override
- public long[] optimize() {
- int sze = (int) numDice.optimize();
- long res = size.optimize();
-
- long[] ret = new long[sze];
-
- for(int i = 0; i < sze; i++) {
- ret[i] = res;
- }
-
- return ret;
- }
-
- @Override
- public long[] roll() {
- int num = (int) numDice.roll();
-
- long[] ret = new long[num];
-
- for(int i = 0; i < num; i++) {
- ret[i] = size.roll();
- }
-
- return ret;
- }
-
- @Override
- public String toString() {
- return numDice.toString() + "dl" + size.toString();
- }
+package bjc.dicelang.dice;
+
+/**
+ * A simple list of dice.
+ *
+ * @author EVE
+ *
+ */
+public class SimpleDieList implements DieList {
+ private Die numDice;
+ private Die size;
+
+ /**
+ * Create a new list of dice.
+ *
+ * @param nDice
+ * The number of dice in the list.
+ *
+ * @param sze
+ * The size of dice in the list.
+ */
+ public SimpleDieList(Die nDice, Die sze) {
+ numDice = nDice;
+ size = sze;
+ }
+
+ @Override
+ public boolean canOptimize() {
+ if(size.canOptimize() && size.optimize() <= 1)
+ return numDice.canOptimize();
+ else
+ return false;
+ }
+
+ @Override
+ public long[] optimize() {
+ int sze = (int) numDice.optimize();
+ long res = size.optimize();
+
+ long[] ret = new long[sze];
+
+ for(int i = 0; i < sze; i++) {
+ ret[i] = res;
+ }
+
+ return ret;
+ }
+
+ @Override
+ public long[] roll() {
+ int num = (int) numDice.roll();
+
+ long[] ret = new long[num];
+
+ for(int i = 0; i < num; i++) {
+ ret[i] = size.roll();
+ }
+
+ return ret;
+ }
+
+ @Override
+ public String toString() {
+ return numDice.toString() + "dl" + size.toString();
+ }
} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/expr/Lexer.java b/dice-lang/src/bjc/dicelang/expr/Lexer.java
index 7c15884..3147463 100644
--- a/dice-lang/src/bjc/dicelang/expr/Lexer.java
+++ b/dice-lang/src/bjc/dicelang/expr/Lexer.java
@@ -3,7 +3,8 @@ package bjc.dicelang.expr;
import java.util.LinkedList;
import java.util.List;
-import bjc.utils.parserutils.splitter.SimpleTokenSplitter;
+import bjc.utils.funcdata.IList;
+import bjc.utils.parserutils.splitter.ConfigurableTokenSplitter;
/**
* Implements the lexer for simple expression operations.
@@ -12,18 +13,18 @@ import bjc.utils.parserutils.splitter.SimpleTokenSplitter;
*/
public class Lexer {
/*
- * Spliter we use
+ * Splitter we use.
*/
- private SimpleTokenSplitter split;
+ private ConfigurableTokenSplitter split;
/**
* Create a new expression lexer.
*/
public Lexer() {
- split = new SimpleTokenSplitter();
+ split = new ConfigurableTokenSplitter(true);
- split.addDelimiter("(", ")");
- split.addDelimiter("+", "-", "*", "/");
+ split.addSimpleDelimiters("(", ")");
+ split.addSimpleDelimiters("+", "-", "*", "/");
}
/**
@@ -31,8 +32,9 @@ public class Lexer {
*
* @param inp
* The input command.
+ *
* @param tks
- * The token state
+ * The token state.
*
* @return A series of infix tokens representing the command.
*/
@@ -42,11 +44,10 @@ public class Lexer {
List<Token> tokens = new LinkedList<>();
for(String spacedToken : spacedTokens) {
- String[] rawTokens = split.split(spacedToken);
+ IList<String> splitTokens = split.split(spacedToken);
+ IList<Token> rawTokens = splitTokens.map(tok -> tks.lexToken(tok, spacedToken));
- for(String tok : rawTokens) {
- tokens.add(tks.lexToken(tok, spacedToken));
- }
+ rawTokens.forEach(tokens::add);
}
return tokens.toArray(new Token[0]);
diff --git a/dice-lang/src/bjc/dicelang/expr/Parser.java b/dice-lang/src/bjc/dicelang/expr/Parser.java
index e806a6f..71a88fc 100644
--- a/dice-lang/src/bjc/dicelang/expr/Parser.java
+++ b/dice-lang/src/bjc/dicelang/expr/Parser.java
@@ -119,7 +119,7 @@ public class Parser {
if(ast.getChildrenCount() == 0)
/*
- * Handle leaf nodes
+ * Handle leaf nodes.
*/
return data.toExpr();
else {
@@ -150,4 +150,4 @@ public class Parser {
return leftExpr + " " + data.toExpr() + " " + rightExpr;
}
}
-}
+} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/expr/Shunter.java b/dice-lang/src/bjc/dicelang/expr/Shunter.java
index 5d8cb7c..bbece0f 100644
--- a/dice-lang/src/bjc/dicelang/expr/Shunter.java
+++ b/dice-lang/src/bjc/dicelang/expr/Shunter.java
@@ -39,7 +39,12 @@ public class Shunter {
* respecting their left associativity.
*/
int leftPriority = tok.type.operatorPriority;
- int rightPriority = curOp == null ? 0 : curOp.type.operatorPriority;
+
+ int rightPriority;
+ if(curOp == null)
+ rightPriority = 0;
+ else
+ rightPriority = curOp.type.operatorPriority;
boolean isHigherPrec = leftPriority >= rightPriority;
@@ -53,7 +58,11 @@ public class Shunter {
curOp = opStack.peek();
leftPriority = tok.type.operatorPriority;
- rightPriority = curOp == null ? 0 : curOp.type.operatorPriority;
+
+ if(curOp == null)
+ rightPriority = 0;
+ else
+ rightPriority = curOp.type.operatorPriority;
isHigherPrec = leftPriority >= rightPriority;
}
@@ -65,7 +74,8 @@ public class Shunter {
Token curOp = opStack.peek();
/*
- * Pop things until we find the matching paren.
+ * Pop things until we find the matching
+ * parenthesis.
*/
while(curOp.type != TokenType.OPAREN) {
Token tk = opStack.pop();
@@ -92,4 +102,4 @@ public class Shunter {
return postfixTokens.toArray(new Token[0]);
}
-}
+} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/expr/Token.java b/dice-lang/src/bjc/dicelang/expr/Token.java
index b02f6c9..2a73d0b 100644
--- a/dice-lang/src/bjc/dicelang/expr/Token.java
+++ b/dice-lang/src/bjc/dicelang/expr/Token.java
@@ -33,8 +33,10 @@ public class Token {
*
* @param type
* The type of this token.
+ *
* @param raw
* The string this token came from.
+ *
* @param toks
* The state for this token
*/
@@ -84,4 +86,4 @@ public class Token {
return "???";
}
}
-}
+} \ No newline at end of file
diff --git a/dice-lang/src/bjc/dicelang/expr/Tokens.java b/dice-lang/src/bjc/dicelang/expr/Tokens.java
index 08e7197..88bd99e 100644
--- a/dice-lang/src/bjc/dicelang/expr/Tokens.java
+++ b/dice-lang/src/bjc/dicelang/expr/Tokens.java
@@ -26,7 +26,7 @@ public class Tokens {
public final Map<Integer, String> symbolTable;
/*
- * Next index into the symbol table
+ * Next index into the symbol table.
*/
private int nextSym;
@@ -60,7 +60,7 @@ public class Tokens {
* Convert the string representation of a token into a token.
*
* @param tok
- * The string repr. of the token.
+ * The string representation of the token.
* @param raw
* The original string the token came from.
*
diff --git a/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java b/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java
index c0a8d86..7efcaf7 100644
--- a/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java
+++ b/dice-lang/src/bjc/dicelang/scl/StreamControlEngine.java
@@ -179,8 +179,15 @@ public class StreamControlEngine {
private Stack<Token> curStack;
+ @SuppressWarnings("unused")
private Map<String, Token> words;
+ /**
+ * Create a new stream control engine.
+ *
+ * @param eng
+ * The engine to control.
+ */
public StreamControlEngine(StreamEngine eng) {
this.eng = eng;
@@ -192,9 +199,9 @@ public class StreamControlEngine {
* Run a SCL program.
*
* @param tokens
- * The program to run
+ * The program to run.
*
- * @return Whether the program executed succesfully
+ * @return Whether the program executed successfully.
*/
public boolean runProgram(String[] tokens) {
for(int i = 0; i < tokens.length; i++) {
diff --git a/dice-lang/src/bjc/dicelang/scl/StreamEngine.java b/dice-lang/src/bjc/dicelang/scl/StreamEngine.java
index f8d6e09..26b99c4 100644
--- a/dice-lang/src/bjc/dicelang/scl/StreamEngine.java
+++ b/dice-lang/src/bjc/dicelang/scl/StreamEngine.java
@@ -71,10 +71,11 @@ public class StreamEngine {
}
/**
- * Process a possibly interleaved set of streams from toks into dest.
+ * Process a possibly interleaved set of streams.
*
* @param toks
* The raw token to read streams from.
+ *
* @param dest
* The list to write the final stream to.
*
@@ -120,10 +121,18 @@ public class StreamEngine {
return true;
}
+ /**
+ * Create a new stream.
+ */
public void newStream() {
streams.insertAfter(new FunctionalList<>());
}
+ /**
+ * Move to a stream to the right.
+ *
+ * @return Whether or not the move was successful.
+ */
public boolean rightStream() {
if(!streams.right()) {
Errors.inst.printError(EK_STRM_NONEX);
@@ -134,6 +143,11 @@ public class StreamEngine {
return true;
}
+ /**
+ * Move to a stream to the left.
+ *
+ * @return Whether or not the move was successful.
+ */
public boolean leftStream() {
if(!streams.left()) {
Errors.inst.printError(EK_STRM_NONEX);
@@ -144,6 +158,11 @@ public class StreamEngine {
return true;
}
+ /**
+ * Delete the current stream.
+ *
+ * @return Whether or not the delete succeeded.
+ */
public boolean deleteStream() {
if(streams.size() == 1) {
Errors.inst.printError(EK_STRM_LAST);
@@ -156,6 +175,11 @@ public class StreamEngine {
return true;
}
+ /**
+ * Merge the current stream into the previous stream.
+ *
+ * @return Whether or not the merge succeded.
+ */
public boolean mergeStream() {
if(streams.size() == 1) {
Errors.inst.printError(EK_STRM_LAST);
diff --git a/dice-lang/src/bjc/dicelang/util/ResourceLoader.java b/dice-lang/src/bjc/dicelang/util/ResourceLoader.java
index c8561dc..c9b65d7 100644
--- a/dice-lang/src/bjc/dicelang/util/ResourceLoader.java
+++ b/dice-lang/src/bjc/dicelang/util/ResourceLoader.java
@@ -1,42 +1,41 @@
-package bjc.dicelang.util;
-
-import bjc.dicelang.Errors;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import static bjc.dicelang.Errors.ErrorKey.EK_MISC_IOEX;
-
-/**
- * Load resources bundled with DiceLang
- *
- * @author EVE
- *
- */
-public class ResourceLoader {
- /**
- * Loads a .help file from the data/help directory.
- *
- * @param name
- * The name of the help file to load.
- *
- * @return The contents of the help file, or null if it could not be
- * opened
- */
- public static String[] loadHelpFile(String name) {
- URL fle = ResourceLoader.class.getResource("/data/help/" + name + ".help");
-
- try {
- return Files.lines(Paths.get(fle.toURI())).toArray(sze -> new String[sze]);
- } catch(IOException ioex) {
- Errors.inst.printError(EK_MISC_IOEX, fle.toString());
- } catch(URISyntaxException usex) {
- Errors.inst.printError(EK_MISC_IOEX, fle.toString());
- }
-
- return null;
- }
-}
+package bjc.dicelang.util;
+
+import bjc.dicelang.Errors;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static bjc.dicelang.Errors.ErrorKey.EK_MISC_IOEX;
+
+/**
+ * Load resources bundled with DiceLang.
+ *
+ * @author EVE
+ *
+ */
+public class ResourceLoader {
+ /**
+ * Loads a .help file from the data/help directory.
+ *
+ * @param name
+ * The name of the help file to load.
+ *
+ * @return The contents of the help file, or null if it could not be
+ * opened.
+ */
+ @SuppressWarnings("unused")
+ public static String[] loadHelpFile(String name) {
+ URL fle = ResourceLoader.class.getResource("/data/help/" + name + ".help");
+
+ try {
+ return Files.lines(Paths.get(fle.toURI())).toArray(sze -> new String[sze]);
+ } catch(IOException | URISyntaxException ioex) {
+ Errors.inst.printError(EK_MISC_IOEX, fle.toString());
+ }
+
+ return null;
+ }
+}