summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin J. Culkin <bjculkin@mix.wvu.edu>2018-05-29 15:02:15 -0300
committerBenjamin J. Culkin <bjculkin@mix.wvu.edu>2018-05-29 15:02:15 -0300
commitfbf0024a72e58b303bfa54dfd181b59ede935891 (patch)
tree82e69012cc92a76e0c743aeb01b8fef4605ae3a2
parent1898f53cc072befe2694b5af78b1b916bef3b450 (diff)
Error handling cleanup
Cleanup the way errors are handled, as well as add some additional debugging text.
-rw-r--r--src/main/java/bjc/dicelang/scl/Errors.java85
-rw-r--r--src/main/java/bjc/dicelang/scl/StreamControlEngine.java14
-rw-r--r--src/main/java/bjc/dicelang/scl/StreamEngine.java37
-rw-r--r--src/main/java/bjc/dicelang/scl/tokens/SCLToken.java3
4 files changed, 79 insertions, 60 deletions
diff --git a/src/main/java/bjc/dicelang/scl/Errors.java b/src/main/java/bjc/dicelang/scl/Errors.java
index 8d3faff..ef20086 100644
--- a/src/main/java/bjc/dicelang/scl/Errors.java
+++ b/src/main/java/bjc/dicelang/scl/Errors.java
@@ -1,5 +1,7 @@
package bjc.dicelang.scl;
+import java.util.Arrays;
+
/**
* Repository for error messages.
*
@@ -12,11 +14,17 @@ package bjc.dicelang.scl;
* This way of handling error messages is not easy to deal with. Something else
* needs to be done, but I'm not sure what at the moment.
*
+ * ADDENDA: 5/28/18 Ben Culkin
+ * The error messages were moved into ErrorKey, as well as checking how
+ * many arguments they expect. This is better than it was, but still mildly
+ * annoying.
*
*/
public class Errors {
/**
- * The types of error message.
+ * The types of error/warning message.
+ *
+ * Error messages are marked by starting with EK, warnings start with WK
*
* @author EVE
*
@@ -26,38 +34,50 @@ public class Errors {
/**
* Attempted to switch to a non-existant stream
*/
- EK_STRM_NONEX,
+ EK_STRM_NONEX("\tERROR: Fell off the stream list, attempting to move %s", 1),
/**
* Can't delete the last stream
*/
- EK_STRM_LAST,
+ EK_STRM_LAST("\tERROR: Cannot delete last remaining stream", 0),
/**
* Unknown stream command
*/
- EK_STRM_INVCOM,
+ EK_STRM_INVCOM("\tERROR: Unknown stream control command %s\n", 1),
+
+ /* SCL Warnings */
+ WK_SCL_WRDFAIL("\tWARNING: Execution of word %s failed\n", 1),
+
/* SCL Errors */
/**
* Unknown SCL token
*/
- EK_SCL_INVTOKEN,
+ EK_SCL_INVTOKEN("\tERROR: Unknown SCL token %s\n", 1),
/**
* Mismatched quote in SCL command
*/
- EK_SCL_MMQUOTE,
+ EK_SCL_MMQUOTE("\tERROR: Mismatched delimiter %s in SCL command\n", 1),
/**
* Stack underflow in SCL command
*/
- EK_SCL_SUNDERFLOW,
+ EK_SCL_SUNDERFLOW("\tERROR: Not enough items in stack for word %s (need at least %d)\n", 2),
/**
* Unknown word in SCL command
*/
- EK_SCL_UNWORD,
+ EK_SCL_UNWORD("\tERROR: Unknown word %s\n", 1),
/**
* Invalid argument to SCL command
*/
- EK_SCL_INVARG,
- }
+ EK_SCL_INVARG("\tERROR: Invalid argument to SCL command\n", 0);
+
+ public final String msg;
+ public final int argc;
+
+ private ErrorKey(String message, int argcount) {
+ msg = message;
+ argc = argcount;
+ }
+ }
/**
* The mode for the type of error messages to print out.
*
@@ -86,54 +106,27 @@ public class Errors {
* @param args
* The arguments for the error.
*/
- public void printError(final ErrorKey key, final String... args) {
+ public void printError(final ErrorKey key, final Object... args) {
switch(mode) {
case WIZARD:
- System.out.println("\t? " + key.ordinal());
+ System.out.printf("\t? %d %s\n", key.ordinal(), Arrays.deepToString(args));
break;
-
case DEV:
devError(key, args);
break;
-
default:
- System.out.println("\tERROR ERROR: Unknown error mode " + mode);
+ System.out.printf("\tERROR ERROR: Unknown error mode %s\n", mode);
}
}
- private static void devError(final ErrorKey key, final String[] args) {
- switch(key) {
- 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;
+ private static void devError(final ErrorKey key, final Object[] args) {
+ if(args.length != key.argc) {
+ System.out.printf("\tERROR ERROR: Incorrect # of format arguments (got %d, expected %d)\n", args.length, key.argc);
- 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;
-
- default:
- System.out.printf("\tERROR ERROR: Unknown error key %s\n", key);
+ return;
}
+
+ System.out.printf(key.msg, args);
}
/**
diff --git a/src/main/java/bjc/dicelang/scl/StreamControlEngine.java b/src/main/java/bjc/dicelang/scl/StreamControlEngine.java
index 5c2b4de..d48d593 100644
--- a/src/main/java/bjc/dicelang/scl/StreamControlEngine.java
+++ b/src/main/java/bjc/dicelang/scl/StreamControlEngine.java
@@ -27,6 +27,7 @@ import static bjc.dicelang.scl.tokens.WordType.*;
*
* This is a large enough class that it should maybe be split into subclasses.
*/
+
/**
* Runs a Stream Control Language (SCL) program.
*
@@ -108,7 +109,7 @@ public class StreamControlEngine {
case WORD:
/* Handle words. */
if (!handleWord((WordSCLToken) tok)) {
- System.out.printf("WARNING: Execution of word '%s' failed\n", tok);
+ Errors.inst.printError(WK_SCL_WRDFAIL, tok);
}
break;
@@ -183,7 +184,8 @@ public class StreamControlEngine {
break;
case DROP:
if (curStack.size() == 0) {
- Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.toString());
+ Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.toString(), 1);
+
return false;
}
curStack.drop();
@@ -196,7 +198,7 @@ public class StreamControlEngine {
break;
case NIP:
if (curStack.size() < 2) {
- Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.toString());
+ Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.toString(), 2);
return false;
}
curStack.nip();
@@ -223,7 +225,7 @@ public class StreamControlEngine {
private boolean handleDefine() {
if (curStack.size() < 2) {
- Errors.inst.printError(EK_SCL_SUNDERFLOW, "def");
+ Errors.inst.printError(EK_SCL_SUNDERFLOW, "def", 2);
return false;
}
@@ -256,7 +258,7 @@ public class StreamControlEngine {
final int n = (int) ((IntSCLToken) num).intVal;
if (curStack.size() < n) {
- Errors.inst.printError(EK_SCL_SUNDERFLOW, NNIP.toString());
+ Errors.inst.printError(EK_SCL_SUNDERFLOW, NNIP.toString(), n);
return false;
}
@@ -276,7 +278,7 @@ public class StreamControlEngine {
final int n = (int) ((IntSCLToken) num).intVal;
if (curStack.size() < n) {
- Errors.inst.printError(EK_SCL_SUNDERFLOW, NDROP.toString());
+ Errors.inst.printError(EK_SCL_SUNDERFLOW, NDROP.toString(), n);
return false;
}
diff --git a/src/main/java/bjc/dicelang/scl/StreamEngine.java b/src/main/java/bjc/dicelang/scl/StreamEngine.java
index 59c2121..ba1f029 100644
--- a/src/main/java/bjc/dicelang/scl/StreamEngine.java
+++ b/src/main/java/bjc/dicelang/scl/StreamEngine.java
@@ -30,11 +30,11 @@ public class StreamEngine {
public final boolean debug = true;
/* Our streams. */
- Tape<IList<String>> streams;
- IList<String> currStream;
+ private Tape<IList<String>> streams;
+ private IList<String> currStream;
/* Saved streams */
- TapeLibrary<IList<String>> savedStreams;
+ private TapeLibrary<IList<String>> savedStreams;
/* Handler for SCL programs */
private final StreamControlEngine scleng;
@@ -56,6 +56,9 @@ public class StreamEngine {
commands.put('L', (eng) -> {
String[] arr = eng.currStream.toArray(new String[0]);
+ if(eng.debug)
+ System.out.printf("\tDEBUG: Executing '%s' as SCL program\n", eng.currStream);
+
boolean succ = eng.scleng.runProgram(arr);
return succ;
@@ -119,6 +122,8 @@ public class StreamEngine {
/* Process stream commands. */
if(tk.startsWith("{@S") && !quoteMode) {
if(tk.equals("{@SQ}")) {
+ if(debug)
+ System.out.println("\tDEBUG: Enabling quote mode\n");
/* Start quoting. */
quoteMode = true;
} else if(!processCommand(tk)) {
@@ -126,6 +131,8 @@ public class StreamEngine {
}
} else {
if(tk.equals("{@SU}")) {
+ if(debug)
+ System.out.println("\tDEBUG: Disabling quote mode\n");
/* Stop quoting. */
quoteMode = false;
} else if(tk.startsWith("\\") && tk.endsWith("{@SU}")) {
@@ -157,7 +164,7 @@ public class StreamEngine {
*/
public boolean rightStream() {
if(!streams.right()) {
- Errors.inst.printError(EK_STRM_NONEX);
+ Errors.inst.printError(EK_STRM_NONEX, "right");
return false;
}
@@ -172,7 +179,7 @@ public class StreamEngine {
*/
public boolean leftStream() {
if(!streams.left()) {
- Errors.inst.printError(EK_STRM_NONEX);
+ Errors.inst.printError(EK_STRM_NONEX, "left");
return false;
}
@@ -210,11 +217,26 @@ public class StreamEngine {
final IList<String> stringLit = streams.remove();
currStream = streams.item();
- currStream.add(ListUtils.collapseTokens(stringLit, " "));
+
+ final String merg = ListUtils.collapseTokens(stringLit, "");
+
+ if(debug)
+ System.out.printf("\tDEBUG: Merging string '%s'\n", merg);
+
+ currStream.add(merg);
return true;
}
+ /*
+ * Process an SCL command.
+ *
+ * These are single-character requests, but they can be chorded
+ * together.
+ *
+ * For example, the command {@SM} executes the M command, while the
+ * command {@SNS} would execute the N command, then the S command.
+ */
private boolean processCommand(final String tk) {
char[] comms = null;
@@ -231,6 +253,7 @@ public class StreamEngine {
for(final char comm : comms) {
boolean succ = commands.getOrDefault(comm, (eng) -> {
Errors.inst.printError(EK_STRM_INVCOM, tk);
+
return false;
}).test(this);
@@ -239,4 +262,4 @@ public class StreamEngine {
return true;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/bjc/dicelang/scl/tokens/SCLToken.java b/src/main/java/bjc/dicelang/scl/tokens/SCLToken.java
index 4d4987f..1075ab8 100644
--- a/src/main/java/bjc/dicelang/scl/tokens/SCLToken.java
+++ b/src/main/java/bjc/dicelang/scl/tokens/SCLToken.java
@@ -45,6 +45,7 @@ public class SCLToken {
return new FloatSCLToken(Double.parseDouble(token));
} else {
Errors.inst.printError(EK_SCL_INVTOKEN, token);
+
return null;
}
}
@@ -95,4 +96,4 @@ public class SCLToken {
public String toString() {
return "SCLToken [type=" + type + "]";
}
-} \ No newline at end of file
+}