summaryrefslogtreecommitdiff
path: root/clformat
diff options
context:
space:
mode:
Diffstat (limited to 'clformat')
-rw-r--r--clformat/TODO20
-rw-r--r--clformat/data/clformat.sprop11
-rw-r--r--clformat/docs/Makefile22
-rw-r--r--clformat/docs/clformat.ms231
-rw-r--r--clformat/docs/clformat.tmac63
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java324
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLModifiers.java18
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java85
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLString.java10
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLTokenizer.java80
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java44
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/ClauseDecree.java54
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/Decree.java133
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/GroupDecree.java39
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/SimpleDecree.java129
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java57
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java16
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java17
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/CompileContext.java4
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java85
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/DecimalDirective.java89
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java34
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/FormatParameters.java22
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java7
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java2
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/IndentDirective.java11
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/InflectDirective.java25
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java63
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java4
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java5
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java18
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java12
-rw-r--r--clformat/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java24
-rw-r--r--clformat/src/test/java/bjc/utils/test/ioutils/CLFormatterTest.java16
-rw-r--r--clformat/src/test/java/bjc/utils/test/ioutils/CLTokenizerTest.java2
35 files changed, 1077 insertions, 699 deletions
diff --git a/clformat/TODO b/clformat/TODO
new file mode 100644
index 0000000..abe3a37
--- /dev/null
+++ b/clformat/TODO
@@ -0,0 +1,20 @@
+@TODO Nov 13th, 2020 Ben Culkin :InvokeDirective
+This is more a 'mad-science' kind of thing, but creating a directive that allows
+people to invoke invokable items passed as format arguments could be interesting.
+ The key-name for this directive would probably be `I, and there are a number
+ of invokable types that could be interesting
+ * Supplier<String> to just insert the resulting string.
+ * Function<Object, String> to convert a format item to a string.
+
+@TODO Nov 13th, 2020 Ben Culkin :ConfigDirectives
+Add a way to configure user-based directives from reading a config file, which
+allows you to bind directives to various characters and customize their behavior.
+One thing that will need to be involved is that all of the directives should
+probably have their interfaces tweaked to allow you to provide a custom form of
+them. One could argue this is the sort of thing that macros could do, but I can
+see no compelling reason not to implement both features
+
+@TODO Nov 14th, 2020 Ben Culkin :OnceDirective
+Implement a directive (`O probably) that will only be executed once per given
+invocation of 'format', or maybe one for 'once per enclosing directive'. Could
+be useful, especially once we have more stateful directives. \ No newline at end of file
diff --git a/clformat/data/clformat.sprop b/clformat/data/clformat.sprop
index ba1e83c..1d31de6 100644
--- a/clformat/data/clformat.sprop
+++ b/clformat/data/clformat.sprop
@@ -27,9 +27,9 @@ clFormatPrefixParam (?:(?:[-+]?\d+|'.|[Vv]|#|%|".*?(?<!\\)")?)
##
## Parameters are seperated by ','
##
-## Named parameters are indicated by a preceeding #, which is followed by a
-## parameter name (any sequence of non-space, non-seperator (',', ':', ';')
-## printing characters), a seperator (: or ;), then the value of the parameter
+## Named parameters are indicated by a preceding #, which is followed by a
+## parameter name (any sequence of non-space, non-separator (',', ':', ';')
+## printing characters), a separator (: or ;), then the value of the parameter
clFormatPrefix (?:(?:#[\S&&[^,:;]]+[:;]%1$s)|%1$s)
## Match a format string modifier
@@ -42,9 +42,10 @@ clFormatModifier (?:[@$:*]+)
## Matches a directive name.
## A directive name is either
-## 1) A single, non-whitespace, non-/ character, optionally preceded by a grave
+## 1) A single, non-whitespace, non-/ character, optionally preceded by any
+## number of grave characters.
## 2) A name enclosed in /'s
-clFormatName (?:(?<name>`?[\S&&[^/]])|(?:/(?<funcname>[\S&&[^/]]+)/))
+clFormatName (?:(?<name>`*[\S&&[^/]])|(?:/(?<funcname>[\S&&[^/]]+)/))
#################################################
# Generic format strings for regular expressions.
diff --git a/clformat/docs/Makefile b/clformat/docs/Makefile
new file mode 100644
index 0000000..c2ad7f4
--- /dev/null
+++ b/clformat/docs/Makefile
@@ -0,0 +1,22 @@
+.PHONY: all clean
+
+all: clformat.pdf
+
+clean:
+ rm clformat.pdf
+
+clformat.pdf: clformat.ps
+ ps2pdf clformat.ps clformat.pdf
+ rm clformat.ps
+
+clformat.ps: clformat.ms
+ groff -ms -s -t -Tps clformat.ms > clformat.ps
+
+clformat.ms: clformat.tmac
+ touch clformat.ms
+
+clformat.tmac:
+ touch clformat.tmac
+
+preview: clformat.pdf
+ fbpdf clformat.pdf
diff --git a/clformat/docs/clformat.ms b/clformat/docs/clformat.ms
new file mode 100644
index 0000000..1a2731f
--- /dev/null
+++ b/clformat/docs/clformat.ms
@@ -0,0 +1,231 @@
+\# CLFormat documentation
+\# Load macros and stuff
+.so clformat.tmac
+.TL
+CLFormat Documentation
+.AU
+Ben Culkin
+\# No abstract needed
+.AB no
+.AE
+.PP
+CLFormat is an implementation of something that is strongly reminiscent of the
+Common Lisp FORMAT function. I say 'strongly reminiscent', because we don't
+support quite all the directives they, but support several new ones they don't.
+.Section "Directive Syntax"
+FORMAT strings are made up of free-form text, with all of the functionality
+coming from \fIdirectives\fP. A directive is always started with a tilde, and
+consists of the following parts:
+.Numlist
+.Numitem
+.Italic "An optional set of " "prefix parameters" "."
+.Numitem
+.Italic "An optional set of " "directive modifiers" "."
+.Numitem
+The name of the directive
+.PP
+To execute a format string, and get it to provide formatting, a set of arguments
+called \fIformat items\fP must be provided. These serve the same purpose as the
+arguments provided to printf and other similar functions after their format
+string.
+.Subsection "Prefix Parameters"
+Prefix parameters are used to configure the options for a directive. These can
+include things varying from the number of columns to print a field in, to the
+radix that a number should be printed in. They are separated from each by
+commas.
+.PP
+A prefix parameter can be any one of the following:
+.Defn "A signed decimal number"
+The value of this parameter is the provided number.
+.Defn "A single character, preceeded by a single-quote"
+The value of this parameter is the provided character
+.Defn "The letter V"
+The value of this parameter will be read from the format string items.
+.Defn "The character #"
+The value of this parameter will be set to the number of format string
+parameters remaining
+.Defn "The character %"
+The value of this paramter will be set to the current position in the list
+of format string items.
+.Defn "A double quoted string"
+The value of this parameter is the represented string.
+.PP
+Prefix parameters are numbered positionally by default, but they can be given a
+name by starting the parameter with a # character, following that with a
+parameter name (which can be any series of printing characters that is not a
+whitespace character, and not one of the following separator characters: ',',
+',', ':' or ';'). It is then followed by a name-separator character (either ':'
+or ';') then its value from the above list.
+.Supersection "Notes"
+.Bullet
+The difference between ':' and ';' is that if you use ':', that
+parameter can't be addressed positionally, while if you use ';', it still can.
+.Bullet
+If you specify more parameters than a directive is noted to take, the behavior
+is based off of whether you've provided extra named, non-positional parameters or extra
+positional ones. You can specify as many named non-positional parameters as you
+want, and the directive will be fine. However, if you specify more or less
+positional parameters, that is an an error.
+.Bullet
+As a 'useful' feature, when you are naming named parameters, you may abbreviate
+the name to its shortest unambigous value. However, as an exception to the
+normal rule that you can provide unused named parameters, passing an ambiguous
+parameter name will cause an error. For instance, if a directive took the
+parameters 'foo', 'foobar' and 'fizz', these are some of the results:
+.RS
+.CWDefn "foo"
+ Refers to foo
+.CWDefn "foobar"
+ Refers to foobar
+.CWDefn "foob"
+ Refers to foobar
+.CWDefn "fizz"
+ Refers to fizz
+.CWDefn "fi"
+ Refers to fizz
+.CWDefn "f"
+ Error, could refer to foo, foobar or fizz
+.RE
+.Endsupersection
+.Endsubsection
+.Subsection "Directive modifiers"
+Directive modifiers, or \fImodifier sets\fP, are any combination of the
+following characters (with duplicate characters having no effect)
+.Bullet
+.CW "$"
+.Bullet
+.CW ":"
+.Bullet
+.CW "*"
+.Bullet
+.CW "@"
+.Endsubsection
+.Subsection "Directive names"
+A directive name can be either
+.Bullet
+A single, non-whitespace, non-/ character, optionally preceeded by a grave
+.Bullet
+A name bracketed by /
+.PP
+If the directive is a bracketed name, then it is a call to a user-specified
+function. Otherwise, it is an invocation of one of the built-in directives.
+.Endsubsection
+.Endsection
+.Section "Directive List"
+The following is a table of all of the directives that are currently implemented,
+as well as a short description of what each directive does.
+.KS
+.TS H
+center allbox ;
+c s s
+c | c | c .
+Directive Overview
+Directive Name Brief Description
+_
+.TH
+.T&
+lfCR | l | l .
+A Aesthetic General string printer.
+S Alias for the A directive\[dg]
+C Character Print out a single character
+B Binary Print out a base-2 integer
+O Octal Print out a base-8 integer
+D Decimal Print out a base-10 integer
+X Hexadecimal Print out a base-16 integer
+R Radix Print out an integer in an arbitrary base\[bu]
+& Fresh Line Print a newline character, if we didn't just print one
+% Newline Print out a literal new line
+| Formfeed Print out a 'formfeed' and start a new page
+~ Tilde Print out a literal tilde
+? Recursive Invoke a sub-frmat string
+* Go-to Move around in the item list
+^ Escape Escape from an enclosing directive
+[ Conditional Select a sub-format string, based on a conditional
+{ Iteration Repeatedly invoke a sub-format string
+( Case Perform case-manipulation on text
+\`[ Inflection Perform inflection (pluralization/singularization) on a sub-format string
+T Tabulate Print items in a tabular format
+.TE
+.ce 1
+\fITable 1: Directive Overview\fP
+.KE
+.FS \[dg]
+CommonLisp has S use a slightly different format, but there isn't one that makes
+sense for us to use. In the future, we may either come up with a format, or
+reassign S to do something else entirely
+.FE
+.FS \[bu]
+At some point, it may make sense to remove some of the radix-specific ones, and
+just tell people to use R. However, for now, we're sticking with it.
+.FE
+.PP
+The following are directives that aren't valid for use outside of a specific
+context (usually, they must follow another directive
+.KS
+.TS H
+center allbox ;
+c s s
+c | c | c .
+Context-Sensitive Directives
+Directive Name Brief Description
+_
+.TH
+.T&
+lfCR | l | l .
+] End Conditional Ends a conditional directive
+; Clause Separator Separates two clauses in a block directive
+) End Case Ends a case directive
+\'] End Inflection Ends a inflection directive
+< Inflection Start Starts an inflection control
+> Inflection End Ends an inflection control
+.TE
+.ce 1
+\fITable 2: Context-Sensitive Directives\fP
+.KE
+.PP
+And the following are directives which have not yet been implemented
+.KS
+.TS H
+center allbox ;
+c s s
+c | c | c .
+Unimplemented Directives
+Directive Name Brief Description
+_
+.TH
+.T&
+lfCR | l | l .
+\`< Start Layout Start a layout-control block
+\`> End Layout Ends a layout-control block
+F Fixed-Format Float Print a floating-point number in a fixed-point format
+E Exponential Float Print a engineering-style (1.2e2) floating point number
+G General Float Print a general floating point number
+$ Monetary Float Print a floating point number like currency
+W String Print Use the A directive instead
+P Plural Use the `[ and `] directives instead
+.TE
+.ce 1
+\fITable 3: Unimplemented Directives\fP
+.KE
+.PP
+The following section contains a detailed reference for the directives mentioned
+above. This details how the directive works, how many parameters it takes, and
+of what sort they should be, and whatever other details are necessary for that
+particular directive.
+.Subsection "A Directive"
+.PP
+The A directive is the general purpose string formatting directive, serving as
+the equivalent to the S specifier in printf and other similar formats.
+
+It takes either zero, one or four parameters, as well as one format string item.
+.KS
+.TS
+allbox;
+c c
+lfCR l .
+Sample Format String Description
+~a Prints out the format string item as a string
+.TE
+.KE
+.Endsubsection
+.Endsection
diff --git a/clformat/docs/clformat.tmac b/clformat/docs/clformat.tmac
new file mode 100644
index 0000000..0d7da96
--- /dev/null
+++ b/clformat/docs/clformat.tmac
@@ -0,0 +1,63 @@
+\# Useful macros and settings
+\# Section header
+.de Section
+.NH 1
+\s+4\\$1\s-4
+\# Place current section title in right corner
+.ds RH "\\$1
+.PP
+..
+\# Section footer
+.de Endsection
+..
+\# Subsection header
+.de Subsection
+.NH 2
+\s+2\\$1\s-2
+.RS
+.PP
+..
+\# Subsection footer
+.de Endsubsection
+.RE
+..
+\# Supersection header
+.de Supersection
+.NH 3
+\\$1
+.RS
+.PP
+..
+\# Supersection footer
+.de Endsupersection
+.RE
+..
+\# Bulleted list item
+.de Bullet
+.IP \[bu]
+..
+\# Simple numbered list
+.de Numlist
+.nr listitem 0 1
+..
+\# Item in numbered list
+.de Numitem
+.IP "\\n+[listitem]."
+..
+\# Italicize text
+.de Italic
+.I "\\$2" "\\$3" "\\$1"
+..
+\# Definition-list item
+.de Defn
+.IP "\fB\\$1\fP"
+..
+\# Constant-width Definition-list item
+.de CWDefn
+.IP "\f(CB\\$1\fP"
+..
+\# Set in 12pt font
+.nr PS 12p
+\# Put manual title in left corner
+.ds LH "CLFormat Manual
+.DA
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..276356c 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java
@@ -8,7 +8,6 @@ import bjc.utils.ioutils.ReportWriter;
import bjc.utils.ioutils.format.directives.*;
// Grab our easy converters/constructors
-import static bjc.utils.funcutils.IteratorUtils.AI;
import static bjc.utils.funcutils.IteratorUtils.I;
/**
@@ -70,6 +69,8 @@ public class CLFormatter {
builtinDirectives.put("`[", new InflectDirective());
builtinDirectives.put("T", new TabulateDirective());
+
+ builtinDirectives.put("`D", new DecimalDirective());
}
/**
@@ -101,14 +102,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
@@ -123,7 +142,7 @@ public class CLFormatter {
* if something goes wrong during formatting the string.
*/
public String formatString(String format, Object... params) throws IOException {
- return formatString(format, I(AI(params)));
+ return formatString(format, I(I(params)));
}
/**
@@ -280,103 +299,91 @@ public class CLFormatter {
boolean isToplevel) throws IOException {
try {
while (cltok.hasNext()) {
- Decree decr = cltok.next();
+ SimpleDecree decr = cltok.next();
if (decr.isLiteral) {
rw.write(decr.name);
- continue;
- }
-
- Object item = tParams.item();
-
- if (decr.isUserCall) {
+ } else if (decr.isUserCall) {
/*
* @TODO implement user-called functions.
*/
- continue;
- }
-
- if (extraDirectives.containsKey(decr.name)) {
+ } else if (extraDirectives.containsKey(decr.name)) {
FormatParameters params
- = new FormatParameters(rw, item, decr, tParams, cltok, this);
+ = new FormatParameters(rw, tParams.item(), decr,
+ tParams, cltok, this);
extraDirectives.get(decr.name).format(params);
-
- continue;
- }
-
- if (builtinDirectives.containsKey(decr.name)) {
+ } else if (builtinDirectives.containsKey(decr.name)) {
FormatParameters params
- = new FormatParameters(rw, item, decr, tParams, cltok, this);
+ = new FormatParameters(rw, tParams.item(), decr,
+ tParams, cltok, this);
builtinDirectives.get(decr.name).format(params);
- continue;
- }
-
- if (decr.name == null)
- decr.name = "<null>";
-
- switch (decr.name) {
- case "]":
- throw new IllegalArgumentException(
- "Found conditional-end outside of conditional.");
- case ";":
- throw new IllegalArgumentException(
- "Found seperator outside of block.");
- case "}":
- throw new IllegalArgumentException(
- "Found iteration-end outside of iteration");
- case ")":
- throw new IllegalArgumentException(
- "Case-conversion end outside of case conversion");
- case "`]":
- throw new IllegalArgumentException(
- "Inflection-end outside of inflection");
- case "<":
- case ">":
- throw new IllegalArgumentException(
- "Inflection marker outside of inflection");
- case "`<":
- case "`>":
- throw new IllegalArgumentException(
- "Layout-control directives aren't implemented yet.");
- case "F":
- case "E":
- case "G":
- case "$":
- /*
- * @TODO
- *
- * implement floating point directives.
- */
- throw new IllegalArgumentException(
- "Floating-point directives aren't implemented yet.");
- case "W":
- /*
- * @TODO
- *
- * figure out if we want to implement someting for these directives
- * instead of punting.
- */
- throw new IllegalArgumentException(
- "S and W aren't implemented. Use A instead");
- case "P":
- throw new IllegalArgumentException(
- "These directives aren't implemented yet");
- case "\n":
- /*
- * Ignored newline.
- */
- break;
- default:
- String msg
- = String.format("Unknown format directive '%s'", decr.name);
- throw new IllegalArgumentException(msg);
+ } else {
+ // All of these conditions are an error in some way
+ if (decr.name == null) decr.name = "<null>";
+
+ switch (decr.name) {
+ case "]":
+ throw new IllegalArgumentException(
+ "Found conditional-end outside of conditional.");
+ case ";":
+ throw new IllegalArgumentException(
+ "Found seperator outside of block.");
+ case "}":
+ throw new IllegalArgumentException(
+ "Found iteration-end outside of iteration");
+ case ")":
+ throw new IllegalArgumentException(
+ "Case-conversion end outside of case conversion");
+ case "`]":
+ throw new IllegalArgumentException(
+ "Inflection-end outside of inflection");
+ case "<":
+ case ">":
+ throw new IllegalArgumentException(
+ "Inflection marker outside of inflection");
+ case "`<":
+ case "`>":
+ throw new IllegalArgumentException(
+ "Layout-control directives aren't implemented yet.");
+ case "F":
+ case "E":
+ case "G":
+ case "$":
+ /*
+ * @TODO
+ *
+ * implement floating point directives.
+ */
+ throw new IllegalArgumentException(
+ "For now, floating point directives are implemented via the `D directive. Use that instead");
+ case "W":
+ /*
+ * @TODO
+ *
+ * figure out if we want to implement someting for these directives
+ * instead of punting.
+ */
+ throw new IllegalArgumentException(
+ "S and W aren't implemented. Use A instead");
+ case "P":
+ throw new IllegalArgumentException(
+ "These directives aren't implemented yet");
+ case "\n":
+ /*
+ * Ignored newline.
+ */
+ break;
+ default:
+ String msg
+ = String.format("Unknown format directive '%s'", decr.name);
+ throw new IllegalArgumentException(msg);
+ }
}
}
} catch (DirectiveEscape eex) {
- if (!isToplevel)
- throw eex;
+ if (!isToplevel) throw eex;
}
}
@@ -404,10 +411,9 @@ public class CLFormatter {
*
* @return A set of edicts compiled from the decrees.
*/
- public List<Edict> compile(Iterable<Decree> decrees) {
+ public List<Edict> compile(Iterable<SimpleDecree> decrees) {
// If we have no decrees, there are no edicts.
- if (decrees == null)
- return new ArrayList<>();
+ if (decrees == null) return new ArrayList<>();
CLTokenizer it = CLTokenizer.fromTokens(decrees);
return compile(it);
@@ -422,10 +428,8 @@ public class CLFormatter {
* @return The set of edicts compiled from the clause.
*/
public List<Edict> compile(ClauseDecree clause) {
- if (clause == null)
- return new ArrayList<>();
-
- return compile(clause.body);
+ if (clause == null) return new ArrayList<>();
+ else return compile(clause.body);
}
/**
@@ -440,96 +444,86 @@ public class CLFormatter {
List<Edict> result = new ArrayList<>();
while (cltok.hasNext()) {
- Decree decr = cltok.next();
+ SimpleDecree decr = cltok.next();
String nam = decr.name;
CompileContext compCTX = new CompileContext(cltok, this, decr);
if (decr.isLiteral) {
result.add(new StringEdict(decr.name));
-
- continue;
- }
-
- if (decr.isUserCall) {
+ } else if (decr.isUserCall) {
/*
* @TODO implement user-called functions.
*/
throw new IllegalArgumentException(
"User-called functions have not yet been implemented");
- }
-
- if (extraDirectives.containsKey(nam)) {
+ } else if (extraDirectives.containsKey(nam)) {
Edict edt = extraDirectives.get(nam).compile(compCTX);
result.add(edt);
-
- continue;
} else if (builtinDirectives.containsKey(nam)) {
Edict edt = builtinDirectives.get(nam).compile(compCTX);
result.add(edt);
-
- continue;
- }
-
- if (nam == null)
- nam = "<null>";
-
- switch (nam) {
- case "]":
- throw new IllegalArgumentException(
- "Found conditional-end outside of conditional.");
- case ";":
- throw new IllegalArgumentException("Found seperator outside of block.");
- case "}":
- throw new IllegalArgumentException(
- "Found iteration-end outside of iteration");
- case ")":
- throw new IllegalArgumentException(
- "Case-conversion end outside of case conversion");
- case "`]":
- throw new IllegalArgumentException(
- "Inflection-end outside of inflection");
- case "<":
- case ">":
- throw new IllegalArgumentException(
- "Inflection marker outside of inflection");
- case "`<":
- case "`>":
- throw new IllegalArgumentException(
- "Layout-control directives aren't implemented yet.");
- case "F":
- case "E":
- case "G":
- case "$":
- /*
- * @TODO
- *
- * implement floating point directives.
- */
- throw new IllegalArgumentException(
- "Floating-point directives aren't implemented yet.");
- case "W":
- /*
- * @TODO
- *
- * figure out if we want to implement someting for these directives
- * instead of punting.
- */
- throw new IllegalArgumentException(
- "S and W aren't implemented. Use A instead");
- case "P":
- throw new IllegalArgumentException(
- "These directives aren't implemented yet");
- case "\n":
- /*
- * Ignored newline.
- */
- break;
- default:
- String msg = String.format("Unknown format directive '%s'", nam);
- throw new IllegalArgumentException(msg);
+ } else {
+ // All of these conditions are an error in some way
+ if (nam == null) nam = "<null>";
+
+ switch (nam) {
+ case "]":
+ throw new IllegalArgumentException(
+ "Found conditional-end outside of conditional.");
+ case ";":
+ throw new IllegalArgumentException("Found seperator outside of block.");
+ case "}":
+ throw new IllegalArgumentException(
+ "Found iteration-end outside of iteration");
+ case ")":
+ throw new IllegalArgumentException(
+ "Case-conversion end outside of case conversion");
+ case "`]":
+ throw new IllegalArgumentException(
+ "Inflection-end outside of inflection");
+ case "<":
+ case ">":
+ throw new IllegalArgumentException(
+ "Inflection marker outside of inflection");
+ case "`<":
+ case "`>":
+ throw new IllegalArgumentException(
+ "Layout-control directives aren't implemented yet.");
+ case "F":
+ case "E":
+ case "G":
+ case "$":
+ /*
+ * @TODO
+ *
+ * implement floating point directives.
+ */
+ throw new IllegalArgumentException(
+ "Floating-point directives aren't implemented yet.");
+ case "W":
+ /*
+ * @TODO
+ *
+ * figure out if we want to implement someting for these directives
+ * instead of punting.
+ */
+ throw new IllegalArgumentException(
+ "S and W aren't implemented. Use A instead");
+ case "P":
+ throw new IllegalArgumentException(
+ "These directives aren't implemented yet");
+ case "\n":
+ /*
+ * Ignored newline.
+ */
+ break;
+ default:
+ String msg = String.format("Unknown format directive '%s'", nam);
+ throw new IllegalArgumentException(msg);
+ }
}
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLModifiers.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLModifiers.java
index e2cb8b4..c0bd75d 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/CLModifiers.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLModifiers.java
@@ -60,10 +60,10 @@ public class CLModifiers {
boolean starMod = false;
if (modString != null) {
- atMod = modString.contains("@");
- colonMod = modString.contains(":");
+ atMod = modString.contains("@");
+ colonMod = modString.contains(":");
dollarMod = modString.contains("$");
- starMod = modString.contains("*");
+ starMod = modString.contains("*");
}
return new CLModifiers(atMod, colonMod, dollarMod, starMod);
@@ -73,14 +73,10 @@ public class CLModifiers {
public String toString() {
StringBuilder sb = new StringBuilder();
- if (atMod)
- sb.append('@');
- if (colonMod)
- sb.append(':');
- if (dollarMod)
- sb.append('$');
- if (starMod)
- sb.append('*');
+ if (atMod) sb.append('@');
+ if (colonMod) sb.append(':');
+ if (dollarMod) sb.append('$');
+ if (starMod) sb.append('*');
return sb.toString();
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java
index aef8fbe..61d88bf 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java
@@ -5,6 +5,10 @@ import java.util.*;
import bjc.esodata.*;
import bjc.utils.parserutils.TokenUtils;
+// @TODO Nov 13th, 2020 Ben Culkin :ParameterDefaulting
+// Implement a method which will 'overlay' a set of parameters onto another
+// paramater set, with support for preferring one or the other.
+
/**
* Represents a set of parameters to a CL format directive.
*
@@ -13,13 +17,13 @@ import bjc.utils.parserutils.TokenUtils;
public class CLParameters {
private static String MSG_FMT = "Invalid %s (%s) \"%s\" to %s directive";
- private static String RX_TRUE = "(?i)y(?:es)?|t(?:rue)?(?i)";
+ private static String RX_TRUE = "(?i)y(?:es)?|t(?:rue)?(?i)";
private static String RX_FALSE = "(?i)no?|f(?:alse)?(?i)";
private CLValue[] params;
private Set<String> abbrevWords;
- private AbbrevMap2 nameAbbrevs;
+ private AbbrevMap2 nameAbbrevs;
private Map<String, CLValue> namedParams;
private Map<String, Integer> nameIndices;
@@ -80,19 +84,13 @@ public class CLParameters {
// with here, as these objects are fairly temporary.
//
// If it becomes an issue, I'll resolve it
- for (String key : namedParams.keySet()) {
- refreshAbbrev(key);
- }
-
- for (String key : nameIndices.keySet()) {
- refreshAbbrev(key);
- }
+ for (String key : namedParams.keySet()) refreshAbbrev(key);
+ for (String key : nameIndices.keySet()) refreshAbbrev(key);
}
// Refresh a particular abbreviation
private void refreshAbbrev(String key) {
- if (abbrevWords.contains(key))
- return;
+ if (abbrevWords.contains(key)) return;
abbrevWords.add(key);
nameAbbrevs.add(key);
@@ -110,8 +108,7 @@ public class CLParameters {
for (int i = 0; i < opts.length; i++) {
String opt = opts[i];
- if (!opt.equals(""))
- mapIndex(opt, i);
+ if (!opt.equals("")) mapIndex(opt, i);
}
refreshAbbrevs();
@@ -139,8 +136,7 @@ public class CLParameters {
nameIndices.put(opt.toUpperCase(), idx);
- if (doRefresh)
- refreshAbbrevs();
+ if (doRefresh) refreshAbbrevs();
}
/**
@@ -152,8 +148,7 @@ public class CLParameters {
* @return The value at that index.
*/
public CLValue getByIndex(int idx) {
- if (idx < 0 || idx >= params.length)
- return null;
+ if (idx < 0 || idx >= params.length) return null;
return params[idx];
}
@@ -235,8 +230,7 @@ public class CLParameters {
if (ch == ':' || ch == ';') {
// Semicolon says to add as
// indexed parameter
- if (ch == ';')
- setIndex = true;
+ if (ch == ';') setIndex = true;
nameIdx = i;
break;
@@ -251,8 +245,7 @@ public class CLParameters {
namedParams.put(paramName.toUpperCase(), actVal);
- if (setIndex)
- parameters.add(actVal);
+ if (setIndex) parameters.add(actVal);
} else {
parameters.add(parseParam(param));
}
@@ -311,10 +304,11 @@ public class CLParameters {
sb.append("\". Could've meant: ");
boolean isFirst = true;
for (String possKey : keys) {
- if (!isFirst)
- sb.append(", ");
- if (isFirst)
+ if (isFirst) {
isFirst = false;
+ } else {
+ sb.append(", ");
+ }
sb.append("\"");
sb.append(possKey);
@@ -335,10 +329,8 @@ public class CLParameters {
// @NOTE 9/22/18
//
// Consider whether we should throw an exception here.
- if (idx < 0 || idx >= params.length)
- return null;
-
- return params[idx];
+ if (idx < 0 || idx >= params.length) return null;
+ else return params[idx];
}
return null;
@@ -370,10 +362,8 @@ public class CLParameters {
String bol = resolveKey(key).getValue(parms);
if (!bol.equals("")) {
- if (bol.matches(RX_TRUE))
- return true;
- else if (bol.matches(RX_FALSE))
- return false;
+ if (bol.matches(RX_TRUE)) return true;
+ else if (bol.matches(RX_FALSE)) return false;
else {
String msg = String.format(MSG_FMT, paramName, key, bol, directive);
throw new IllegalArgumentException(msg);
@@ -412,8 +402,7 @@ public class CLParameters {
//
// This raises the question of what to do if the empty string is a valid
// value for a parameter
- if (!vl.equals(""))
- return vl;
+ if (!vl.equals("")) return vl;
return def;
}
@@ -508,25 +497,23 @@ public class CLParameters {
int idx = 0;
// First off, the named parameters
for (Map.Entry<String, CLValue> param : namedParams.entrySet()) {
- String paramName = param.getKey();
+ String paramName = param.getKey();
CLValue paramValue = param.getValue();
if (nameIndices.containsKey(paramName)) {
int paramIdx = nameIndices.get(paramName);
- String msg
- = String.format("%s(%d):'%s'", paramName, paramIdx, paramValue);
+ String msg = String.format("%s(%d):'%s'",
+ paramName, paramIdx, paramValue);
- if (idx != 0)
- sb.append(", ");
+ if (idx != 0) sb.append(", ");
sb.append(msg);
seenIndices.add(idx);
} else {
String msg = String.format("%s:'%s'", paramName, paramValue);
- if (idx != 0)
- sb.append(", ");
+ if (idx != 0) sb.append(", ");
sb.append(msg);
}
@@ -541,14 +528,12 @@ public class CLParameters {
int paramIdx = paramMap.getValue();
// We've already gotten this argument before
- if (seenIndices.contains(paramIdx))
- continue;
+ if (seenIndices.contains(paramIdx)) continue;
- String msg
- = String.format("%d(%s):'%s'", paramIdx, paramName, params[paramIdx]);
+ String msg = String.format("%d(%s):'%s'",
+ paramIdx, paramName, params[paramIdx]);
- if (idx != 0)
- sb.append(", ");
+ if (idx != 0) sb.append(", ");
sb.append(msg);
seenIndices.add(paramIdx);
@@ -559,13 +544,11 @@ public class CLParameters {
// Third, unnamed indexed parameters
for (idx = 0; idx < params.length; idx++) {
// We've already gotten this argument before
- if (seenIndices.contains(idx))
- continue;
+ if (seenIndices.contains(idx)) continue;
String msg = String.format("%d:'%s'", idx, params[idx]);
- if (idx != 0)
- sb.append(", ");
+ if (idx != 0) sb.append(", ");
sb.append(msg);
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLString.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLString.java
index 01e7617..6d77503 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/CLString.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLString.java
@@ -98,9 +98,7 @@ public class CLString {
*/
public String format(FormatContext formCTX) throws IOException {
try {
- for (Edict edt : edicts) {
- edt.format(formCTX);
- }
+ for (Edict edt : edicts) edt.format(formCTX);
} catch (DirectiveEscape eex) {
// General escape exception, so stop formatting.
}
@@ -114,10 +112,8 @@ public class CLString {
* @return If this format string is empty.
*/
public boolean isEmpty() {
- if (edicts.size() == 0)
- return true;
-
- return false;
+ if (edicts.size() == 0) return true;
+ else return false;
}
@Override
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 af7c935..7ed76d2 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/CLTokenizer.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLTokenizer.java
@@ -9,7 +9,7 @@ import java.util.regex.*;
* @author bjculkin
*
*/
-public class CLTokenizer implements Iterator<Decree> {
+public class CLTokenizer implements Iterator<SimpleDecree> {
/**
* Whether or not the tokenizer is in debug mode or not.
*/
@@ -19,34 +19,30 @@ public class CLTokenizer implements Iterator<Decree> {
* Internal class for a tokenizer that returns a specific set of tokens.
*/
private static class SetCLTokenizer extends CLTokenizer {
- private Iterator<Decree> body;
+ private Iterator<SimpleDecree> body;
- public SetCLTokenizer(Iterator<Decree> bod) {
+ public SetCLTokenizer(Iterator<SimpleDecree> bod) {
body = bod;
}
- public SetCLTokenizer(Iterable<Decree> bod) {
+ public SetCLTokenizer(Iterable<SimpleDecree> bod) {
body = bod.iterator();
}
@Override
public boolean hasNext() {
- boolean nxt = body.hasNext();
-
- return nxt;
+ return body.hasNext();
}
@Override
- public Decree next() {
- Decree nxt = body.next();
-
- return nxt;
+ public SimpleDecree next() {
+ return body.next();
}
}
private Matcher mat;
- private Decree dir;
+ private SimpleDecree dir;
/**
* Empty constructor that should only be invoked if you are a subclass who
@@ -74,7 +70,7 @@ public class CLTokenizer implements Iterator<Decree> {
*
* @return A tokenizer yielding the given set of decrees.
*/
- public static CLTokenizer fromTokens(Iterator<Decree> bod) {
+ public static CLTokenizer fromTokens(Iterator<SimpleDecree> bod) {
return new SetCLTokenizer(bod);
}
@@ -86,30 +82,25 @@ public class CLTokenizer implements Iterator<Decree> {
*
* @return A tokenizer yielding the given set of decrees.
*/
- public static CLTokenizer fromTokens(Iterable<Decree> bod) {
+ public static CLTokenizer fromTokens(Iterable<SimpleDecree> bod) {
return new SetCLTokenizer(bod);
}
@Override
public boolean hasNext() {
- boolean nxt = !mat.hitEnd();
-
- return nxt;
+ return !mat.hitEnd();
}
@Override
- public Decree next() {
- Decree tk = getNext();
-
- return tk;
+ public SimpleDecree next() {
+ return getNext();
}
- private Decree getNext() {
- if (!hasNext())
- throw new NoSuchElementException("No possible decrees remaining");
+ private SimpleDecree getNext() {
+ if (!hasNext()) throw new NoSuchElementException("No possible decrees remaining");
if (dir != null) {
- Decree tmp = dir;
+ SimpleDecree tmp = dir;
dir = null;
@@ -124,39 +115,35 @@ public class CLTokenizer implements Iterator<Decree> {
String tmp = sb.toString();
{
- String dirName = mat.group("name");
- String dirFunc = mat.group("funcname");
- String dirMods = mat.group("modifiers");
- String dirParams = mat.group("params");
+ String directiveName = mat.group("name");
+ String directiveFunction = mat.group("funcname");
+ String directiveModifierString = mat.group("modifiers");
+ String directiveParameterString = mat.group("params");
- if (dirMods == null) {
- dirMods = "";
- }
-
- if (dirParams == null) {
- dirParams = "";
- }
+ if (directiveModifierString == null) directiveModifierString = "";
+ if (directiveParameterString == null) directiveParameterString = "";
- boolean isUser = dirName == null && dirFunc != null;
+ boolean isUser = directiveName == null && directiveFunction != null;
- dir = new Decree(dirName, isUser, CLParameters.fromDirective(dirParams),
- CLModifiers.fromString(dirMods));
+ dir = new SimpleDecree(directiveName, isUser,
+ CLParameters.fromDirective(directiveParameterString),
+ CLModifiers.fromString(directiveModifierString));
}
if (tmp.equals("")) {
- Decree dcr = dir;
+ SimpleDecree dcr = dir;
dir = null;
return dcr;
}
- return new Decree(sb.toString());
+ return new SimpleDecree(sb.toString());
}
mat.appendTail(sb);
- return new Decree(sb.toString());
+ return new SimpleDecree(sb.toString());
}
/**
@@ -170,7 +157,7 @@ public class CLTokenizer implements Iterator<Decree> {
*
* @return A group decree with the given properties.
*/
- public GroupDecree nextGroup(Decree openedWith, String desiredClosing) {
+ public GroupDecree nextGroup(SimpleDecree openedWith, String desiredClosing) {
return nextGroup(openedWith, desiredClosing, null);
}
@@ -190,19 +177,18 @@ public class CLTokenizer implements Iterator<Decree> {
*
* @return A group decree with the given properties.
*/
- public GroupDecree nextGroup(Decree openedWith, String desiredClosing,
+ public GroupDecree nextGroup(SimpleDecree openedWith, String desiredClosing,
String clauseSep) {
GroupDecree newGroup = new GroupDecree();
newGroup.opening = openedWith;
- if (!hasNext())
- throw new NoSuchElementException("No decrees available");
+ if (!hasNext()) throw new NoSuchElementException("No decrees available");
ClauseDecree curClause = new ClauseDecree();
int nestingLevel = 1;
- Decree curDecree;
+ SimpleDecree curDecree;
do {
curDecree = next();
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java
index e4b4c32..c623e6f 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLValue.java
@@ -2,6 +2,25 @@ package bjc.utils.ioutils.format;
import bjc.esodata.*;
+// @TODO Nov 13th, 2020 Ben Culkin :DefaultValues
+// Create some way to specify default values for the arguments to the various
+// asWhatever methods. This will cleanup use-site code for them
+
+/* @TODO Nov 13th, 2020 Ben Culkin :ParamVariables
+ * Create a new CLValue type that implements variables in a way. There are a
+ * number of different sorts of 'scopes' that could be useful, so here is the
+ * list of them:
+ * - Static variables, stored on the CLString instance
+ * - Global variables, stored on a map set on the FormatContext when formatting
+ * starts, and copied over whenever a new context is built.
+ * - Lexical variables, stored on the FormatContext, but in some sort of map which
+ * models lexical scopes (extend on FunctionalMap may do the right thing, not sure)
+ * - Local variables, stored on the FormatContext as well, but these
+ * aren't copied over when a new context is built.
+ *
+ * For static/global variables, maybe some equivalent of 'local' from perl to
+ * localize them.
+ */
/**
* Represents a parameter value to an edict that may have a dynamic value
* obtained from the format arguments.
@@ -18,23 +37,14 @@ public interface CLValue {
* @return The CLValue represented by the string.
*/
public static CLValue parse(String val) {
- if (val == null)
- return new NullValue();
-
- if (val.equalsIgnoreCase("V")) {
- return new VValue();
- }
+ if (val == null) return new NullValue();
switch (val) {
- case "V":
- case "v":
- return new VValue();
- case "#":
- return new HashValue();
- case "%":
- return new PercValue();
- default:
- return new LiteralValue(val);
+ case "V": // Fall-through, V is the same as v
+ case "v": return new VValue();
+ case "#": return new HashValue();
+ case "%": return new PercValue();
+ default: return new LiteralValue(val);
}
}
@@ -60,7 +70,7 @@ public interface CLValue {
* The format parameters to use.
*
* @param paramName
- * The user-intelligble name for the value.
+ * The user-intelligible name for the value.
*
* @param directive
* The directive this value is for.
@@ -107,7 +117,7 @@ public interface CLValue {
* The format parameters to use.
*
* @param paramName
- * The user-intelligble name for the value.
+ * The user-intelligible name for the value.
*
* @param directive
* The directive the value is for.
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/ClauseDecree.java b/clformat/src/main/java/bjc/utils/ioutils/format/ClauseDecree.java
index aa4efbe..db38eca 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/ClauseDecree.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/ClauseDecree.java
@@ -13,16 +13,16 @@ import bjc.utils.ioutils.ReportWriter;
*
* @author Ben Culkin
*/
-public class ClauseDecree {
+public class ClauseDecree implements Decree {
/**
* The decrees that make up the body of this clause.
*/
- public List<Decree> body;
+ public List<SimpleDecree> body;
/**
* The decree that terminated this clause.
*/
- public Decree terminator;
+ public SimpleDecree terminator;
/**
* Create a new blank clause decree.
@@ -38,12 +38,10 @@ public class ClauseDecree {
* @param children
* The decrees to form the body of the clause.
*/
- public ClauseDecree(Decree... children) {
+ public ClauseDecree(SimpleDecree... children) {
this();
- for (Decree child : children) {
- body.add(child);
- }
+ for (SimpleDecree child : children) body.add(child);
}
/**
@@ -55,7 +53,7 @@ public class ClauseDecree {
* @param children
* The decrees that form the body of the clause.
*/
- public ClauseDecree(Decree term, Decree... children) {
+ public ClauseDecree(SimpleDecree term, SimpleDecree... children) {
this(children);
this.terminator = term;
@@ -67,32 +65,40 @@ public class ClauseDecree {
* @param child
* The decree to add to this clause.
*/
- public void addChild(Decree child) {
+ public void addChild(SimpleDecree child) {
body.add(child);
}
@Override
public String toString() {
- try (ReportWriter rw = new ReportWriter()) {
- String term = "<null>";
- if (terminator != null)
- term = terminator.toString();
-
- rw.write("ClauseDecree (terminator " + term.toString() + ")");
- rw.indent();
- rw.write("\n");
-
- for (Decree kid : body) {
- rw.write("Child: " + kid.toString() + "\n");
- }
+ try (ReportWriter writer = new ReportWriter()) {
+ toReportWriter(writer);
- rw.dedent();
-
- return rw.toString();
+ return writer.toString();
} catch (IOException ioex) {
return "<IOEXCEPTION>";
}
// return String.format("ClauseDecree [body=%s, terminator=%s]", body,
// terminator);
}
+
+ /**
+ * Write the string version of this decree to a report writer.
+ * @param writer The report write to write to.
+ * @throws IOException If something goes wrong
+ */
+ public void toReportWriter(ReportWriter writer) throws IOException {
+ String term = "<null>";
+ if (terminator != null) term = terminator.toString();
+
+ writer.writef("ClauseDecree (terminator %s)", term);
+ writer.indent();
+ writer.write("\n");
+
+ int idx = 0;
+ for (SimpleDecree kid : body)
+ writer.writef("Child %d: %s\n", idx, kid.toString());
+
+ writer.dedent();
+ }
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/Decree.java b/clformat/src/main/java/bjc/utils/ioutils/format/Decree.java
index 9a90285..e06caf0 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/Decree.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/Decree.java
@@ -1,131 +1,14 @@
package bjc.utils.ioutils.format;
/**
- * A decree is the building blocks of what we need to pick and call a directive.
+ * Interface for all decrees.
+ *
+ * At the moment, this is just a marker interface, but there may be things added
+ * here.
+ *
+ * @author Ben Culkin
*
- * Namely, it is the name of the directive, any modifiers attached to the
- * directive, and any prefix parameters that are also attached to the directive.
- *
- * @author Ben Culkin.
*/
-public class Decree {
- /**
- * The name of the directive.
- */
- public String name;
-
- /**
- * Is this directive an actual directive, or just a literal string?
- */
- public boolean isLiteral;
-
- /**
- * Is this directive a user function call?
- */
- public boolean isUserCall;
-
- /**
- * The prefix parameters for this directive.
- */
- public CLParameters parameters;
-
- /**
- * The modifiers for this directive.
- */
- public CLModifiers modifiers;
-
- /**
- * Create a new blank decree.
- */
- public Decree() {
-
- }
-
- /**
- * Create a new literal text directive.
- *
- * @param txt
- * The text of the directive.
- */
- public Decree(String txt) {
- this.name = txt;
-
- this.isLiteral = true;
- }
-
- /**
- * Create a new directive.
- *
- * @param name
- * The name of the directive. Whether or not it is an actual
- * directive will be auto-determined (if it starts with a ~, it's
- * a directive.)
- *
- * @param params
- * The prefix parameters to the directive.
- *
- * @param mods
- * The modifiers to the directive.
- */
- public Decree(String name, CLParameters params, CLModifiers mods) {
- this.name = name;
-
- this.parameters = params;
-
- this.modifiers = mods;
-
- this.isLiteral = false;
- }
-
- /**
- * Create a new directive that may be a user function.
- *
- * @param name
- * The name of the directive. Whether or not it is an actual
- * directive will be auto-determined (if it starts with a ~ and is
- * not a user function, it's a directive.)
- *
- * @param isUser
- * Is this directive a user function?
- *
- * @param params
- * The prefix parameters to the directive.
- *
- * @param mods
- * The modifiers to the directive.
- */
- public Decree(String name, boolean isUser, CLParameters params, CLModifiers mods) {
- this.name = name;
-
- this.parameters = params;
-
- this.modifiers = mods;
-
- this.isUserCall = isUser;
-
- this.isLiteral = isUser;
- }
-
- /**
- * Check if this decree is a non-literal, with a particular name.
- *
- * @param nam
- * The name to see if we have.
- *
- * @return Whether or not the provided name equals our name.
- */
- public boolean isNamed(String nam) {
- // Literals don't have a meaningful name
- if (isLiteral)
- return false;
-
- return name.equals(nam);
- }
-
- @Override
- public String toString() {
- return String.format(
- "Decree [name='%s', isLiteral=%s, isUserCall=%s, parameters=%s, modifiers='%s']",
- name, isLiteral, isUserCall, parameters, modifiers);
- }
+public interface Decree {
+ // Marker interface, for now
}
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 736e15a..c1c5c7b 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/GroupDecree.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/GroupDecree.java
@@ -13,16 +13,16 @@ import bjc.utils.ioutils.ReportWriter;
*
* @author Ben Culkin
*/
-public class GroupDecree implements Iterable<ClauseDecree> {
+public class GroupDecree implements Iterable<ClauseDecree>, Decree {
/**
* The decree that opened this group.
*/
- public Decree opening;
+ public SimpleDecree opening;
/**
* The decree that closed this group.
*/
- public Decree closing;
+ public SimpleDecree closing;
/**
* The clauses that make up the body of this group.
@@ -45,9 +45,7 @@ public class GroupDecree implements Iterable<ClauseDecree> {
public GroupDecree(ClauseDecree... children) {
this();
- for (ClauseDecree child : children) {
- body.add(child);
- }
+ for (ClauseDecree child : children) body.add(child);
}
/**
@@ -62,7 +60,7 @@ public class GroupDecree implements Iterable<ClauseDecree> {
* @param children
* The decree making up the body of the group.
*/
- public GroupDecree(Decree opening, Decree closing, ClauseDecree... children) {
+ public GroupDecree(SimpleDecree opening, SimpleDecree closing, ClauseDecree... children) {
this(children);
this.opening = opening;
@@ -105,33 +103,32 @@ public class GroupDecree implements Iterable<ClauseDecree> {
*
* @return The decrees that make up the body of the first clause.
*/
- public List<Decree> unwrap() {
+ public List<SimpleDecree> unwrap() {
return body.get(0).body;
}
@Override
public String toString() {
- try (ReportWriter rw = new ReportWriter()) {
- String open = "<null>";
+ try (ReportWriter writer = new ReportWriter()) {
+ String open = "<null>";
String close = "<null>";
- if (opening != null)
- open = opening.toString();
- if (closing != null)
- close = closing.toString();
-
- rw.write("GroupDecree (opening " + open + ") (closing " + close + ")");
- rw.indent();
- rw.write("\n");
+ if (opening != null) open = opening.toString();
+ if (closing != null) close = closing.toString();
+ writer.writef("GroupDecree (opening %s) (closing %s)\n", open, close);
+ writer.indent();
+
int idx = 0;
for (ClauseDecree clause : body) {
- rw.write("Clause " + idx++ + ": " + clause.toString() + "\n");
+ writer.writef("Clause %d:", idx++);
+
+ clause.toReportWriter(writer);
}
- rw.dedent();
+ writer.dedent();
- return rw.toString();
+ return writer.toString();
} catch (IOException ioex) {
return "<IOEXCEPTION>";
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/SimpleDecree.java b/clformat/src/main/java/bjc/utils/ioutils/format/SimpleDecree.java
new file mode 100644
index 0000000..a7db42f
--- /dev/null
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/SimpleDecree.java
@@ -0,0 +1,129 @@
+package bjc.utils.ioutils.format;
+
+/**
+ * A decree is the building blocks of what we need to pick and call a directive.
+ *
+ * Namely, it is the name of the directive, any modifiers attached to the
+ * directive, and any prefix parameters that are also attached to the directive.
+ *
+ * @author Ben Culkin.
+ */
+public class SimpleDecree implements Decree {
+ /**
+ * The name of the directive.
+ */
+ public String name;
+
+ /**
+ * Is this directive an actual directive, or just a literal string?
+ */
+ public boolean isLiteral;
+
+ /**
+ * Is this directive a user function call?
+ */
+ public boolean isUserCall;
+
+ /**
+ * The prefix parameters for this directive.
+ */
+ public CLParameters parameters;
+
+ /**
+ * The modifiers for this directive.
+ */
+ public CLModifiers modifiers;
+
+ /**
+ * Create a new blank decree.
+ */
+ public SimpleDecree() {
+
+ }
+
+ /**
+ * Create a new literal text directive.
+ *
+ * @param txt
+ * The text of the directive.
+ */
+ public SimpleDecree(String txt) {
+ this.name = txt;
+
+ this.isLiteral = true;
+ }
+
+ /**
+ * Create a new directive.
+ *
+ * @param name
+ * The name of the directive. Whether or not it is an actual
+ * directive will be auto-determined (if it starts with a ~, it's
+ * a directive.)
+ *
+ * @param params
+ * The prefix parameters to the directive.
+ *
+ * @param mods
+ * The modifiers to the directive.
+ */
+ public SimpleDecree(String name, CLParameters params, CLModifiers mods) {
+ this.name = name;
+
+ this.parameters = params;
+
+ this.modifiers = mods;
+
+ this.isLiteral = false;
+ }
+
+ /**
+ * Create a new directive that may be a user function.
+ *
+ * @param name
+ * The name of the directive. Whether or not it is an actual
+ * directive will be auto-determined (if it starts with a ~ and is
+ * not a user function, it's a directive.)
+ *
+ * @param isUser
+ * Is this directive a user function?
+ *
+ * @param params
+ * The prefix parameters to the directive.
+ *
+ * @param mods
+ * The modifiers to the directive.
+ */
+ public SimpleDecree(String name, boolean isUser, CLParameters params, CLModifiers mods) {
+ this.name = name;
+
+ this.parameters = params;
+
+ this.modifiers = mods;
+
+ this.isUserCall = isUser;
+
+ this.isLiteral = isUser;
+ }
+
+ /**
+ * Check if this decree is a non-literal, with a particular name.
+ *
+ * @param nam
+ * The name to see if we have.
+ *
+ * @return Whether or not the provided name equals our name.
+ */
+ public boolean isNamed(String nam) {
+ // Literals don't have a meaningful name
+ if (isLiteral) return false;
+ else return name.equals(nam);
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "Decree [name='%s', isLiteral=%s, isUserCall=%s, parameters=%s, modifiers='%s']",
+ name, isLiteral, isUserCall, parameters, modifiers);
+ }
+}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
index 4fec0e0..0589992 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
@@ -79,44 +79,47 @@ class AestheticEdict implements Edict {
// Check that we have an item
CLFormatter.checkItem(itemTape.item(), 'A');
- String tmp = itemTape.item().toString();
+ String itemString = itemTape.item().toString();
StringBuilder work = new StringBuilder();
- char padchar = padcharPar.asChar(itemTape, "padding character", "A", ' ');
+ char padchar = padcharPar.asChar(itemTape,
+ "padding character", "A", ' ');
- int mincol = mincolPar.asInt(itemTape, "minimum column count", "A", 0);
- int colinc = colincPar.asInt(itemTape, "padding increment", "A", 1);
- int minpad = minpadPar.asInt(itemTape, "minumum amount of padding", "A", 0);
+ int mincol = mincolPar.asInt(itemTape,
+ "minimum column count", "A", 0);
+ int colinc = colincPar.asInt(itemTape,
+ "padding increment", "A", 1);
+ int minpad = minpadPar.asInt(itemTape,
+ "minumum amount of padding", "A", 0);
- if (padBefore) {
- for (int i = 0; i < minpad; i++) {
- work.append(padchar);
- }
+ work.append(itemString);
- for (int i = work.length() + tmp.length(); i < mincol; i++) {
- for (int k = 0; k < colinc; k++) {
- work.append(padchar);
- }
- }
- }
+ String padding = createPadding(work, padchar, mincol, colinc, minpad);
+ if (padBefore) work.insert(0, padding);
+ else work.append(padding);
- work.append(tmp);
+ formCTX.writer.write(work.toString());
- if (!padBefore) {
- for (int i = 0; i < minpad; i++) {
- work.append(padchar);
- }
+ itemTape.right();
+ }
- for (int i = work.length(); i < mincol; i++) {
- for (int k = 0; k < colinc; k++) {
- work.append(padchar);
- }
+ private String createPadding(
+ StringBuilder work,
+ char padchar,
+ int mincol,
+ int colinc,
+ int minpad)
+ {
+ StringBuilder padding = new StringBuilder();
+ for (int i = 0; i < minpad; i++) padding.append(padchar);
+
+ for (int i = work.length(); i < mincol; i++) {
+ for (int k = 0; k < colinc; k++) {
+ padding.append(padchar);
}
}
- formCTX.writer.write(work.toString());
-
- itemTape.right();
+ return padding.toString();
}
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java
index 7e1ca87..2e45600 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java
@@ -75,10 +75,11 @@ class CaseEdict implements Edict {
while (mat.find()) {
mat.appendReplacement(sb, "");
- String word = mat.group(1);
- String ward = word.substring(0, 1).toUpperCase() + word.substring(1);
+ String word = mat.group(1);
+ String upperWord = word.substring(0, 1).toUpperCase()
+ + word.substring(1);
- sb.append(ward);
+ sb.append(upperWord);
sb.append(mat.group(2));
}
@@ -100,7 +101,8 @@ class CaseEdict implements Edict {
if (doCap) {
doCap = false;
- word = word.substring(0, 1).toUpperCase() + word.substring(1);
+ word = word.substring(0, 1).toUpperCase()
+ + word.substring(1);
}
sb.append(word);
@@ -116,8 +118,10 @@ class CaseEdict implements Edict {
strang = strang.toLowerCase();
break;
default:
- throw new IllegalArgumentException("INTERNAL ERROR: CaseEdict mode "
- + caseMode + " is not supported. This is a bug.");
+ String msg = String.format(
+ "INTERNAL ERROR: CaseEdict mode %s is not supported. This is a bug.",
+ caseMode);
+ throw new IllegalArgumentException(msg);
}
formCTX.writer.write(strang);
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java
index ca0432c..6fd2309 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java
@@ -30,24 +30,21 @@ class CharacterEdict implements Edict {
@Override
public void format(FormatContext formCTX) throws IOException {
- Object o = formCTX.items.item();
+ Object item = formCTX.items.item();
- CLFormatter.checkItem(o, 'C');
+ CLFormatter.checkItem(item, 'C');
- if (!(o instanceof Character)) {
- throw new IllegalFormatConversionException('C', o.getClass());
+ if (!(item instanceof Character)) {
+ throw new IllegalFormatConversionException('C', item.getClass());
}
- char ch = (Character) o;
+ char ch = (Character) item;
int codepoint = ch;
ReportWriter rw = formCTX.writer;
- if (printCharName) {
- rw.write(Character.getName(codepoint));
- } else {
- rw.write(ch);
- }
+ if (printCharName) rw.write(Character.getName(codepoint));
+ else rw.write(ch);
formCTX.items.right();
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/CompileContext.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/CompileContext.java
index 3c5f692..77c8402 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/CompileContext.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/CompileContext.java
@@ -21,7 +21,7 @@ public class CompileContext {
/**
* The decree that is currently being parsed.
*/
- public Decree decr;
+ public SimpleDecree decr;
/**
* Create a new compilation context.
@@ -35,7 +35,7 @@ public class CompileContext {
* @param dcr
* The decree currently being compiled.
*/
- public CompileContext(CLTokenizer dirs, CLFormatter fmt, Decree dcr) {
+ public CompileContext(CLTokenizer dirs, CLFormatter fmt, SimpleDecree dcr) {
directives = dirs;
formatter = fmt;
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 491d629..c7b2999 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
@@ -18,25 +18,24 @@ import bjc.utils.ioutils.format.*;
public class ConditionalDirective implements Directive {
@Override
public Edict compile(CompileContext compCTX) {
- CLModifiers mods = compCTX.decr.modifiers;
+ CLModifiers mods = compCTX.decr.modifiers;
CLParameters params = compCTX.decr.parameters;
+ // :ConfigDirectives
GroupDecree clauses = compCTX.directives.nextGroup(compCTX.decr, "]", ";");
ClauseDecree defClause = null;
- boolean isDefault = false;
+ boolean isDefault = false;
for (ClauseDecree clause : clauses) {
- if (isDefault)
- defClause = clause;
+ if (isDefault) defClause = clause;
if (clause.terminator != null && clause.terminator.modifiers.colonMod) {
isDefault = true;
}
}
- if (mods.starMod && clauses.size() > 0)
- defClause = clauses.clause();
+ if (mods.starMod && clauses.size() > 0)defClause = clauses.clause();
CLValue index = null;
@@ -56,8 +55,8 @@ 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);
}
}
@@ -87,7 +86,9 @@ class ConditionalEdict implements Edict {
this.clauses = new ArrayList<>();
for (ClauseDecree clause : clauses) {
- this.clauses.add(new CLString(fmt.compile(clause)));
+ List<Edict> compiled = fmt.compile(clause);
+
+ this.clauses.add(new CLString(compiled));
}
this.defClause = new CLString(fmt.compile(defClause));
@@ -101,47 +102,47 @@ class ConditionalEdict implements Edict {
try {
switch (condMode) {
case FIRST_SECOND: {
- Object o = items.item();
+ Object item = items.item();
items.right();
- boolean res = false;
- if (o == null) {
+ boolean conditionResult = false;
+ if (item == null) {
// throw new IllegalArgumentException("No parameter provided for [
// directive.");
- } else if (!(o instanceof Boolean)) {
- throw new IllegalFormatConversionException('[', o.getClass());
+ } else if (!(item instanceof Boolean)) {
+ throw new IllegalFormatConversionException('[', item.getClass());
} else {
- res = (Boolean) o;
+ conditionResult = (Boolean) item;
}
- CLString frmt;
- if (res) {
- frmt = clauses.get(1);
+ CLString pickedFormat;
+ if (conditionResult) {
+ pickedFormat = clauses.get(1);
} else {
- frmt = clauses.get(0);
+ pickedFormat = clauses.get(0);
}
- frmt.format(formCTX);
+ pickedFormat.format(formCTX);
}
break;
case OUTPUT_TRUE: {
- boolean res = false;
- Object o = items.item();
+ boolean conditionResult = false;
+ Object item = items.item();
- if (o == null) {
+ if (item == null) {
// throw new IllegalArgumentException("No parameter provided for [
// directive.");
- } else if (o instanceof Integer) {
- if ((Integer) o != 0) {
- res = true;
+ } else if (item instanceof Integer) {
+ if ((Integer) item != 0) {
+ conditionResult = true;
}
- } else if (o instanceof Boolean) {
- res = (Boolean) o;
+ } else if (item instanceof Boolean) {
+ conditionResult = (Boolean) item;
} else {
- throw new IllegalFormatConversionException('[', o.getClass());
+ throw new IllegalFormatConversionException('[', item.getClass());
}
- if (res) {
+ if (conditionResult) {
clauses.get(0).format(formCTX);
} else {
items.right();
@@ -149,34 +150,32 @@ class ConditionalEdict implements Edict {
}
break;
case INDEX_CLAUSE: {
- int res;
+ int clauseIndex;
if (index != null) {
- res = index.asInt(items, "conditional choice", "[", 0);
+ clauseIndex = index.asInt(items, "conditional choice", "[", 0);
} else {
- Object o = items.item();
+ Object item = items.item();
- if (o == null) {
+ if (item == null) {
throw new IllegalArgumentException(
"No parameter provided for [ directive.");
- } else if (!(o instanceof Number)) {
- throw new IllegalFormatConversionException('[', o.getClass());
+ } else if (!(item instanceof Number)) {
+ throw new IllegalFormatConversionException('[', item.getClass());
}
- res = ((Number) o).intValue();
+ clauseIndex = ((Number) item).intValue();
items.right();
}
if (decrementIndex)
- res -= 1;
+ clauseIndex -= 1;
- if (clauses.size() == 0 || res < 0 || res >= clauses.size()) {
- if (defClause != null) {
- defClause.format(formCTX.writer, items);
- }
+ if (clauses.size() == 0 || clauseIndex < 0 || clauseIndex >= clauses.size()) {
+ if (defClause != null) defClause.format(formCTX.writer, items);
} else {
- CLString frmt = clauses.get(res);
+ CLString frmt = clauses.get(clauseIndex);
frmt.format(formCTX.writer, items);
}
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..6447eef
--- /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;
+ @SuppressWarnings("unused")
+ 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 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());
+ formCTX.writer.write(numForm.format(itemTape.item()));
+ itemTape.right();
+ }
+}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
index 343a54d..3610bda 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
@@ -14,7 +14,7 @@ public class EscapeDirective implements Directive {
@Override
public Edict compile(CompileContext compCTX) {
CLParameters params = compCTX.decr.parameters;
- CLModifiers mods = compCTX.decr.modifiers;
+ CLModifiers mods = compCTX.decr.modifiers;
CLValue param1 = CLValue.nil();
CLValue param2 = CLValue.nil();
@@ -27,28 +27,31 @@ public class EscapeDirective implements Directive {
break;
case 1:
mode = EscapeEdict.Mode.COUNT;
+
params.mapIndices("count");
param1 = params.resolveKey("count");
break;
case 2:
+ mode = EscapeEdict.Mode.EQUALITY;
+
params.mapIndices("lhand", "rhand");
param1 = params.resolveKey("lhand");
param2 = params.resolveKey("rhand");
- mode = EscapeEdict.Mode.EQUALITY;
break;
case 3:
+ mode = EscapeEdict.Mode.RANGE;
+
params.mapIndices("lower", "ival", "upper");
param1 = params.resolveKey("lower");
param2 = params.resolveKey("ival");
param3 = params.resolveKey("upper");
- mode = EscapeEdict.Mode.RANGE;
break;
default:
throw new IllegalArgumentException("Too many parameters to ^ directive");
}
- return new EscapeEdict(mods.atMod, mode, mods.colonMod, param1, param2, param3,
- mods.dollarMod);
+ return new EscapeEdict(mods.atMod, mode, mods.colonMod,
+ param1, param2, param3, mods.dollarMod);
}
}
@@ -88,8 +91,7 @@ class EscapeEdict implements Edict {
Tape<Object> items = formCTX.items;
- if (advance)
- items.right();
+ if (advance) items.right();
switch (mode) {
case END:
@@ -102,15 +104,15 @@ class EscapeEdict implements Edict {
}
break;
case EQUALITY: {
- int left = param1.asInt(items, "left-hand condition", "^", 0);
+ int left = param1.asInt(items, "left-hand condition", "^", 0);
int right = param2.asInt(items, "right-hand condition", "^", 0);
shouldExit = (left == right);
}
break;
case RANGE: {
- int low = param1.asInt(items, "lower-bound condition", "^", 0);
- int mid = param2.asInt(items, "interval condition", "^", 0);
+ int low = param1.asInt(items, "lower-bound condition", "^", 0);
+ int mid = param2.asInt(items, "interval condition", "^", 0);
int high = param3.asInt(items, "upper-bound condition", "^", 0);
shouldExit = (low <= mid) && (mid <= high);
@@ -121,15 +123,9 @@ class EscapeEdict implements Edict {
"Escape condition mode " + mode + " isn't supported");
}
- if (advance)
- items.left();
-
- if (isNegated) {
- shouldExit = !shouldExit;
- }
+ if (advance) items.left();
+ if (isNegated) shouldExit = !shouldExit;
- if (shouldExit) {
- throw new DirectiveEscape(terminateIteration);
- }
+ if (shouldExit) throw new DirectiveEscape(terminateIteration);
}
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/FormatParameters.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/FormatParameters.java
index 3ffa4ed..e2884d3 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/FormatParameters.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/FormatParameters.java
@@ -18,7 +18,7 @@ public class FormatParameters {
/**
* The {@link ReportWriter} used for output.
*/
- public ReportWriter rw;
+ public ReportWriter writer;
/**
* The current format parameter.
@@ -28,7 +28,7 @@ public class FormatParameters {
/**
* The current decree.
*/
- public Decree decr;
+ public SimpleDecree decr;
/**
* The current format parameters.
@@ -43,12 +43,12 @@ public class FormatParameters {
/**
* The formatter we are going from.
*/
- public CLFormatter fmt;
+ public CLFormatter formatter;
/**
* Create a new set of format parameters.
*
- * @param rw
+ * @param writer
* The writer we are sending output to.
*
* @param item
@@ -63,12 +63,12 @@ public class FormatParameters {
* @param dirIter
* The set of format decrees.
*
- * @param fmt
+ * @param formatter
* The formatter we are using
*/
- public FormatParameters(ReportWriter rw, Object item, Decree decr,
- Tape<Object> tParams, CLTokenizer dirIter, CLFormatter fmt) {
- this.rw = rw;
+ public FormatParameters(ReportWriter writer, Object item, SimpleDecree decr,
+ Tape<Object> tParams, CLTokenizer dirIter, CLFormatter formatter) {
+ this.writer = writer;
this.item = item;
@@ -78,7 +78,7 @@ public class FormatParameters {
this.dirIter = dirIter;
- this.fmt = fmt;
+ this.formatter = formatter;
}
/**
@@ -105,7 +105,7 @@ public class FormatParameters {
* @return The compilation context from these parameters.
*/
public CompileContext toCompileCTX() {
- return new CompileContext(dirIter, fmt, decr);
+ return new CompileContext(dirIter, formatter, decr);
}
/**
@@ -114,6 +114,6 @@ public class FormatParameters {
* @return The format context from these parameters.
*/
public FormatContext toFormatCTX() {
- return new FormatContext(rw, tParams);
+ return new FormatContext(writer, tParams);
}
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java
index 7402c98..dedbbac 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java
@@ -38,11 +38,8 @@ class FreshlineEdict implements Edict {
public void format(FormatContext formCTX) throws IOException {
int nTimes = times.asInt(formCTX.items, "occurance count", "&", 1);
- if (formCTX.writer.isLastCharNL())
- nTimes -= 1;
+ if (formCTX.writer.isLastCharNL()) nTimes -= 1;
- for (int i = 0; i < nTimes; i++) {
- formCTX.writer.write("\n");
- }
+ for (int i = 0; i < nTimes; i++) formCTX.writer.write("\n");
}
}
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 f12880e..f2fca71 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
@@ -57,7 +57,7 @@ public abstract class GeneralNumberDirective implements Directive {
*/
protected NumberParams getParams(CompileContext compCTX, int argidx) {
CLParameters params = compCTX.decr.parameters;
- CLModifiers mods = compCTX.decr.modifiers;
+ CLModifiers mods = compCTX.decr.modifiers;
NumberParams np = new NumberParams();
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/IndentDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/IndentDirective.java
index a19866f..4ccf627 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/IndentDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/IndentDirective.java
@@ -14,9 +14,7 @@ public class IndentDirective implements Directive {
CLParameters params = compCTX.decr.parameters;
CLModifiers mods = compCTX.decr.modifiers;
- if (mods.dollarMod) {
- return new IndentConfigureEdict();
- }
+ if (mods.dollarMod) return new IndentConfigureEdict();
CLValue indentCount = CLValue.nil();
if (params.length() >= 1) {
@@ -52,11 +50,8 @@ class IndentEdict implements Edict {
}
if (isRelative) {
- if (dedent) {
- formCTX.writer.dedent(numIndents);
- } else {
- formCTX.writer.indent(numIndents);
- }
+ if (dedent) formCTX.writer.dedent(numIndents);
+ else formCTX.writer.indent(numIndents);
} else {
if (dedent) {
throw new IllegalArgumentException("Cannot have negative indent level");
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/InflectDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/InflectDirective.java
index 8ed39fb..937bd9d 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/InflectDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/InflectDirective.java
@@ -15,13 +15,13 @@ import bjc.utils.ioutils.format.*;
public class InflectDirective implements Directive {
@Override
public Edict compile(CompileContext compCTX) {
- List<Decree> body = new ArrayList<>();
+ List<SimpleDecree> body = new ArrayList<>();
int nestLevel = 1;
- Iterator<Decree> dirIter = compCTX.directives;
+ Iterator<SimpleDecree> dirIter = compCTX.directives;
while (dirIter.hasNext()) {
- Decree decr = dirIter.next();
+ SimpleDecree decr = dirIter.next();
if (decr.isLiteral) {
body.add(decr);
@@ -30,11 +30,11 @@ public class InflectDirective implements Directive {
String dirName = decr.name;
+ // @FIXME Nov 13th 2020 Ben Culkin :GroupDecree
+ // Would it be appropriate to convert this to use GroupDecree?
if (dirName != null) {
if (dirName.equals("`[")) {
- if (nestLevel > 0) {
- body.add(decr);
- }
+ if (nestLevel > 0) body.add(decr);
nestLevel += 1;
} else if (Directive.isOpening(dirName)) {
@@ -44,9 +44,8 @@ public class InflectDirective implements Directive {
} else if (dirName.equals("`]")) {
nestLevel = Math.max(0, nestLevel - 1);
- /* End the iteration. */
- if (nestLevel == 0)
- break;
+ /* End the iteration if this was the final `]. */
+ if (nestLevel == 0) break;
} else if (Directive.isClosing(dirName)) {
nestLevel = Math.max(0, nestLevel - 1);
} else {
@@ -63,17 +62,17 @@ public class InflectDirective implements Directive {
class InflectEdict implements Edict {
private CLString body;
- public InflectEdict(List<Decree> body, CLFormatter fmt) {
+ public InflectEdict(List<SimpleDecree> body, CLFormatter fmt) {
this.body = new CLString(fmt.compile(body));
}
@Override
public void format(FormatContext formCTX) throws IOException {
- ReportWriter nrw = formCTX.writer.duplicate(new StringWriter());
+ ReportWriter newWriter = formCTX.writer.duplicate(new StringWriter());
- body.format(nrw, formCTX.items);
+ body.format(newWriter, formCTX.items);
- String strang = nrw.toString();
+ String strang = newWriter.toString();
strang = InflectionML.inflect(strang);
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
index b8cdf36..34f815d 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
@@ -16,30 +16,26 @@ public class IterationDirective implements Directive {
public Edict compile(CompileContext compCTX) {
IterationEdict.Mode mode;
- List<Decree> body = new ArrayList<>();
+ List<SimpleDecree> body = new ArrayList<>();
- Iterator<Decree> dirIter = compCTX.directives;
+ Iterator<SimpleDecree> dirIter = compCTX.directives;
+ // :GroupDecree
while (dirIter.hasNext()) {
- Decree decr = dirIter.next();
+ SimpleDecree decr = dirIter.next();
if (decr.isLiteral) {
body.add(decr);
- continue;
- }
-
- String dirName = decr.name;
-
- if (dirName != null) {
- if (dirName.equals("}")) {
- break;
- } else {
- /* Not a special directive. */
- body.add(decr);
+ } else {
+ String dirName = decr.name;
+
+ if (dirName != null) {
+ if (dirName.equals("}")) break;
+ else body.add(decr);
}
}
}
CLParameters params = compCTX.decr.parameters;
- CLModifiers mods = compCTX.decr.modifiers;
+ CLModifiers mods = compCTX.decr.modifiers;
CLValue maxItr = CLValue.nil();
if (params.length() > 0) {
@@ -77,7 +73,7 @@ class IterationEdict implements Edict {
private CLValue maxItrVal;
- public IterationEdict(Mode mode, List<Decree> body, CLFormatter fmt, CLValue maxItr) {
+ public IterationEdict(Mode mode, List<SimpleDecree> body, CLFormatter fmt, CLValue maxItr) {
this.mode = mode;
this.body = new CLString(fmt.compile(body));
@@ -96,7 +92,7 @@ class IterationEdict implements Edict {
Object iter = formCTX.items.item();
boolean usingString = false;
- String strang = null;
+ String currBody = null;
if (body.isEmpty()) {
/* Grab an argument. */
@@ -105,7 +101,7 @@ class IterationEdict implements Edict {
}
usingString = true;
- strang = (String) iter;
+ currBody = (String) iter;
if (!formCTX.items.right()) {
throw new IllegalArgumentException(
@@ -119,8 +115,7 @@ class IterationEdict implements Edict {
case ALL_SUBLISTS:
try {
do {
- if (numIterations > maxIterations)
- break;
+ if (numIterations > maxIterations) break;
numIterations += 1;
if (!(iter instanceof Iterable<?>)) {
@@ -129,8 +124,8 @@ class IterationEdict implements Edict {
}
@SuppressWarnings("unchecked")
- Iterable<Object> nitr = (Iterable<Object>) iter;
- Tape<Object> nParams = new SingleTape<>(nitr);
+ Iterable<Object> nitr = (Iterable<Object>) iter;
+ Tape<Object> nParams = new SingleTape<>(nitr);
try {
if (usingString) {
@@ -140,15 +135,13 @@ class IterationEdict implements Edict {
// CLString and then caching those compiled string. However,
// we aren't
// doing that now. -- ben, 12/17/19
- fmt.doFormatString(strang, formCTX.writer, nParams, false);
+ fmt.doFormatString(currBody, formCTX.writer, nParams, false);
} else {
body.format(formCTX.writer, nParams);
}
} catch (DirectiveEscape eex) {
if (eex.endIteration) {
- if (formCTX.items.atEnd()) {
- throw eex;
- }
+ if (formCTX.items.atEnd()) throw eex;
}
}
@@ -162,14 +155,13 @@ class IterationEdict implements Edict {
case ALL:
try {
while (!formCTX.items.atEnd()) {
- if (numIterations > maxIterations)
- break;
+ if (numIterations > maxIterations) break;
numIterations += 1;
if (usingString) {
// :DynamicFormatString
- fmt.doFormatString(strang, formCTX.writer, formCTX.items, false);
+ fmt.doFormatString(currBody, formCTX.writer, formCTX.items, false);
} else {
body.format(formCTX);
}
@@ -192,8 +184,7 @@ class IterationEdict implements Edict {
while (itr.hasNext()) {
Object obj = itr.next();
- if (numIterations > maxIterations)
- break;
+ if (numIterations > maxIterations) break;
numIterations += 1;
if (!(obj instanceof Iterable<?>)) {
@@ -208,13 +199,12 @@ class IterationEdict implements Edict {
try {
if (usingString) {
// :DynamicString
- fmt.doFormatString(strang, formCTX.writer, nParams, false);
+ fmt.doFormatString(currBody, formCTX.writer, nParams, false);
} else {
body.format(formCTX.writer, nParams);
}
} catch (DirectiveEscape eex) {
- if (eex.endIteration && !itr.hasNext())
- throw eex;
+ if (eex.endIteration && !itr.hasNext()) throw eex;
}
}
} catch (DirectiveEscape eex) {
@@ -232,13 +222,12 @@ class IterationEdict implements Edict {
Tape<Object> nParams = new SingleTape<>(itr);
while (!nParams.atEnd()) {
- if (numIterations > maxIterations)
- break;
+ if (numIterations > maxIterations) break;
numIterations += 1;
if (usingString) {
// :DynamicString
- fmt.doFormatString(strang, formCTX.writer, nParams, false);
+ fmt.doFormatString(currBody, formCTX.writer, nParams, false);
} else {
body.format(formCTX.writer, nParams);
}
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java
index c63bf4e..3e4a5ef 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java
@@ -63,8 +63,6 @@ class LiteralEdict implements Edict {
num = nTimes.asInt(formCTX.items, "occurance count", "literal", 1);
}
- for (int i = 0; i < num; i++) {
- formCTX.writer.write(lit);
- }
+ for (int i = 0; i < num; i++) formCTX.writer.write(lit);
}
}
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 c7d4ab6..de1bb28 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
@@ -71,9 +71,8 @@ class NumberEdict implements Edict {
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, ' ');
+ 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;
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 e3ccfb4..24af908 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
@@ -27,13 +27,9 @@ public class RadixDirective extends GeneralNumberDirective {
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;
- }
+ 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;
@@ -96,11 +92,9 @@ class RadixEdict implements Edict {
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", ' ');
+ 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;
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java
index 41c7adb..c60d0bb 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java
@@ -48,9 +48,7 @@ class RecursiveEdict implements Edict {
fmt.doFormatString(bod, formCTX.writer, formCTX.items, true);
} catch (DirectiveEscape eex) {
- if (eex.endIteration) {
- throw new UnexpectedColonEscape();
- }
+ if (eex.endIteration) throw new UnexpectedColonEscape();
}
} else {
if (formCTX.items.atEnd()) {
@@ -58,11 +56,11 @@ class RecursiveEdict implements Edict {
"? directive requires two format parameters");
}
- Object o = formCTX.items.item();
+ Object item = formCTX.items.item();
formCTX.items.right();
- if (!(o instanceof Iterable<?>)) {
- throw new MismatchedFormatArgType("?", Iterable.class, o.getClass());
+ if (!(item instanceof Iterable<?>)) {
+ throw new MismatchedFormatArgType("?", Iterable.class, item.getClass());
}
if (!(body instanceof String)) {
@@ -70,7 +68,7 @@ class RecursiveEdict implements Edict {
}
@SuppressWarnings("unchecked")
- Iterable<Object> itb = (Iterable<Object>) o;
+ Iterable<Object> itb = (Iterable<Object>) item;
Tape<Object> newParams = new SingleTape<>(itb);
try {
diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java b/clformat/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java
index 91b40c3..a9814ba 100644
--- a/clformat/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java
+++ b/clformat/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java
@@ -68,7 +68,7 @@ class TabulateEdict implements Edict {
@Override
public void format(FormatContext formCTX) throws IOException {
- ReportWriter rw = formCTX.writer;
+ ReportWriter writer = formCTX.writer;
Tape<Object> itms = formCTX.items;
@@ -76,24 +76,19 @@ class TabulateEdict implements Edict {
int currCol;
- if (fromIndent) {
- currCol = rw.getIndentPos();
- } else {
- currCol = rw.getLinePos();
- }
+ if (fromIndent) currCol = writer.getIndentPos();
+ else currCol = writer.getLinePos();
if (isRelative) {
int colinc = colincVal.asInt(itms, "column increment", "T", 1);
int colrel = colidVal.asInt(itms, "relative column number", "T", 1);
- for (int i = 0; i < colrel; i++) {
- rw.write(padchar);
- }
+ for (int i = 0; i < colrel; i++) writer.write(padchar);
int nSpaces = 0;
while ((currCol + nSpaces) % colinc != 0) {
- rw.write(padchar);
+ writer.write(padchar);
nSpaces++;
}
@@ -102,17 +97,14 @@ class TabulateEdict implements Edict {
int colnum = colidVal.asInt(itms, "column number", "T", 1);
if (currCol < colnum) {
- for (int i = currCol; i < colnum; i++) {
- rw.write(padchar);
- }
+ for (int i = currCol; i < colnum; i++) writer.write(padchar);
} else {
- if (colinc == 0)
- return;
+ if (colinc == 0) return;
int k = 0;
while (colnum > (currCol + (k * colinc))) {
- rw.write(padchar);
+ writer.write(padchar);
k++;
}
diff --git a/clformat/src/test/java/bjc/utils/test/ioutils/CLFormatterTest.java b/clformat/src/test/java/bjc/utils/test/ioutils/CLFormatterTest.java
index 8cd3e61..629e802 100644
--- a/clformat/src/test/java/bjc/utils/test/ioutils/CLFormatterTest.java
+++ b/clformat/src/test/java/bjc/utils/test/ioutils/CLFormatterTest.java
@@ -125,7 +125,8 @@ public class CLFormatterTest {
assertFormat("foo", "~A", "foo");
assertFormat("foobar ", "~7A", "foobar");
assertFormat(" foobar", "~7@A", "foobar");
- assertFormat(" foobar", "~#mincol;8,#colinc;2,#minpad;1,#padchar;' @A",
+ assertFormat(" foobar",
+ "~#mincol;8,#colinc;2,#minpad;1,#padchar;' @A",
"foobar");
}
@@ -138,11 +139,22 @@ public class CLFormatterTest {
}
@Test
+ public void testFloatPrinting() {
+ assertFormat("1", "~`D", 1);
+ assertFormat("1.1", "~`D", 1.1);
+ }
+
+ @Test
public void testRandomCases() {
// Random test cases
- assertEquals("3 dogs are here", format("~D dog~:[s are~; is~] here", 3, 3 == 1));
+ assertEquals("3 dogs are here",
+ format("~D dog~:[s are~; is~] here", 3, 3 == 1));
}
+ /*private void assertFormat(String msg, String res, String fomt, Object... params) {
+ assertEquals(msg, res, format(fomt, params));
+ }*/
+
private void assertFormat(String res, String fomt, Object... params) {
assertEquals(res, format(fomt, params));
}
diff --git a/clformat/src/test/java/bjc/utils/test/ioutils/CLTokenizerTest.java b/clformat/src/test/java/bjc/utils/test/ioutils/CLTokenizerTest.java
index 429c089..20d64b0 100644
--- a/clformat/src/test/java/bjc/utils/test/ioutils/CLTokenizerTest.java
+++ b/clformat/src/test/java/bjc/utils/test/ioutils/CLTokenizerTest.java
@@ -18,7 +18,7 @@ public class CLTokenizerTest {
CLTokenizer tokenzer = new CLTokenizer("");
assertTrue("Empty tokenizer has a decree", tokenzer.hasNext());
- Decree dec = tokenzer.next();
+ SimpleDecree dec = tokenzer.next();
assertFalse("Empty tokenizer has only one decree", tokenzer.hasNext());
assertTrue("Decree from empty tokenizer is a literal", dec.isLiteral);