From cb7be8155255fad01aaf5beebe7a0f793cff016b Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Mon, 6 Jan 2020 18:05:15 -0500 Subject: Re-apply implementation of GroupDecree for ConditionalDirective --- .../java/bjc/utils/ioutils/format/CLFormatter.java | 44 ++-- .../java/bjc/utils/ioutils/format/CLTokenizer.java | 2 +- .../java/bjc/utils/ioutils/format/GroupDecree.java | 16 +- .../format/directives/ConditionalDirective.java | 236 ++++++++------------- 4 files changed, 135 insertions(+), 163 deletions(-) diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java index 0aa2efe..f45b3e8 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java @@ -364,11 +364,11 @@ public class CLFormatter { /** * Compile a CLString from a string. - * + * * @param inp - * The string to compile. - * - * @return The compiled string. + * The string to compile. + * + * @return A CLString compiled from the input. */ public CLString compile(String inp) { CLTokenizer tokenzer = new CLTokenizer(inp); @@ -379,15 +379,15 @@ public class CLFormatter { } /** - * Compile a set of decrees into a set of edicts. - * + * Compile a set of edicts from a list of decrees. + * * @param decrees - * The decrees to compile. - * - * @return The edicts compiled from the decrees. + * The decrees to compile. + * + * @return A set of edicts compiled from the decrees. */ public List compile(Iterable decrees) { - // Not 100% sure this is correct, but the tests are passing + // If we have no decrees, there are no edicts. if (decrees == null) return new ArrayList<>(); CLTokenizer it = CLTokenizer.fromTokens(decrees); @@ -395,12 +395,26 @@ public class CLFormatter { } /** - * Compile a set of edicts from a tokenizer. - * + * Compile a set of edicts from a clause. + * + * @param clause + * The clause to compile. + * + * @return The set of edicts compiled from the clause. + */ + public List compile(ClauseDecree clause) { + if (clause == null) return new ArrayList<>(); + + return compile(clause.body); + } + + /** + * Compile a set of edicts from a set of tokens. + * * @param cltok - * The tokenizer to get decrees from. - * - * @return The set of edicts compiled from the tokenizer. + * The tokenizer providing us with our tokens. + * + * @return The edicts compiled from those tokens. */ public List compile(CLTokenizer cltok) { List result = new ArrayList<>(); diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLTokenizer.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLTokenizer.java index 6caead5..04bbae4 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/CLTokenizer.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLTokenizer.java @@ -224,7 +224,7 @@ public class CLTokenizer implements Iterator { } while (hasNext()); if (newGroup.closing == null) { - String msg = String.format("Did not find closing directive for group (wanted %s, last decree was %s)", + String msg = String.format("Did not find closing directive for group (wanted \"%s\", last decree was \"%s\")", desiredClosing, curDecree.name); throw new NoSuchElementException(msg); diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/GroupDecree.java b/clformat/src/main/java/bjc/utils/ioutils/format/GroupDecree.java index ddf9f6d..cf124bc 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/GroupDecree.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/GroupDecree.java @@ -9,7 +9,7 @@ import java.util.*; * * @author Ben Culkin */ -public class GroupDecree { +public class GroupDecree implements Iterable { /** * The decree that opened this group. */ @@ -109,4 +109,18 @@ public class GroupDecree { public String toString() { return String.format("GroupDecree [opening=%s, closing=%s, body=%s]", opening, closing, body); } + + @Override + public Iterator iterator() { + return body.iterator(); + } + + /** + * Get the number of clauses in this group. + * + * @return The number of clauses in the group. + */ + public int size() { + return body.size(); + } } 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 099c793..b61eb7b 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 @@ -2,15 +2,16 @@ package bjc.utils.ioutils.format.directives; import java.io.*; import java.util.*; +import java.util.regex.*; + import bjc.utils.esodata.*; import bjc.utils.ioutils.format.*; /** * Implements the [ directive. * - * 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. + * 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 */ @@ -20,85 +21,20 @@ public class ConditionalDirective implements Directive { CLModifiers mods = compCTX.decr.modifiers; CLParameters params = compCTX.decr.parameters; - List condBody = new ArrayList<>(); - List> clauses = new ArrayList<>(); + GroupDecree clauses = compCTX.directives.nextGroup(compCTX.decr, "]", ";"); - List defClause = null; + ClauseDecree defClause = null; boolean isDefault = false; - int nestLevel = 1; + for (ClauseDecree clause : clauses) { + if (isDefault) defClause = clause; - Iterator dirIter = compCTX.directives; - while (dirIter.hasNext()) { - Decree decr = dirIter.next(); - if (decr.isLiteral) { - condBody.add(decr); - continue; - } - - String dirName = decr.name; - if (dirName != null) { - if (dirName.equals("[")) { - if (nestLevel > 0) { - condBody.add(decr); - } - nestLevel += 1; - } else if (Directive.isOpening(dirName)) { - nestLevel += 1; - - condBody.add(decr); - } else if (dirName.equals("]")) { - nestLevel = Math.max(0, nestLevel - 1); - - if (nestLevel == 0) { - /* End the conditional. */ - List clause = condBody; - - if (isDefault) { - defClause = clause; - } - clauses.add(clause); - - break; - } else { - /* Not a special directive. */ - condBody.add(decr); - } - } else if (Directive.isClosing(dirName)) { - nestLevel = Math.max(0, nestLevel - 1); - - condBody.add(decr); - } else if (dirName.equals(";")) { - if (nestLevel == 1) { - /* End the clause. */ - List clause = condBody; - - condBody = new ArrayList<>(); - - if (isDefault) { - defClause = clause; - } - clauses.add(clause); - - /* - * Mark the next clause as the - * default. - */ - if (decr.modifiers.colonMod) { - isDefault = true; - } - } else { - /* Not a special directive. */ - condBody.add(decr); - } - } else { - /* Not a special directive. */ - condBody.add(decr); - } + if (clause.terminator != null && clause.terminator.modifiers.colonMod) { + isDefault = true; } } - if (mods.starMod && clauses.size() > 0) defClause = clauses.get(0); + if (mods.starMod && clauses.size() > 0) defClause = clauses.clause(); CLValue index = null; @@ -118,13 +54,16 @@ public class ConditionalDirective implements Directive { mode = ConditionalEdict.Mode.INDEX_CLAUSE; } - return new ConditionalEdict(mode, mods.dollarMod, index, clauses, defClause, compCTX.formatter); + 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 + FIRST_SECOND, + OUTPUT_TRUE, + INDEX_CLAUSE } private Mode condMode; @@ -135,18 +74,23 @@ class ConditionalEdict implements Edict { private List clauses; private CLString defClause; - public ConditionalEdict(Mode condMode, boolean decrementIndex, CLValue index, List> clauses, - List defClause, CLFormatter fmt) { + private CLFormatter formatter; + + public ConditionalEdict(Mode condMode, boolean decrementIndex, + CLValue index, GroupDecree clauses, ClauseDecree defClause, + CLFormatter fmt) { this.condMode = condMode; this.decrementIndex = decrementIndex; this.index = index; this.clauses = new ArrayList<>(); - for (List clause : clauses) { + for (ClauseDecree clause : clauses) { this.clauses.add(new CLString(fmt.compile(clause))); } this.defClause = new CLString(fmt.compile(defClause)); + + this.formatter = fmt; } @Override @@ -155,91 +99,91 @@ class ConditionalEdict implements Edict { try { switch (condMode) { - case FIRST_SECOND: { - Object o = items.item(); - items.right(); - - 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; - } + case FIRST_SECOND: + { + Object o = items.item(); + items.right(); - CLString frmt; - if (res) { - frmt = clauses.get(1); - } else { - frmt = clauses.get(0); - } + 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; + } - frmt.format(formCTX); - } - break; - case OUTPUT_TRUE: { - boolean res = false; - Object o = items.item(); - - if (o == null) { - // throw new IllegalArgumentException("No parameter provided for [ directive."); - } else if (o instanceof Integer) { - if ((Integer) o != 0) { - res = true; + CLString frmt; + if (res) { + frmt = clauses.get(1); + } else { + frmt = clauses.get(0); } - } else if (o instanceof Boolean) { - res = (Boolean) o; - } else { - throw new IllegalFormatConversionException('[', o.getClass()); - } - if (res) { - clauses.get(0).format(formCTX); - } else { - items.right(); + frmt.format(formCTX); } - } break; - case INDEX_CLAUSE: { - int res; - - if (index != null) { - res = index.asInt(items, "conditional choice", "[", 0); - } else { + case OUTPUT_TRUE: + { + boolean res = false; Object o = items.item(); if (o == null) { - throw new IllegalArgumentException( - "No parameter provided for [ directive."); - } else if (!(o instanceof Number)) { throw new IllegalFormatConversionException( - '[', o.getClass()); } - - res = ((Number) o).intValue(); + // 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()); + } - items.right(); + if (res) { + clauses.get(0).format(formCTX); + } else { + items.right(); + } } + break; + case INDEX_CLAUSE: + { + int res; + + if (index != null) { + res = index.asInt(items, "conditional choice", "[", 0); + } else { + Object o = items.item(); + + if (o == null) { + throw new IllegalArgumentException("No parameter provided for [ directive."); + } else if (!(o instanceof Number)) { + throw new IllegalFormatConversionException('[', o.getClass()); + } - if (decrementIndex) res -= 1; + res = ((Number) o).intValue(); - if (clauses.size() == 0 || res < 0 || res >= clauses.size()) { - if (defClause != null) { - defClause.format(formCTX.writer, items); + items.right(); } - } else { - CLString frmt = clauses.get(res); - frmt.format(formCTX.writer, items); + if (decrementIndex) res -= 1; + + if (clauses.size() == 0 || res < 0 || res >= clauses.size()) { + if (defClause != null) { + defClause.format(formCTX.writer, items); + } + } else { + CLString frmt = clauses.get(res); + + frmt.format(formCTX.writer, items); + } } - } break; - default: - throw new IllegalArgumentException("INTERNAL ERROR: ConditionalEdict mode " + condMode - + " is not supported. This is a bug."); } - } catch (DirectiveEscape eex) { + } catch (DirectiveEscape dex) { // Conditionals are transparent to iteration-escapes - throw eex; + throw dex; } } } -- cgit v1.2.3