summaryrefslogtreecommitdiff
path: root/clformat/src/main/java/bjc/utils
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2019-07-28 19:33:15 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2019-07-28 19:33:15 -0400
commit883a5b51581421783206bac3b6e44f5b3f6612eb (patch)
treeaf6833ad3fd25f011f1cfd608360ba51f71b12fd /clformat/src/main/java/bjc/utils
parent2d143e435d646480e89c6941924fdf65c1c7f4bf (diff)
Implement compilation for EscapeDirective
Diffstat (limited to 'clformat/src/main/java/bjc/utils')
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java2
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java138
2 files changed, 137 insertions, 3 deletions
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java
index bc78f3f..a068048 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java
@@ -92,6 +92,8 @@ public interface CLValue {
}
class NullValue implements CLValue {
+ public static CLValue nullVal = new NullValue();
+
public String getValue(Tape<Object> params) {
return null;
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
index f20f976..a5356c9 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
@@ -1,17 +1,25 @@
package bjc.utils.ioutils.format.directives;
+import java.io.*;
+
import bjc.utils.esodata.*;
import bjc.utils.ioutils.format.*;
/**
* Implementation for the ^ directive.
- * @author student
*
+ * This directive allows you to escape an iteration directive.
+ *
+ * @author Ben Culkin
*/
public class EscapeDirective implements Directive {
+ public void format(FormatParameters dirParams) throws IOException {
+ Edict edt = compile(dirParams.toCompileCTX());
- @Override
- public void format(FormatParameters dirParams) {
+ edt.format(dirParams.toFormatCTX());
+ }
+
+ public void formatF(FormatParameters dirParams) {
Tape<Object> itemTape = dirParams.tParams;
CLModifiers mods = dirParams.getMods();
@@ -60,4 +68,128 @@ public class EscapeDirective implements Directive {
if(shouldExit) throw new EscapeException(mods.colonMod);
}
+ @Override
+ public Edict compile(CompileContext compCTX) {
+ CLParameters params = compCTX.decr.parameters;
+ CLModifiers mods = compCTX.decr.modifiers;
+
+ CLValue param1 = CLValue.nil();
+ CLValue param2 = CLValue.nil();
+ CLValue param3 = CLValue.nil();
+
+ EscapeEdict.Mode mode;
+ switch (params.length()) {
+ case 0:
+ mode = EscapeEdict.Mode.END;
+ break;
+ case 1:
+ mode = EscapeEdict.Mode.COUNT;
+ params.mapIndices("count");
+ param1 = params.resolveKey("count");
+ break;
+ case 2:
+ params.mapIndices("lhand", "rhand");
+ param1 = params.resolveKey("lhand");
+ param2 = params.resolveKey("rhand");
+ mode = EscapeEdict.Mode.EQUALITY;
+ break;
+ case 3:
+ params.mapIndices("lower", "ival", "upper");
+ param1 = params.resolveKey("lower");
+ param2 = params.resolveKey("ival");
+ param3 = params.resolveKey("upper");
+ mode = EscapeEdict.Mode.RANGE;
+ break;
+ default:
+ throw new IllegalArgumentException("Too many parameters to ^ directive");
+ }
+
+ return new EscapeEdict(mods.atMod, mode, mods.colonMod, param1, param2,
+ param3, mods.dollarMod);
+ }
+}
+
+class EscapeEdict implements Edict {
+ public static enum Mode {
+ END,
+ COUNT,
+ EQUALITY,
+ RANGE
+ }
+
+ private Mode mode;
+
+ private boolean isNegated;
+ private boolean terminateIteration;
+
+ private CLValue param1;
+ private CLValue param2;
+ private CLValue param3;
+
+ private boolean advance;
+
+ public EscapeEdict(boolean isNegated, Mode mode, boolean terminateIteration,
+ CLValue param1, CLValue param2, CLValue param3, boolean advance) {
+ this.mode = mode;
+
+ this.isNegated = isNegated;
+ this.terminateIteration = terminateIteration;
+
+ this.param1 = param1;
+ this.param2 = param2;
+ this.param3 = param3;
+
+ this.advance = advance;
+ }
+
+ @Override
+ public void format(FormatContext formCTX) {
+ boolean shouldExit;
+
+ Tape<Object> items = formCTX.items;
+
+ if (advance) items.right();
+
+ switch (mode) {
+ case END:
+ shouldExit = items.atEnd();
+ break;
+ case COUNT:
+ {
+ int num = param1.asInt(items, "condition count", "^", 0);
+
+ shouldExit = (num == 0);
+ }
+ break;
+ case EQUALITY:
+ {
+ int left = param1.asInt(items, "left-hand condition", "^", 0);
+ int right = param2.asInt(items, "right-hand condition", "^", 0);
+
+ shouldExit = (left == right);
+ }
+ break;
+ case RANGE:
+ {
+ int low = param1.asInt(items, "lower-bound condition", "^", 0);
+ int mid = param2.asInt(items, "interval condition", "^", 0);
+ int high = param3.asInt(items, "upper-bound condition", "^", 0);
+
+ shouldExit = (low <= mid) && (mid <= high);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Escape condition mode " + mode + " isn't supported");
+ }
+
+ if (advance) items.left();
+
+ if (isNegated) {
+ shouldExit = !shouldExit;
+ }
+
+ if (shouldExit) {
+ throw new EscapeException(terminateIteration);
+ }
+ }
}