From 883a5b51581421783206bac3b6e44f5b3f6612eb Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 28 Jul 2019 19:33:15 -0400 Subject: Implement compilation for EscapeDirective --- .../java/bjc/utils/ioutils/format/CLValue.java | 2 + .../ioutils/format/directives/EscapeDirective.java | 138 ++++++++++++++++++++- 2 files changed, 137 insertions(+), 3 deletions(-) (limited to 'clformat/src/main/java/bjc/utils') 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 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 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 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); + } + } } -- cgit v1.2.3