From 2d143e435d646480e89c6941924fdf65c1c7f4bf Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 28 Jul 2019 17:28:48 -0400 Subject: Implement compilation for ConditionalDirective --- .../format/directives/ConditionalDirective.java | 218 ++++++++++++++------- 1 file changed, 143 insertions(+), 75 deletions(-) (limited to 'clformat/src/main/java') diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java index 0a400e9..e481590 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java @@ -4,22 +4,31 @@ import java.io.*; import java.util.*; import java.util.regex.*; +import bjc.utils.esodata.*; import bjc.utils.ioutils.format.*; /** * Implements the [ directive. * - * @author student + * This does varying sorts of conditional dispatches on which string to use for formatting, allowing + * it to be based off of general conditions in varying ways. * + * @author Ben Culkin */ public class ConditionalDirective implements Directive { @Override public void format(FormatParameters dirParams) throws IOException { - CLModifiers mods = dirParams.getMods(); - CLParameters params = dirParams.getParams(); + Edict edt = compile(dirParams.toCompileCTX()); + + edt.format(dirParams.toFormatCTX()); + } - List condBody = new ArrayList<>(); + @Override + public Edict compile(CompileContext compCTX) { + CLModifiers mods = compCTX.decr.modifiers; + CLParameters params = compCTX.decr.parameters; + List condBody = new ArrayList<>(); List> clauses = new ArrayList<>(); List defClause = null; @@ -27,7 +36,7 @@ public class ConditionalDirective implements Directive { int nestLevel = 1; - Iterator dirIter = dirParams.dirIter; + Iterator dirIter = compCTX.directives; while (dirIter.hasNext()) { Decree decr = dirIter.next(); if (decr.isLiteral) { @@ -100,92 +109,151 @@ public class ConditionalDirective implements Directive { if (mods.starMod && clauses.size() > 0) defClause = clauses.get(0); + CLValue index = null; + + if (params.length() >= 1) { + params.mapIndices("choice"); + + index = params.resolveKey("choice"); + } + + ConditionalEdict.Mode mode; + + if (mods.colonMod) { + mode = ConditionalEdict.Mode.FIRST_SECOND; + } else if (mods.atMod) { + mode = ConditionalEdict.Mode.OUTPUT_TRUE; + } else { + mode = ConditionalEdict.Mode.INDEX_CLAUSE; + } + + return new ConditionalEdict(mode, mods.dollarMod, index, clauses, + defClause, compCTX.formatter); + } +} + +class ConditionalEdict implements Edict { + public static enum Mode { + FIRST_SECOND, + OUTPUT_TRUE, + INDEX_CLAUSE + } + + private Mode condMode; + + private boolean decrementIndex; + private CLValue index; + + private List> clauses; + private List defClause; + + private CLFormatter formatter; + + public ConditionalEdict(Mode condMode, boolean decrementIndex, + CLValue index, List> clauses, List defClause, + CLFormatter fmt) { + this.condMode = condMode; + + this.decrementIndex = decrementIndex; + this.index = index; + + this.clauses = clauses; + this.defClause = defClause; + + this.formatter = fmt; + } + + @Override + public void format(FormatContext formCTX) throws IOException { + Tape items = formCTX.items; + try { - if (mods.colonMod) { - dirParams.tParams.right(); - - boolean res = false; - if (dirParams.item == null) { - //throw new IllegalArgumentException("No parameter provided for [ directive."); - } else if (!(dirParams.item instanceof Boolean)) { - throw new IllegalFormatConversionException('[', dirParams.item.getClass()); - } else { - res = (Boolean) dirParams.item; - } + switch (condMode) { + case FIRST_SECOND: + { + Object o = items.item(); + items.right(); - List frmt; - if (res) - frmt = clauses.get(1); - else - frmt = clauses.get(0); - - dirParams.fmt.doFormatString(frmt, dirParams.rw, dirParams.tParams, false); - } else if (mods.atMod) { - boolean res = false; - if (dirParams.item == null) { - // throw new IllegalArgumentException("No parameter provided for [ directive."); - } else if (dirParams.item instanceof Integer) { - if ((Integer)dirParams.item != 0) res = true; - } else if (dirParams.item instanceof Boolean) { - res = (Boolean) dirParams.item; - } else { - throw new IllegalFormatConversionException('[', dirParams.item.getClass()); - } + boolean res = false; + if (o == null) { + //throw new IllegalArgumentException("No parameter provided for [ directive."); + } else if (!(o instanceof Boolean)) { + throw new IllegalFormatConversionException('[', o.getClass()); + } else { + res = (Boolean) o; + } - if (res) { - dirParams.fmt.doFormatString(clauses.get(0), dirParams.rw, dirParams.tParams, false); - } else { - dirParams.tParams.right(); + List frmt; + if (res) { + frmt = clauses.get(1); + } else { + frmt = clauses.get(0); + } + + formatter.doFormatString(frmt, formCTX.writer, formCTX.items, false); } - } else { - int res; - if (params.length() >= 1) { - params.mapIndices("choice"); + break; + case OUTPUT_TRUE: + { + boolean res = false; + Object o = items.item(); - res = params.getInt(dirParams.tParams, - "choice", "conditional choice", "[", 0); - } else { - if (dirParams.item == null) { - throw new IllegalArgumentException("No parameter provided for [ directive."); - } else if (!(dirParams.item instanceof Number)) { - throw new IllegalFormatConversionException('[', dirParams.item.getClass()); + if (o == null) { + // throw new IllegalArgumentException("No parameter provided for [ directive."); + } else if (o instanceof Integer) { + if ((Integer)o != 0) { + res = true; + } + } else if (o instanceof Boolean) { + res = (Boolean) o; + } else { + throw new IllegalFormatConversionException('[', o.getClass()); } - res = ((Number) dirParams.item).intValue(); - dirParams.tParams.right(); + if (res) { + formatter.doFormatString(clauses.get(0), formCTX.writer, formCTX.items, false); + } else { + items.right(); + } } + break; + case INDEX_CLAUSE: + { + int res; - if (mods.dollarMod) res -= 1; + if (index != null) { + res = index.asInt(items, "conditional choice", "[", 0); + } else { + Object o = items.item(); - // System.err.printf("Attempting selection of clause %d of %d (%s) (default %s)\n", - // res, clauses.size(), clauses, defClause); - if (clauses.size() == 0 || res < 0 || res >= clauses.size()) { - // System.err.printf("Selecting default clause (res %d, max %d): %s\n", res, clauses.size(), defClause); - // int clauseNo = 0; - // for (String clause : clauses) { - // System.err.printf("... clause %d: %s\n", ++clauseNo, clause); - // } + if (o == null) { + throw new IllegalArgumentException("No parameter provided for [ directive."); + } else if (!(o instanceof Number)) { + throw new IllegalFormatConversionException('[', o.getClass()); + } - if (defClause != null) dirParams.fmt.doFormatString(defClause, dirParams.rw, dirParams.tParams, false); - } else { - List frmt = clauses.get(res); + res = ((Number) o).intValue(); + + items.right(); + } + + if (decrementIndex) res -= 1; - // System.out.printf("Selecting clause %d of %d (params %s): %s\n", res, clauses.size(), formatParams, frmt); - dirParams.fmt.doFormatString(frmt, dirParams.rw, dirParams.tParams, false); + if (clauses.size() == 0 || res < 0 || res >= clauses.size()) { + if (defClause != null) { + formatter.doFormatString(defClause, formCTX.writer, items, false); + } + } else { + List frmt = clauses.get(res); + + formatter.doFormatString(frmt, formCTX.writer, items, false); + } } + break; } } catch (EscapeException eex) { - // @NOTE 9/5/18 - // - // I am not sure if it is valid to error here. I'm not - // even sure that we need to handle this here, but I - // dunno - //if (eex.endIteration) - // throw new UnsupportedOperationException("Colon mod not allowed on escape marker without colon mod on iteration"); + // Conditionals are transparent to iteration-escapes throw eex; } - - return; } - } -- cgit v1.2.3