diff options
Diffstat (limited to 'clformat/src/main')
3 files changed, 248 insertions, 10 deletions
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java index 990558c..6685346 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java @@ -14,6 +14,36 @@ import bjc.utils.math.*; * */ public abstract class GeneralNumberDirective implements Directive { + public static class NumberParams { + /** + * Minimum # of printed columns + */ + public CLValue mincol = CLValue.nil(); + /** + * Character to use for padding if needed. + */ + public CLValue padchar = CLValue.nil(); + + /** + * Should the sign always be printed? + */ + public boolean signed; + + /** + * Should there be commas inserted into the numbers? + */ + public boolean commaMode; + + /** + * Number of places to go before inserting a comma. + */ + public CLValue commaInterval = CLValue.nil(); + /** + * Character to use as a comma. + */ + public CLValue commaChar = CLValue.nil(); + } + protected static void handleNumberDirective(Tape<Object> itemTape, ReportWriter rw, Decree decr, int argidx, long val, int radix) throws IOException { @@ -62,4 +92,39 @@ public abstract class GeneralNumberDirective implements Directive { rw.write(res); } + + protected NumberParams getParams(CompileContext compCTX, int argidx) { + CLParameters params = compCTX.decr.parameters; + CLModifiers mods = compCTX.decr.modifiers; + + NumberParams np = new NumberParams(); + + if (params.length() >= (argidx + 2)) { + params.mapIndex("mincol", argidx + 1); + np.mincol = params.resolveKey("mincol"); + } + + if (params.length() >= (argidx + 3)) { + params.mapIndex("padchar", argidx + 2); + np.padchar = params.resolveKey("padchar"); + } + + if (mods.colonMod) { + np.commaMode = true; + + if (params.length() >= (argidx + 4)) { + params.mapIndex("cchar", argidx + 3); + np.commaChar = params.resolveKey("cchar"); + } + + if (params.length() >= (argidx + 5)) { + params.mapIndex("cinterval", argidx + 4); + np.commaInterval = params.resolveKey("cinterval"); + } + } + + np.signed = mods.atMod; + + return np; + } } diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java index 09acdd5..83b294c 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java @@ -1,9 +1,12 @@ package bjc.utils.ioutils.format.directives; -import java.io.IOException; -import java.util.IllegalFormatConversionException; +import java.io.*; +import java.util.*; -import bjc.utils.ioutils.format.CLFormatter; +import bjc.utils.ioutils.format.*; +import bjc.utils.math.*; + +import static bjc.utils.ioutils.format.directives.GeneralNumberDirective.NumberParams; /** * Implements radix based numbers. @@ -34,17 +37,66 @@ public class NumberDirective extends GeneralNumberDirective { @Override public void format(FormatParameters dirParams) throws IOException { - CLFormatter.checkItem(dirParams.item, directive); + Edict edt = compile(dirParams.toCompileCTX()); - if (!(dirParams.item instanceof Number)) { - throw new IllegalFormatConversionException(directive, dirParams.item.getClass()); - } + edt.format(dirParams.toFormatCTX()); + } + + @Override + public Edict compile(CompileContext compCTX) { + NumberParams np = getParams(compCTX, argidx); + + return new NumberEdict(radix, directive, argidx, np); + } +} + +class NumberEdict implements Edict { + private int radix; + private int argidx; - long val = ((Number) dirParams.item).longValue(); + private String directive; - handleNumberDirective(dirParams.tParams, dirParams.rw, dirParams.decr, argidx, val, radix); + private NumberParams np; - dirParams.tParams.right(); + public NumberEdict(int radix, char directive, int argidx, NumberParams np) { + this.radix = radix; + this.argidx = argidx; + + this.directive = Character.toString(directive); + + this.np = np; } + @Override + public void format(FormatContext formCTX) throws IOException { + Object item = formCTX.items.item(); + + CLFormatter.checkItem(item, directive.charAt(0)); + + if (!(item instanceof Number)) { + throw new IllegalFormatConversionException(directive.charAt(0), item.getClass()); + } + + long val = ((Number) item).longValue(); + + int mincol = np.mincol.asInt(formCTX.items, "minimum column count", directive, 0); + char padchar = np.padchar.asChar(formCTX.items, "padding character", directive, ' '); + + boolean signed = np.signed; + + String res; + + if (np.commaMode) { + char commaChar = np.commaChar.asChar(formCTX.items, "comma character", directive, ','); + int commaInterval = np.commaInterval.asInt(formCTX.items, "comma interval", directive, 0); + + res = NumberUtils.toCommaString(val, mincol, padchar, commaInterval, commaChar, signed, radix); + } else { + res = NumberUtils.toNormalString(val, mincol, padchar, signed, radix); + } + + formCTX.writer.write(res); + + formCTX.items.right(); + } } diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java index d3b662a..698c4ac 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java @@ -3,9 +3,12 @@ package bjc.utils.ioutils.format.directives; import java.io.*; import java.util.*; +import bjc.utils.esodata.*; import bjc.utils.ioutils.format.*; import bjc.utils.math.*; +import static bjc.utils.ioutils.format.directives.GeneralNumberDirective.NumberParams; + /** * Generalized radix directive. * @@ -16,6 +19,12 @@ public class RadixDirective extends GeneralNumberDirective { @Override public void format(FormatParameters dirParams) throws IOException { + Edict edt = compile(dirParams.toCompileCTX()); + + edt.format(dirParams.toFormatCTX()); + } + + public void formatF(FormatParameters dirParams) throws IOException { CLFormatter.checkItem(dirParams.item, 'R'); if (!(dirParams.item instanceof Number)) { @@ -52,4 +61,116 @@ public class RadixDirective extends GeneralNumberDirective { dirParams.tParams.right(); } + + @Override + public Edict compile(CompileContext compCTX) { + CLParameters params = compCTX.decr.parameters; + CLModifiers mods = compCTX.decr.modifiers; + + RadixEdict.Mode mode; + + CLValue radixVal = CLValue.nil(); + + NumberParams np = null; + + if (params.length() == 0) { + if (mods.atMod) { + mode = RadixEdict.Mode.ROMAN; + } else if (mods.colonMod) { + mode = RadixEdict.Mode.ORDINAL; + } else { + mode = RadixEdict.Mode.CARDINAL; + } + } else { + mode = RadixEdict.Mode.NORMAL; + + if (params.length() < 1) + throw new IllegalArgumentException("R directive requires at least one parameter, the radix"); + + params.mapIndex("radix", 0); + radixVal = params.resolveKey("radix"); + + np = getParams(compCTX, 0); + } + + return new RadixEdict(mode, radixVal, np, mods.colonMod); + } +} + +class RadixEdict implements Edict { + public static enum Mode { + NORMAL, + ROMAN, + ORDINAL, + CARDINAL + } + + private Mode mode; + + private CLValue radixVal; + + private NumberParams np; + + private boolean isClassic; + + public RadixEdict(Mode mode, CLValue radix, NumberParams np, boolean isClassic) { + this.mode = mode; + + this.radixVal = radix; + + this.np = np; + } + + @Override + public void format(FormatContext formCTX) throws IOException { + Object item = formCTX.items.item(); + + CLFormatter.checkItem(item, 'R'); + + if (!(item instanceof Number)) { + throw new IllegalFormatConversionException('R', item.getClass()); + } + + long val = ((Number) item).longValue(); + + String res; + switch (mode) { + case ROMAN: + res = NumberUtils.toRoman(val, isClassic); + break; + case ORDINAL: + res = NumberUtils.toOrdinal(val); + break; + case CARDINAL: + res = NumberUtils.toCardinal(val); + break; + case NORMAL: + { + int radix = radixVal.asInt(formCTX.items, "radix", "R", 10); + + int mincol = np.mincol.asInt(formCTX.items, "minimum column count", "R", 0); + char padchar = np.padchar.asChar(formCTX.items, "padding character", "R", ' '); + + boolean signed = np.signed; + + if (np.commaMode) { + char commaChar = np.commaChar.asChar(formCTX.items, "comma character", "R", ','); + int commaInterval = np.commaInterval.asInt(formCTX.items, "comma interval", "R", 0); + + res = NumberUtils.toCommaString(val, mincol, padchar, commaInterval, commaChar, signed, radix); + } else { + res = NumberUtils.toNormalString(val, mincol, padchar, signed, radix); + } + + break; + } + + default: + throw new IllegalArgumentException("Unsupported radix mode " + mode); + } + + formCTX.writer.write(res); + + formCTX.items.right(); + } } |
