summaryrefslogtreecommitdiff
path: root/clformat/src/main/java/bjc/utils/ioutils
diff options
context:
space:
mode:
authorBenjamin J. Culkin <bjculkin@mix.wvu.edu>2019-08-08 21:26:59 -0300
committerBenjamin J. Culkin <bjculkin@mix.wvu.edu>2019-08-08 21:26:59 -0300
commit1bd9d9803c7a8056831af51d14bad7f5105c3ad3 (patch)
tree4ca21e9749cc1936b5bd213601e823a63512c5b6 /clformat/src/main/java/bjc/utils/ioutils
parent5218fb4a3cfde1568417c5190833c4c319721b5a (diff)
Implement compilation for number-print directives
Diffstat (limited to 'clformat/src/main/java/bjc/utils/ioutils')
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java65
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java72
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java121
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();
+ }
}