summaryrefslogtreecommitdiff
path: root/clformat/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'clformat/src/main')
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java24
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/DecimalDirective.java89
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();
+ }
+}