summaryrefslogtreecommitdiff
path: root/base/src
diff options
context:
space:
mode:
authorstudent <student@localhost>2018-02-12 12:01:53 -0500
committerstudent <student@localhost>2018-02-12 12:01:53 -0500
commitc25b68c6b24d86b7d1169ad4ec1e619d79a2b38d (patch)
treedc9579836d6856cf93ae7f682446a4e69a94e37f /base/src
parentd7af27dab45dd6f82c27519e6b4fd2faa162f884 (diff)
Split SCLToken into subclasses.
Instead of one class with a lot of fields whose state varies based on an enum, we now have a hierarchy of classes that does the same in a more obvious manner.
Diffstat (limited to 'base/src')
-rw-r--r--base/src/bjc/dicelang/scl/BooleanSCLToken.java39
-rw-r--r--base/src/bjc/dicelang/scl/FloatSCLToken.java41
-rw-r--r--base/src/bjc/dicelang/scl/IntSCLToken.java18
-rw-r--r--base/src/bjc/dicelang/scl/SCLToken.java140
-rw-r--r--base/src/bjc/dicelang/scl/StreamControlEngine.java51
-rw-r--r--base/src/bjc/dicelang/scl/StringSCLToken.java46
-rw-r--r--base/src/bjc/dicelang/scl/WordSCLToken.java38
-rw-r--r--base/src/bjc/dicelang/scl/WordsSCLToken.java18
8 files changed, 276 insertions, 115 deletions
diff --git a/base/src/bjc/dicelang/scl/BooleanSCLToken.java b/base/src/bjc/dicelang/scl/BooleanSCLToken.java
new file mode 100644
index 0000000..5f89ce0
--- /dev/null
+++ b/base/src/bjc/dicelang/scl/BooleanSCLToken.java
@@ -0,0 +1,39 @@
+package bjc.dicelang.scl;
+
+public class BooleanSCLToken extends SCLToken {
+ /* Used for BLIT */
+ public boolean boolVal;
+
+ public BooleanSCLToken(boolean val) {
+ super(Type.BLIT);
+
+ boolVal = val;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + (boolVal ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BooleanSCLToken other = (BooleanSCLToken) obj;
+ if (boolVal != other.boolVal)
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "BooleanSCLToken [boolVal=" + boolVal + "]";
+ }
+}
diff --git a/base/src/bjc/dicelang/scl/FloatSCLToken.java b/base/src/bjc/dicelang/scl/FloatSCLToken.java
new file mode 100644
index 0000000..46db4c5
--- /dev/null
+++ b/base/src/bjc/dicelang/scl/FloatSCLToken.java
@@ -0,0 +1,41 @@
+package bjc.dicelang.scl;
+
+public class FloatSCLToken extends SCLToken {
+ /* Used for FLIT */
+ public double floatVal;
+
+ public FloatSCLToken(double val) {
+ super(Type.FLIT);
+
+ floatVal = val;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ long temp;
+ temp = Double.doubleToLongBits(floatVal);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ FloatSCLToken other = (FloatSCLToken) obj;
+ if (Double.doubleToLongBits(floatVal) != Double.doubleToLongBits(other.floatVal))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "FloatSCLToken [floatVal=" + floatVal + "]";
+ }
+}
diff --git a/base/src/bjc/dicelang/scl/IntSCLToken.java b/base/src/bjc/dicelang/scl/IntSCLToken.java
new file mode 100644
index 0000000..b90aa83
--- /dev/null
+++ b/base/src/bjc/dicelang/scl/IntSCLToken.java
@@ -0,0 +1,18 @@
+package bjc.dicelang.scl;
+
+public class IntSCLToken extends SCLToken {
+ /* Used for ILIT */
+ public long intVal;
+
+ /* Create a new token. */
+ public IntSCLToken(final Type typ) {
+ super(typ);
+ }
+
+ /* Create a new token. */
+ public IntSCLToken(final long iVal) {
+ super(Type.ILIT);
+
+ intVal = iVal;
+ }
+} \ No newline at end of file
diff --git a/base/src/bjc/dicelang/scl/SCLToken.java b/base/src/bjc/dicelang/scl/SCLToken.java
index a3226e2..45e35f6 100644
--- a/base/src/bjc/dicelang/scl/SCLToken.java
+++ b/base/src/bjc/dicelang/scl/SCLToken.java
@@ -1,33 +1,27 @@
package bjc.dicelang.scl;
-import static bjc.dicelang.Errors.ErrorKey.EK_SCL_INVTOKEN;
-
import java.util.HashMap;
import java.util.Map;
import bjc.dicelang.Errors;
-import bjc.utils.funcdata.IList;
import bjc.utils.parserutils.TokenUtils;
+import static bjc.dicelang.Errors.ErrorKey.EK_SCL_INVTOKEN;
+
import static bjc.dicelang.scl.SCLToken.Type.*;
+import static bjc.dicelang.scl.SCLToken.Word.*;
-/*
- * @TODO 10/08/17 Ben Culkin :TokenSplit
- * Again with the multiple subclasses in one class. Split it so
- * that each subclass only has the fields it needs.
- */
public class SCLToken {
+
public static enum Type {
/* Natural tokens. These come directly from strings */
ILIT, FLIT, BLIT, SQUOTE, DQUOTE, OBRACKET, OBRACE, SYMBOL, WORD,
/* Synthetic tokens. These are produced from special tokens. */
SLIT, WORDS, ARRAY,
+ }
- /* Word tokens These are subordinate to WORD tokens */
- /*
- * @NOTE These should really be in their own enum.
- */
+ public static enum Word {
/* Array manipulation */
MAKEARRAY, MAKEEXEC, MAKEUNEXEC,
/* Stream manipulation */
@@ -36,100 +30,39 @@ public class SCLToken {
STACKCOUNT, STACKEMPTY, DROP, NDROP, NIP, NNIP,
}
- /* The type of this token */
public SCLToken.Type type;
- /* Used for ILIT */
- public long intVal;
- /* Used for FLIT */
- public double floatVal;
- /* Used for BLIT */
- public boolean boolVal;
- /* Used for SYMBOL & SLIT */
- public String stringVal;
- /* Used for WORD */
- public SCLToken tokenVal;
- /* Used for WORDS & ARRAY */
- public IList<SCLToken> tokenVals;
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ) {
- type = typ;
- }
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ, final long iVal) {
- this(typ);
-
- intVal = iVal;
- }
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ, final double dVal) {
- this(typ);
-
- floatVal = dVal;
- }
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ, final boolean bVal) {
- this(typ);
-
- boolVal = bVal;
- }
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ, final String sVal) {
- this(typ);
-
- stringVal = sVal;
- }
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ, final SCLToken tVal) {
- this(typ);
-
- tokenVal = tVal;
- }
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ, final SCLToken.Type tVal) {
- this(typ, new SCLToken(tVal));
- }
-
- /* Create a new token. */
- public SCLToken(final SCLToken.Type typ, final IList<SCLToken> tVals) {
- this(typ);
-
- tokenVals = tVals;
- }
-
- /* Convert a string into a token. */
public static SCLToken tokenizeString(final String token) {
if (litTokens.containsKey(token)) {
- return new SCLToken(litTokens.get(token));
+ return new IntSCLToken(litTokens.get(token));
} else if (token.startsWith("\\")) {
- return new SCLToken(SYMBOL, token.substring(1));
+ return new StringSCLToken(true, token.substring(1));
} else if (builtinWords.containsKey(token)) {
- return new SCLToken(WORD, builtinWords.get(token));
+ return new WordSCLToken(builtinWords.get(token));
} else if (token.equals("true")) {
- return new SCLToken(BLIT, true);
+ return new BooleanSCLToken(true);
} else if (token.equals("false")) {
- return new SCLToken(BLIT, false);
+ return new BooleanSCLToken(false);
} else if (TokenUtils.isInt(token)) {
- return new SCLToken(ILIT, Long.parseLong(token));
+ return new IntSCLToken(Long.parseLong(token));
} else if (TokenUtils.isDouble(token)) {
- return new SCLToken(FLIT, Double.parseDouble(token));
+ return new FloatSCLToken(Double.parseDouble(token));
} else {
Errors.inst.printError(EK_SCL_INVTOKEN, token);
return null;
}
}
- /* The literal tokens. */
- private static final Map<String, SCLToken.Type> litTokens;
- /* The builtin words. */
- private static final Map<String, SCLToken.Type> builtinWords;
+ protected static final Map<String, Type> litTokens;
+ protected static final Map<String, Word> builtinWords;
+
+ protected SCLToken() {
+
+ }
+
+ protected SCLToken(Type typ) {
+ type = typ;
+ }
static {
/* Init literal tokens. */
@@ -158,4 +91,31 @@ public class SCLToken {
builtinWords.put("nip", NIP);
builtinWords.put("nnip", NNIP);
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SCLToken other = (SCLToken) obj;
+ if (type != other.type)
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "SCLToken [type=" + type + "]";
+ }
} \ No newline at end of file
diff --git a/base/src/bjc/dicelang/scl/StreamControlEngine.java b/base/src/bjc/dicelang/scl/StreamControlEngine.java
index ec0f706..073f15e 100644
--- a/base/src/bjc/dicelang/scl/StreamControlEngine.java
+++ b/base/src/bjc/dicelang/scl/StreamControlEngine.java
@@ -12,6 +12,7 @@ import bjc.utils.parserutils.TokenUtils;
import static bjc.dicelang.Errors.ErrorKey.*;
import static bjc.dicelang.scl.SCLToken.Type.*;
+import static bjc.dicelang.scl.SCLToken.Word.*;
/*
* @TODO 10/08/17 Ben Culkin :SCLReorg
@@ -40,7 +41,7 @@ public class StreamControlEngine {
* Create a new stream control engine.
*
* @param engine
- * The engine to control.
+ * The engine to control.
*/
public StreamControlEngine(final StreamEngine engine) {
eng = engine;
@@ -53,7 +54,7 @@ public class StreamControlEngine {
* Run a SCL program.
*
* @param tokens
- * The program to run.
+ * The program to run.
*
* @return Whether the program executed successfully.
*/
@@ -61,7 +62,7 @@ public class StreamControlEngine {
for (int i = 0; i < tokens.length; i++) {
/* Tokenize each token. */
final String token = tokens[i];
- final SCLToken tok = SCLToken.tokenizeString(token);
+ final SCLToken tok = SCLToken.tokenizeString(token);
if (tok == null) {
System.out.printf("ERROR: Tokenization failed for '%s'\n", token);
@@ -91,12 +92,12 @@ public class StreamControlEngine {
return false;
}
final SCLToken brak = curStack.pop();
- curStack.push(new SCLToken(ARRAY, brak.tokenVals));
+ curStack.push(new WordsSCLToken(true, ((WordsSCLToken) brak).tokenVals));
break;
case WORD:
/* Handle words. */
- if(!handleWord(tok)) {
+ if (!handleWord((WordSCLToken) tok)) {
System.out.printf("WARNING: Execution of word '%s' failed\n", tok);
}
break;
@@ -110,16 +111,14 @@ public class StreamControlEngine {
return true;
}
- private boolean handleWord(final SCLToken tk) {
+ private boolean handleWord(final WordSCLToken tk) {
boolean succ = true;
/* Handle each type of word. */
- /*
- * @NOTE
- * This should probably use something other than a switch
- * statement.
+ /*
+ * @NOTE This should probably use something other than a switch statement.
*/
- switch (tk.tokenVal.type) {
+ switch (tk.wordVal) {
case NEWSTREAM:
eng.newStream();
break;
@@ -166,14 +165,14 @@ public class StreamControlEngine {
}
break;
case STACKCOUNT:
- curStack.push(new SCLToken(ILIT, curStack.size()));
+ curStack.push(new IntSCLToken(curStack.size()));
break;
case STACKEMPTY:
- curStack.push(new SCLToken(BLIT, curStack.empty()));
+ curStack.push(new BooleanSCLToken(curStack.empty()));
break;
case DROP:
if (curStack.size() == 0) {
- Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.tokenVal.type.toString());
+ Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.toString());
return false;
}
curStack.drop();
@@ -186,7 +185,7 @@ public class StreamControlEngine {
break;
case NIP:
if (curStack.size() < 2) {
- Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.tokenVal.type.toString());
+ Errors.inst.printError(EK_SCL_SUNDERFLOW, tk.toString());
return false;
}
curStack.nip();
@@ -198,7 +197,7 @@ public class StreamControlEngine {
}
break;
default:
- Errors.inst.printError(EK_SCL_UNWORD, tk.tokenVal.type.toString());
+ Errors.inst.printError(EK_SCL_UNWORD, tk.toString());
return false;
}
@@ -214,7 +213,7 @@ public class StreamControlEngine {
return false;
}
- final int n = (int) num.intVal;
+ final int n = (int) ((IntSCLToken) num).intVal;
if (curStack.size() < n) {
Errors.inst.printError(EK_SCL_SUNDERFLOW, NNIP.toString());
@@ -234,7 +233,7 @@ public class StreamControlEngine {
return false;
}
- final int n = (int) num.intVal;
+ final int n = (int) ((IntSCLToken) num).intVal;
if (curStack.size() < n) {
Errors.inst.printError(EK_SCL_SUNDERFLOW, NDROP.toString());
@@ -278,11 +277,11 @@ public class StreamControlEngine {
final IList<SCLToken> arr = new FunctionalList<>();
- for (int i = 0; i < num.intVal; i++) {
+ for (int i = 0; i < ((IntSCLToken) num).intVal; i++) {
arr.add(curStack.pop());
}
- curStack.push(new SCLToken(ARRAY, arr));
+ curStack.push(new WordsSCLToken(true, arr));
return true;
}
@@ -324,7 +323,7 @@ public class StreamControlEngine {
return -1;
}
final SCLToken brak = curStack.pop();
- toks.add(new SCLToken(ARRAY, brak.tokenVals));
+ toks.add(new WordsSCLToken(true, ((WordsSCLToken) brak).tokenVals));
break;
default:
toks.add(ntok);
@@ -344,10 +343,10 @@ public class StreamControlEngine {
/* Skip the closing bracket */
n += 1;
- /* @NOTE
- * Instead of being hardcoded, this should be a parameter.
+ /*
+ * @NOTE Instead of being hardcoded, this should be a parameter.
*/
- curStack.push(new SCLToken(WORDS, toks));
+ curStack.push(new WordsSCLToken(false, toks));
return n;
}
@@ -389,7 +388,9 @@ public class StreamControlEngine {
*/
n += 1;
- curStack.push(new SCLToken(SLIT, TokenUtils.descapeString(sb.toString())));
+ String strang = TokenUtils.descapeString(sb.toString());
+
+ curStack.push(new StringSCLToken(false, strang));
return n;
}
diff --git a/base/src/bjc/dicelang/scl/StringSCLToken.java b/base/src/bjc/dicelang/scl/StringSCLToken.java
new file mode 100644
index 0000000..d50b7e9
--- /dev/null
+++ b/base/src/bjc/dicelang/scl/StringSCLToken.java
@@ -0,0 +1,46 @@
+package bjc.dicelang.scl;
+
+public class StringSCLToken extends SCLToken {
+ /* Used for SYMBOL & SLIT */
+ public String stringVal;
+
+ public StringSCLToken(boolean isSymbol, String val) {
+ if(isSymbol) {
+ type = Type.SYMBOL;
+ } else {
+ type = Type.SLIT;
+ }
+
+ stringVal = val;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((stringVal == null) ? 0 : stringVal.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ StringSCLToken other = (StringSCLToken) obj;
+ if (stringVal == null) {
+ if (other.stringVal != null)
+ return false;
+ } else if (!stringVal.equals(other.stringVal))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "StringSCLToken [stringVal=" + stringVal + "]";
+ }
+}
diff --git a/base/src/bjc/dicelang/scl/WordSCLToken.java b/base/src/bjc/dicelang/scl/WordSCLToken.java
new file mode 100644
index 0000000..46aac4f
--- /dev/null
+++ b/base/src/bjc/dicelang/scl/WordSCLToken.java
@@ -0,0 +1,38 @@
+package bjc.dicelang.scl;
+
+public class WordSCLToken extends SCLToken {
+ public Word wordVal;
+
+ public WordSCLToken(Word wrd) {
+ super(Type.WORD);
+
+ wordVal = wrd;
+ }
+
+ @Override
+ public String toString() {
+ return "WordSCLToken [wordVal=" + wordVal + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((wordVal == null) ? 0 : wordVal.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ WordSCLToken other = (WordSCLToken) obj;
+ if (wordVal != other.wordVal)
+ return false;
+ return true;
+ }
+}
diff --git a/base/src/bjc/dicelang/scl/WordsSCLToken.java b/base/src/bjc/dicelang/scl/WordsSCLToken.java
new file mode 100644
index 0000000..81453dc
--- /dev/null
+++ b/base/src/bjc/dicelang/scl/WordsSCLToken.java
@@ -0,0 +1,18 @@
+package bjc.dicelang.scl;
+
+import bjc.utils.funcdata.IList;
+
+public class WordsSCLToken extends SCLToken {
+ /* Used for WORDS & ARRAY */
+ public IList<SCLToken> tokenVals;
+
+ public WordsSCLToken(boolean isArray, IList<SCLToken> tokens) {
+ if(isArray) {
+ type = Type.ARRAY;
+ } else {
+ type = Type.WORDS;
+ }
+
+ tokenVals = tokens;
+ }
+}