diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2020-10-17 17:13:23 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2020-10-17 17:13:23 -0300 |
| commit | f2702a50a2b7e27ba46c44101edfc737f8eb54ac (patch) | |
| tree | f13f701f83299acc56d4fda0e4242d1cf56f24eb /clformat/src/main/java/bjc/utils | |
| parent | 0a9fb6d243b891e2b56a5a73eb642e9ec8e81137 (diff) | |
Implement float printing
This implements a general directive for float printing (~`D). In the
long term, instead of this directive, a more specific one (probably
implemented by a macro or something) should be used
Diffstat (limited to 'clformat/src/main/java/bjc/utils')
| -rw-r--r-- | clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java | 24 | ||||
| -rw-r--r-- | clformat/src/main/java/bjc/utils/ioutils/format/directives/DecimalDirective.java | 89 |
2 files changed, 111 insertions, 2 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 9263beb..db137a5 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java @@ -70,6 +70,8 @@ public class CLFormatter { builtinDirectives.put("`[", new InflectDirective()); builtinDirectives.put("T", new TabulateDirective()); + + builtinDirectives.put("`D", new DecimalDirective()); } /** @@ -101,14 +103,32 @@ public class CLFormatter { */ public static void checkItem(Object itm, char directive) { if (itm == null) { - String msg - = String.format("No argument provided for %c directive", directive); + String msg = String.format("No argument provided for %c directive", directive); throw new IllegalArgumentException(msg); } } /** + * Check that an item is valid for a directive. + * + * @param itm + * The item to check. + * + * @param directive + * The directive to check for. + * + * @throws IllegalArgumentException + * if itm is null. + */ + public static void checkItem(Object itm, String directive) { + if (itm == null) { + String msg = String.format("No argument provided for %s directive", directive); + + throw new IllegalArgumentException(msg); + } + } + /** * Format a string in the style of CL's FORMAT. * * @param format diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/DecimalDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/DecimalDirective.java new file mode 100644 index 0000000..1130a85 --- /dev/null +++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/DecimalDirective.java @@ -0,0 +1,89 @@ +package bjc.utils.ioutils.format.directives; + +import java.io.*; +import java.text.*; + +import bjc.esodata.*; +import bjc.utils.ioutils.format.*; + +/** + * Implementation of the `D directive. + * + * This is the most general directive for printing out decimal-numbers (floating + * point). + * + * @author Ben Culkin + */ +public class DecimalDirective implements Directive { + @Override + public Edict compile(CompileContext compCTX) { + CLParameters params = compCTX.decr.parameters; + CLModifiers mods = compCTX.decr.modifiers; + + CLValue decForm = CLValue.nil(); + + switch(params.length()) { + case 0: + // Use the default + break; + case 1: + // Use the specified format + params.mapIndices("format"); + + decForm = params.resolveKey("format"); + break; + default: + // @TODO 16 Oct, 2020 - Ben Culkin - :Preformat + // Add ability to specify a common/fixed set of formats + // + // @TODO 16 Oct, 2020 - Ben Culkin - :ErrorFix + // Instead of using IllegalArgumentException here, use a custom + // subtype of it with an appropriate name/auto-message forming + throw new IllegalArgumentException("Must provide 0 or 1 arguments to `D directive"); + } + + return new DecimalEdict(decForm); + } +} + +class DecimalEdict implements Edict { + private static final FieldPosition ZERO_FIELD = new FieldPosition(0); + + private CLValue decFormat; + + public DecimalEdict(CLValue decForm) { + this.decFormat = decForm; + } + + @Override + public void format(FormatContext formCTX) throws IOException { + Tape<Object> itemTape = formCTX.items; + + CLFormatter.checkItem(itemTape.item(), "`D"); + + NumberFormat numForm = NumberFormat.getInstance(); + + String decFormString = decFormat.getValue(itemTape); + + if (decFormString == null || decFormString.equals("")) { + // Use the default if not provided. + } else { + if (numForm instanceof DecimalFormat) { + ((DecimalFormat)numForm).applyPattern(decFormString); + } else { + String clsName = numForm.getClass().getName(); + + String msg = String.format("INTERNAL ERROR: Unknown NumberFormat type %s, expected DecimalFormat or compatible", clsName); + + throw new UnsupportedOperationException(msg); + } + } + + StringBuffer work = new StringBuffer(); + + numForm.format(itemTape.item(), work, ZERO_FIELD); + + formCTX.writer.write(work.toString()); + itemTape.right(); + } +} |
