From 946cab444bc301d8a7c756a1bab039558288de89 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Wed, 11 Oct 2017 13:41:07 -0300 Subject: Cleanup work --- base/src/main/java/bjc/utils/cli/CLICommander.java | 76 +++---- base/src/main/java/bjc/utils/cli/Command.java | 13 +- .../main/java/bjc/utils/cli/CommandHandler.java | 13 +- base/src/main/java/bjc/utils/cli/CommandHelp.java | 9 +- base/src/main/java/bjc/utils/cli/CommandMode.java | 47 +++-- .../main/java/bjc/utils/cli/DelegatingCommand.java | 17 +- .../main/java/bjc/utils/cli/GenericCommand.java | 23 +- .../java/bjc/utils/cli/GenericCommandMode.java | 233 +++++++++++---------- base/src/main/java/bjc/utils/cli/GenericHelp.java | 24 ++- base/src/main/java/bjc/utils/cli/NullHelp.java | 3 +- .../java/bjc/utils/cli/objects/BlockReaderCLI.java | 134 ++++++++---- .../main/java/bjc/utils/cli/objects/Command.java | 84 +++++++- .../main/java/bjc/utils/cli/objects/DefineCLI.java | 10 + .../bjc/utils/components/ComponentDescription.java | 59 +++--- .../components/ComponentDescriptionFileParser.java | 52 +++-- .../components/ComponentDescriptionState.java | 35 ++-- .../utils/components/FileComponentRepository.java | 107 +++++----- .../bjc/utils/components/IComponentRepository.java | 32 +-- .../bjc/utils/components/IDescribedComponent.java | 30 +-- .../main/java/bjc/utils/data/BooleanToggle.java | 5 +- .../main/java/bjc/utils/data/CircularIterator.java | 20 +- base/src/main/java/bjc/utils/data/Either.java | 70 ++++--- .../java/bjc/utils/data/GeneratingIterator.java | 22 +- base/src/main/java/bjc/utils/data/IHolder.java | 81 ++++--- base/src/main/java/bjc/utils/data/IPair.java | 146 ++++++++----- base/src/main/java/bjc/utils/data/ITree.java | 103 +++++---- base/src/main/java/bjc/utils/data/Identity.java | 28 ++- base/src/main/java/bjc/utils/data/Lazy.java | 34 +-- base/src/main/java/bjc/utils/data/LazyPair.java | 51 +++-- base/src/main/java/bjc/utils/data/ListHolder.java | 9 +- base/src/main/java/bjc/utils/data/Option.java | 8 +- base/src/main/java/bjc/utils/data/Pair.java | 25 ++- .../main/java/bjc/utils/data/SingleIterator.java | 7 +- .../main/java/bjc/utils/data/SingleSupplier.java | 21 +- base/src/main/java/bjc/utils/data/Toggle.java | 15 +- .../bjc/utils/data/TopDownTransformIterator.java | 4 +- .../bjc/utils/data/TopDownTransformResult.java | 26 +-- .../java/bjc/utils/data/TransformIterator.java | 12 +- base/src/main/java/bjc/utils/data/Tree.java | 63 ++++-- base/src/main/java/bjc/utils/data/ValueToggle.java | 22 +- .../java/bjc/utils/data/internals/BoundLazy.java | 61 +++--- .../bjc/utils/data/internals/BoundLazyPair.java | 75 ++++--- .../bjc/utils/data/internals/BoundListHolder.java | 19 +- .../utils/data/internals/HalfBoundLazyPair.java | 35 +++- .../java/bjc/utils/data/internals/WrappedLazy.java | 22 +- .../bjc/utils/data/internals/WrappedOption.java | 17 ++ .../src/main/java/bjc/utils/esodata/AbbrevMap.java | 80 +++---- .../src/main/java/bjc/utils/esodata/Directory.java | 54 +++-- .../main/java/bjc/utils/esodata/DoubleTape.java | 86 +------- .../main/java/bjc/utils/esodata/PushdownMap.java | 27 ++- .../main/java/bjc/utils/esodata/QueueStack.java | 11 +- .../java/bjc/utils/esodata/SimpleDirectory.java | 16 +- .../main/java/bjc/utils/esodata/SimpleStack.java | 9 +- .../main/java/bjc/utils/esodata/SingleTape.java | 93 ++------ .../java/bjc/utils/esodata/SpaghettiStack.java | 11 +- base/src/main/java/bjc/utils/esodata/Stack.java | 221 +++++++++---------- base/src/main/java/bjc/utils/esodata/Tape.java | 47 +++-- .../main/java/bjc/utils/esodata/TapeChanger.java | 108 ++-------- .../main/java/bjc/utils/esodata/TapeLibrary.java | 112 ++-------- .../java/bjc/utils/esodata/UnifiedDirectory.java | 14 +- base/src/main/java/bjc/utils/esodata/todos.txt | 6 + .../utils/exceptions/FileNotChosenException.java | 11 +- .../utils/exceptions/PragmaFormatException.java | 13 +- .../utils/exceptions/UnknownPragmaException.java | 9 +- .../main/java/bjc/utils/funcdata/ExtendedMap.java | 24 ++- .../java/bjc/utils/funcdata/FunctionalList.java | 91 ++++---- .../java/bjc/utils/funcdata/FunctionalMap.java | 18 +- .../bjc/utils/funcdata/bst/BinarySearchTree.java | 91 ++++---- .../utils/funcdata/bst/BinarySearchTreeLeaf.java | 14 +- .../utils/funcdata/bst/BinarySearchTreeNode.java | 36 ++-- .../utils/funcdata/bst/DirectedWalkFunction.java | 18 +- .../java/bjc/utils/funcdata/bst/ITreePart.java | 70 ++++--- .../funcdata/bst/TreeLinearizationMethod.java | 3 +- .../java/bjc/utils/funcdata/theory/Bifunctor.java | 98 ++++++--- .../java/bjc/utils/funcdata/theory/Functor.java | 28 ++- 75 files changed, 1805 insertions(+), 1616 deletions(-) create mode 100644 base/src/main/java/bjc/utils/esodata/todos.txt (limited to 'base/src/main/java/bjc') diff --git a/base/src/main/java/bjc/utils/cli/CLICommander.java b/base/src/main/java/bjc/utils/cli/CLICommander.java index cccb255..1504002 100644 --- a/base/src/main/java/bjc/utils/cli/CLICommander.java +++ b/base/src/main/java/bjc/utils/cli/CLICommander.java @@ -10,19 +10,14 @@ import java.util.Scanner; * Runs a CLI interface from the provided set of streams. * * @author ben - * */ public class CLICommander { - /* - * The streams used for input and normal/error output. - */ + /* The streams used for input and normal/error output. */ private final InputStream input; private final OutputStream output; private final OutputStream error; - /* - * The command mode to start execution in. - */ + /* The command mode to start execution in. */ private CommandMode initialMode; /** @@ -30,38 +25,35 @@ public class CLICommander { * * @param input * The stream to get user input from. + * * @param output * The stream to send normal output to. + * * @param error * The stream to send error output to. */ public CLICommander(final InputStream input, final OutputStream output, final OutputStream error) { - if (input == null) - throw new NullPointerException("Input stream must not be null"); - else if (output == null) - throw new NullPointerException("Output stream must not be null"); - else if (error == null) throw new NullPointerException("Error stream must not be null"); + if (input == null) throw new NullPointerException("Input stream must not be null"); + else if (output == null) throw new NullPointerException("Output stream must not be null"); + else if (error == null) throw new NullPointerException("Error stream must not be null"); this.input = input; this.output = output; this.error = error; } - /** - * Start handling commands from the given input stream. - */ + /** Start handling commands from the given input stream. */ public void runCommands() { - /* - * Setup output streams. - */ + /* Setup output streams. */ final PrintStream normalOutput = new PrintStream(output); - final PrintStream errorOutput = new PrintStream(error); + final PrintStream errorOutput = new PrintStream(error); /* * Set up input streams. * - * We're suppressing the warning because we might use the input - * stream multiple times. + * We're suppressing the warning about a potentially leaked + * resource because we might use the input stream multiple + * times. */ @SuppressWarnings("resource") final Scanner inputSource = new Scanner(input); @@ -69,55 +61,55 @@ public class CLICommander { /* * The mode currently being used to handle commands. * - * Used to preserve the initial mode. + * Used to preserve the initial mode, so that a mode can be + * invoked more than once. */ CommandMode currentMode = initialMode; + /* The number of the command we are executing. */ + int comno = 1; /* - * Process commands until we're told to stop. + * Process commands until we're told to stop, by the mode being + * set to null. */ while (currentMode != null) { /* - * Print out the command prompt, using a custom prompt - * if one is specified. + * Print out the command prompt. + * + * Use a custom prompt if one is specified. */ if (currentMode.isCustomPromptEnabled()) { normalOutput.print(currentMode.getCustomPrompt()); } else { - normalOutput.print(currentMode.getName() + ">> "); + normalOutput.printf("%s (%d)>> ", currentMode.getName(), comno); + + comno += 1; } - /* - * Read in a command. - */ + /* Read in a command. */ final String currentLine = inputSource.nextLine(); - /* - * Handle commands we can handle. - */ + /* Handle commands we can handle in this mode. */ if (currentMode.canHandle(currentLine)) { final String[] commandTokens = currentLine.split(" "); - String[] commandArgs = null; + String[] commandArgs = null; final int argCount = commandTokens.length; - /* - * Parse args if they are present. - */ + /* Parse args if they are present. */ if (argCount > 1) { commandArgs = Arrays.copyOfRange(commandTokens, 1, argCount); } - /* - * Process command. - */ + /* Process command. */ currentMode = currentMode.process(commandTokens[0], commandArgs); } else { - errorOutput.print("Error: Unrecognized command " + currentLine); + errorOutput.printf("Error: Unrecognized command '%s' (no. %d)\n", + currentLine, comno); } } - normalOutput.print("Exiting now."); + normalOutput.printf("Exiting now (ran %d commands).\n", comno); } /** @@ -127,7 +119,7 @@ public class CLICommander { * The initial command mode to use. */ public void setInitialCommandMode(final CommandMode initialMode) { - if (initialMode == null) throw new NullPointerException("Initial mode must be non-zero"); + if (initialMode == null) throw new NullPointerException("Initial mode must be non-null"); this.initialMode = initialMode; } diff --git a/base/src/main/java/bjc/utils/cli/Command.java b/base/src/main/java/bjc/utils/cli/Command.java index 02bc061..5969298 100644 --- a/base/src/main/java/bjc/utils/cli/Command.java +++ b/base/src/main/java/bjc/utils/cli/Command.java @@ -4,34 +4,37 @@ package bjc.utils.cli; * Represents a command that can be invoked from a {@link CommandMode} * * @author ben - * */ public interface Command { /** * Create a command that serves as an alias to this one * - * @return A command that serves as an alias to this one + * @return + * A command that serves as an alias to this one */ Command aliased(); /** * Get the handler that executes this command * - * @return The handler that executes this command + * @return + * The handler that executes this command */ CommandHandler getHandler(); /** * Get the help entry for this command * - * @return The help entry for this command + * @return + * The help entry for this command */ CommandHelp getHelp(); /** * Check if this command is an alias of another command * - * @return Whether or not this command is an alias of another + * @return + * Whether or not this command is an alias of another */ default boolean isAlias() { return false; diff --git a/base/src/main/java/bjc/utils/cli/CommandHandler.java b/base/src/main/java/bjc/utils/cli/CommandHandler.java index 2548248..fd40aa3 100644 --- a/base/src/main/java/bjc/utils/cli/CommandHandler.java +++ b/base/src/main/java/bjc/utils/cli/CommandHandler.java @@ -3,20 +3,21 @@ package bjc.utils.cli; import java.util.function.Function; /** - * A handler for a command + * A handler for a command. * * @author ben - * */ @FunctionalInterface public interface CommandHandler extends Function { /** - * Execute this command + * Execute this command. * * @param args - * The arguments for this command - * @return The command mode to switch to after this command, or null to - * stop executing commands + * The arguments for this command. + * + * @return + * The command mode to switch to after this command, or null to + * stop executing commands. */ default CommandMode handle(final String[] args) { return this.apply(args); diff --git a/base/src/main/java/bjc/utils/cli/CommandHelp.java b/base/src/main/java/bjc/utils/cli/CommandHelp.java index 86567a0..90ee404 100644 --- a/base/src/main/java/bjc/utils/cli/CommandHelp.java +++ b/base/src/main/java/bjc/utils/cli/CommandHelp.java @@ -4,13 +4,13 @@ package bjc.utils.cli; * Interface for the help entry for a command * * @author ben - * */ public interface CommandHelp { /** * Get the description of a command. * - * @return The description of a command + * @return + * The description of a command */ String getDescription(); @@ -20,12 +20,13 @@ public interface CommandHelp { * A summary line should consist of a string of the following format * *
-	 * "<command-name>\t<command-summary>"
+	 * "<command-name&rt;\t<command-summary&rt;"
 	 * 
* * where anything in angle brackets should be filled in. * - * @return The summary line line for a command + * @return + * The summary line line for a command */ String getSummary(); } diff --git a/base/src/main/java/bjc/utils/cli/CommandMode.java b/base/src/main/java/bjc/utils/cli/CommandMode.java index 39c72fc..4107717 100644 --- a/base/src/main/java/bjc/utils/cli/CommandMode.java +++ b/base/src/main/java/bjc/utils/cli/CommandMode.java @@ -2,64 +2,71 @@ package bjc.utils.cli; /** * A mode for determining the commands that are valid to enter, and then - * handling those commands + * handling those commands. * * @author ben - * */ public interface CommandMode extends Comparable { /** - * Check to see if this mode can handle the specified command + * Check to see if this mode can handle the specified command. * * @param command - * The command to check - * @return Whether or not this mode can handle the command. It is - * assumed not by default + * The command to check. + * + * @return + * Whether or not this mode can handle the command. It is + * assumed not by default. */ default boolean canHandle(final String command) { return false; }; /** - * Get the custom prompt for this mode + * Get the custom prompt for this mode. * - * @return the custom prompt for this mode + * @return + * The custom prompt for this mode. * * @throws UnsupportedOperationException - * if this mode doesn't support a custom prompt + * If this mode doesn't support a custom prompt. */ default String getCustomPrompt() { throw new UnsupportedOperationException("This mode doesn't support a custom prompt"); } /** - * Get the name of this command mode + * Get the name of this command mode. * - * @return The name of this command mode, which is the empty string by - * default + * @return + * The name of this command mode, or a default string if one isn't + * specified. */ public default String getName() { - return ""; + return "(anonymous)"; } /** - * Check if this mode uses a custom prompt + * Check if this mode uses a custom prompt. * - * @return Whether or not this mode uses a custom prompt + * @return + * Whether or not this mode uses a custom prompt. */ default boolean isCustomPromptEnabled() { return false; } /** - * Process a command in this mode + * Process a command in this mode.. * * @param command - * The command to process + * The command to process. + * * @param args - * A list of arguments to the command - * @return The command mode to use for the next command. Defaults to - * returning this, and doing nothing else + * A list of arguments to the command. + * + * @return + * The command mode to use for the next command. Defaults to doing + * nothing, and staying in the current mode. */ default CommandMode process(final String command, final String[] args) { return this; diff --git a/base/src/main/java/bjc/utils/cli/DelegatingCommand.java b/base/src/main/java/bjc/utils/cli/DelegatingCommand.java index acaa3a6..9e882c2 100644 --- a/base/src/main/java/bjc/utils/cli/DelegatingCommand.java +++ b/base/src/main/java/bjc/utils/cli/DelegatingCommand.java @@ -4,12 +4,9 @@ package bjc.utils.cli; * A class for a command that delegates to another command. * * @author ben - * */ class DelegatingCommand implements Command { - /* - * The command to delegate to. - */ + /* The command to delegate to. */ private final Command delegate; /** @@ -49,16 +46,6 @@ class DelegatingCommand implements Command { */ @Override public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("DelegatingCommand ["); - - if (delegate != null) { - builder.append("delegate="); - builder.append(delegate); - } - - builder.append("]"); - - return builder.toString(); + return String.format("DelegatingCommand [delegate=%s]", delegate); } } diff --git a/base/src/main/java/bjc/utils/cli/GenericCommand.java b/base/src/main/java/bjc/utils/cli/GenericCommand.java index 4ae4dea..89539a4 100644 --- a/base/src/main/java/bjc/utils/cli/GenericCommand.java +++ b/base/src/main/java/bjc/utils/cli/GenericCommand.java @@ -4,17 +4,12 @@ package bjc.utils.cli; * Generic command implementation. * * @author ben - * */ public class GenericCommand implements Command { - /* - * The behavior for invoking the command. - */ + /* The behavior for invoking the command. */ private final CommandHandler handler; - /* - * The help for the command. - */ + /* The help for the command. */ private CommandHelp help; /** @@ -22,9 +17,11 @@ public class GenericCommand implements Command { * * @param handler * The handler to use for the command. + * * @param description * The description of the command. May be null, in which * case a default is provided. + * * @param help * The detailed help message for the command. May be * null, in which case the description is repeated for @@ -69,16 +66,6 @@ public class GenericCommand implements Command { */ @Override public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("GenericCommand ["); - - if (help != null) { - builder.append("help="); - builder.append(help); - } - - builder.append("]"); - - return builder.toString(); + return String.format("GenericCommand [help=%s]", help); } } diff --git a/base/src/main/java/bjc/utils/cli/GenericCommandMode.java b/base/src/main/java/bjc/utils/cli/GenericCommandMode.java index 8764537..e24a17b 100644 --- a/base/src/main/java/bjc/utils/cli/GenericCommandMode.java +++ b/base/src/main/java/bjc/utils/cli/GenericCommandMode.java @@ -8,103 +8,91 @@ import bjc.utils.funcdata.FunctionalMap; import bjc.utils.funcdata.IMap; /** - * A general command mode, with a customizable set of commands + * A general command mode, with a customizable set of commands. * * There is a small set of commands which is handled by default. The first is * 'list', which lists all the commands the user can input. The second is - * 'alias', which allows the user to bind a new name to a command + * 'alias', which allows the user to bind a new name to a command. * * @author ben - * */ public class GenericCommandMode implements CommandMode { - /* - * Contains the commands this mode handles - */ - private final IMap commandHandlers; - private final IMap defaultHandlers; + /* Contains the commands this mode handles. */ + private final IMap commandHandlers; + /* Commands to execute in every mode. */ + private final IMap defaultHandlers; - /* - * Contains help topics without an associated command - */ + /* Contains help topics without an associated command */ private final IMap helpTopics; - /* - * The action to execute upon encountering an unknown command - */ + /* The action to execute upon encountering an unknown command */ private BiConsumer unknownCommandHandler; - /* - * The functions to use for input/output - */ - private final Consumer errorOutput; - private final Consumer normalOutput; + /* The functions to use for input/output */ + private final Consumer errorOutput; + private final Consumer normalOutput; - /* - * The name of this command mode, or null if it is unnamed - */ + /* The name of this command mode, or null if it is unnamed */ private String modeName; - /* - * The custom prompt to use, or null if none is specified - */ + /* The custom prompt to use, or null if none is specified */ private String customPrompt; /** * Create a new generic command mode * * @param normalOutput - * The function to use for normal output + * The function to use for normal output. + * * @param errorOutput - * The function to use for error output + * The function to use for error output. */ public GenericCommandMode(final Consumer normalOutput, final Consumer errorOutput) { - if (normalOutput == null) - throw new NullPointerException("Normal output source must be non-null"); + if (normalOutput == null) throw new NullPointerException("Normal output source must be non-null"); else if (errorOutput == null) throw new NullPointerException("Error output source must be non-null"); this.normalOutput = normalOutput; - this.errorOutput = errorOutput; + this.errorOutput = errorOutput; - /* - * Initialize handler maps so that they sort in alphabetical - */ - /* - * order - */ + /* Initialize maps so that they sort in alphabetical order. */ commandHandlers = new FunctionalMap<>(new TreeMap<>()); defaultHandlers = new FunctionalMap<>(new TreeMap<>()); - helpTopics = new FunctionalMap<>(new TreeMap<>()); + helpTopics = new FunctionalMap<>(new TreeMap<>()); + /* Setup default commands. */ setupDefaultCommands(); } /** - * Add an alias to an existing command + * Add an alias to an existing command. * * @param commandName - * The name of the command to add an alias for + * The name of the command to add an alias for. + * * @param aliasName - * The new alias for the command + * The new alias for the command. * * @throws IllegalArgumentException - * if the specified command doesn't have a bound - * handler, or if the alias name already has a bound - * value + * If the specified command doesn't have a bound handler, or if the + * alias name already has a bound value. */ public void addCommandAlias(final String commandName, final String aliasName) { - if (commandName == null) + if (commandName == null) { throw new NullPointerException("Command name must not be null"); - else if (aliasName == null) - throw new NullPointerException("Alias name must not be null"); - else if (!commandHandlers.containsKey(commandName) && !defaultHandlers.containsKey(commandName)) - throw new IllegalArgumentException("Cannot alias non-existant command '" + commandName + "'"); - else if (commandHandlers.containsKey(aliasName) || defaultHandlers.containsKey(aliasName)) - throw new IllegalArgumentException( - "Cannot bind alias '" + aliasName + "' to a command with a bound handler"); - else { + } else if (aliasName == null) { + String msg = "Alias name must not be null"; + throw new NullPointerException(msg); + } else if (!commandHandlers.containsKey(commandName) && !defaultHandlers.containsKey(commandName)) { + String msg = String.format("Cannot alias non-existant command '%s'", commandName); + throw new IllegalArgumentException(msg); + } else if (commandHandlers.containsKey(aliasName) || defaultHandlers.containsKey(aliasName)) { + String msg = String.format("Cannot bind alias '%s' to an already bound command.", aliasName); + throw new IllegalArgumentException(msg); + } else { + /* The command that will be aliased. */ Command aliasedCommand; + /* Get the alias. */ if (defaultHandlers.containsKey(commandName)) { aliasedCommand = defaultHandlers.get(commandName).aliased(); } else { @@ -116,45 +104,49 @@ public class GenericCommandMode implements CommandMode { } /** - * Add a command to this command mode + * Add a command to this command mode. * * @param command - * The name of the command to add + * The name of the command to add. + * * @param handler - * The handler to use for the specified command + * The handler to use for the specified command. * * @throws IllegalArgumentException - * if the specified command already has a handler - * registered + * If the specified command already has a handler registered. */ public void addCommandHandler(final String command, final Command handler) { - if (command == null) + if (command == null) { throw new NullPointerException("Command must not be null"); - else if (handler == null) + } else if (handler == null) { throw new NullPointerException("Handler must not be null"); - else if (canHandle(command)) - throw new IllegalArgumentException("Command " + command + " already has a handler registered"); - else { + } else if (canHandle(command)) { + String msg = String.format("Command '%s' already has a registered handler"); + throw new IllegalArgumentException(msg); + } else { commandHandlers.put(command, handler); } } /** - * Add a help topic to this command mode that isn't tied to a command + * Add a help topic to this command mode that isn't tied to a command. * * @param topicName - * The name of the topic + * The name of the topic. + * * @param topic - * The contents of the topic + * The contents of the topic. */ public void addHelpTopic(final String topicName, final CommandHelp topic) { helpTopics.put(topicName, topic); } + /* Default command builders */ /* - * Default command builders + * @TODO 10/09/17 Ben Culkin :CommandExtraction + * These command messages should be extracted into some kind of + * file-based abstraction. */ - private GenericCommand buildAliasCommand() { final String aliasShortHelp = "alias\tAlias one command to another"; final String aliasLongHelp = "Gives a command another name it can be invoked by." @@ -200,14 +192,10 @@ public class GenericCommandMode implements CommandMode { return new GenericCommand((args) -> { if (args == null || args.length == 0) { - /* - * Invoke general help - */ + /* Invoke general help */ doHelpSummary(); } else { - /* - * Invoke help for a command - */ + /* Invoke help for a command */ doHelpCommand(args[0]); } @@ -232,22 +220,23 @@ public class GenericCommandMode implements CommandMode { return commandHandlers.containsKey(command) || defaultHandlers.containsKey(command); } - /* - * Implement default commands - */ - + /* Implement default commands */ private void doAliasCommands(final String[] args) { if (args.length != 2) { - errorOutput.accept("ERROR: Alias requires two arguments." - + " The command name, and the alias for that command"); + String msg = String.format("ERROR: Alias requires two arguments. The command name, and the alias for that command. "); + errorOutput.accept(msg); } else { final String commandName = args[0]; final String aliasName = args[1]; if (!canHandle(commandName)) { - errorOutput.accept("ERROR: '" + commandName + "' is not a valid command."); + String msg = String.format("ERROR: '%s' is not a valid command.", commandName); + + errorOutput.accept(msg); } else if (canHandle(aliasName)) { - errorOutput.accept("ERROR: Cannot overwrite command '" + aliasName + "'"); + String msg = String.format("ERROR: Cannot overwrite command '%s'", aliasName); + + errorOutput.accept(msg); } else { addCommandAlias(commandName, aliasName); } @@ -266,8 +255,9 @@ public class GenericCommandMode implements CommandMode { } else if (helpTopics.containsKey(commandName)) { normalOutput.accept("\n" + helpTopics.get(commandName).getDescription()); } else { - errorOutput.accept( - "ERROR: I'm sorry, but there is no help available for '" + commandName + "'"); + String msg = String.format("ERROR: No help available for '%s'", commandName); + + errorOutput.accept(msg); } } @@ -277,7 +267,10 @@ public class GenericCommandMode implements CommandMode { if (commandHandlers.size() > 0) { commandHandlers.forEachValue(command -> { if (!command.isAlias()) { - normalOutput.accept("\t" + command.getHelp().getSummary() + "\n"); + String comLine = command.getHelp().getSummary(); + String msg = String.format("\t%s\n", comLine); + + normalOutput.accept(msg); } }); } else { @@ -286,9 +279,17 @@ public class GenericCommandMode implements CommandMode { normalOutput.accept("\nHelp topics available in all command modes are as follows\n"); if (defaultHandlers.size() > 0) { + /* + * @NOTE + * This block here should be abstracted out into a + * method. + */ defaultHandlers.forEachValue(command -> { if (!command.isAlias()) { - normalOutput.accept("\t" + command.getHelp().getSummary() + "\n"); + String comLine = command.getHelp().getSummary(); + String msg = String.format("\t%s\n", comLine); + + normalOutput.accept(msg); } }); } else { @@ -298,7 +299,9 @@ public class GenericCommandMode implements CommandMode { normalOutput.accept("\nHelp topics not associated with a command are as follows\n"); if (helpTopics.size() > 0) { helpTopics.forEachValue(topic -> { - normalOutput.accept("\t" + topic.getSummary() + "\n"); + String msg = String.format("\t%s\n", topic.getSummary()); + + normalOutput.accept(msg); }); } else { normalOutput.accept("\tNone available\n"); @@ -309,12 +312,16 @@ public class GenericCommandMode implements CommandMode { normalOutput.accept("The available commands for this mode are as follows:\n"); commandHandlers.keyList().forEach(commandName -> { - normalOutput.accept("\t" + commandName); + String msg = String.format("\t%s", commandName); + + normalOutput.accept(msg); }); normalOutput.accept("\nThe following commands are available in all modes:\n"); defaultHandlers.keyList().forEach(commandName -> { - normalOutput.accept("\t" + commandName); + String msg = String.format("\t%s", commandName); + + normalOutput.accept(msg); }); normalOutput.accept("\n"); @@ -349,13 +356,22 @@ public class GenericCommandMode implements CommandMode { return commandHandlers.get(command).getHandler().handle(args); else { if (args != null) { - errorOutput.accept("ERROR: Unrecognized command " + command + String.join(" ", args)); + String argString = String.join(", ", args); + String msg = String.format("ERROR: Unrecognized command %s (arguments %s)", + command, argString); + + errorOutput.accept(msg); } else { - errorOutput.accept("ERROR: Unrecognized command " + command); + String msg = String.format("ERROR: Unrecognized command %s", command); + + errorOutput.accept(msg); } - if (unknownCommandHandler == null) - throw new UnsupportedOperationException("Command " + command + " is invalid."); + if (unknownCommandHandler == null) { + String msg = String.format("Command %s is invalid", command); + + throw new UnsupportedOperationException(msg); + } unknownCommandHandler.accept(command, args); } @@ -367,8 +383,8 @@ public class GenericCommandMode implements CommandMode { * Set the custom prompt for this mode * * @param prompt - * The custom prompt for this mode, or null to disable - * the custom prompt + * The custom prompt for this mode, or null to disable the custom + * prompt */ public void setCustomPrompt(final String prompt) { customPrompt = prompt; @@ -378,8 +394,7 @@ public class GenericCommandMode implements CommandMode { * Set the name of this mode * * @param name - * The desired name of this mode, or null to use the - * default name + * The desired name of this mode, or null to use the default name */ public void setModeName(final String name) { modeName = name; @@ -389,8 +404,8 @@ public class GenericCommandMode implements CommandMode { * Set the handler to use for unknown commands * * @param handler - * The handler to use for unknown commands, or null to - * throw on unknown commands + * The handler to use for unknown commands, or null to throw on + * unknown commands */ public void setUnknownCommandHandler(final BiConsumer handler) { if (handler == null) throw new NullPointerException("Handler must not be null"); @@ -398,25 +413,20 @@ public class GenericCommandMode implements CommandMode { unknownCommandHandler = handler; } + /* Setup default commands. */ private void setupDefaultCommands() { - defaultHandlers.put("list", buildListCommand()); + defaultHandlers.put("list", buildListCommand()); defaultHandlers.put("alias", buildAliasCommand()); - defaultHandlers.put("help", buildHelpCommand()); + defaultHandlers.put("help", buildHelpCommand()); + /* Help unix people :) */ addCommandAlias("help", "man"); + /* Add commands handled in a upper layer. */ /* - * Add commands handled in a upper layer. - */ - - /* - * @TODO figure out a place to put commands that apply across - */ - /* - * all - */ - /* - * modes, but only apply to a specific application + * @NOTE + * Figure out a place to put commands that apply across all + * modes, but only to a specific application. */ defaultHandlers.put("clear", buildClearCommands()); defaultHandlers.put("exit", buildExitCommand()); @@ -465,5 +475,4 @@ public class GenericCommandMode implements CommandMode { return builder.toString(); } - } diff --git a/base/src/main/java/bjc/utils/cli/GenericHelp.java b/base/src/main/java/bjc/utils/cli/GenericHelp.java index 38adf57..92c1eef 100644 --- a/base/src/main/java/bjc/utils/cli/GenericHelp.java +++ b/base/src/main/java/bjc/utils/cli/GenericHelp.java @@ -1,35 +1,39 @@ package bjc.utils.cli; /** - * Generic implementation of a help topic + * Generic implementation of a help topic. * * @author ben - * */ public class GenericHelp implements CommandHelp { - // The strings for this help topic + /* The strings for this help topic. */ private final String summary; private final String description; /** - * Create a new help topic + * Create a new help topic. * * @param summary - * The summary of this help topic + * The summary of this help topic. + * * @param description - * The description of this help topic, or null if this - * help topic doesn't have a more detailed description + * The description of this help topic, or null if this help topic + * doesn't have a more detailed description. */ public GenericHelp(final String summary, final String description) { - if (summary == null) throw new NullPointerException("Help summary must be non-null"); + if (summary == null) { + throw new NullPointerException("Help summary must be non-null"); + } - this.summary = summary; + this.summary = summary; this.description = description; } @Override public String getDescription() { - if (description == null) return summary; + if (description == null) { + return summary; + } return description; } diff --git a/base/src/main/java/bjc/utils/cli/NullHelp.java b/base/src/main/java/bjc/utils/cli/NullHelp.java index 6c49ae6..5e5fb67 100644 --- a/base/src/main/java/bjc/utils/cli/NullHelp.java +++ b/base/src/main/java/bjc/utils/cli/NullHelp.java @@ -1,10 +1,9 @@ package bjc.utils.cli; /** - * Implementation of a help topic that doesn't exist + * Implementation of a help topic that doesn't exist. * * @author ben - * */ public class NullHelp implements CommandHelp { @Override diff --git a/base/src/main/java/bjc/utils/cli/objects/BlockReaderCLI.java b/base/src/main/java/bjc/utils/cli/objects/BlockReaderCLI.java index ec66fe2..2edea08 100644 --- a/base/src/main/java/bjc/utils/cli/objects/BlockReaderCLI.java +++ b/base/src/main/java/bjc/utils/cli/objects/BlockReaderCLI.java @@ -18,19 +18,46 @@ import bjc.utils.ioutils.blocks.*; import static bjc.utils.cli.objects.Command.CommandStatus; import static bjc.utils.cli.objects.Command.CommandStatus.*; +/** + * Command-line interface for configuring block readers. + * + * @author Ben Culkin + */ public class BlockReaderCLI { + /* Logger. */ private final Logger LOGGER = Logger.getLogger(BlockReaderCLI.class.getName()); + /** + * The state of the block reader. + * + * @author Ben Culkin + */ public static class BlockReaderState { + /** + * All of the configured block readers. + */ public final Map readers; + /** + * All of the configured I/O sources. + */ public final Map sources; + /** + * Create a new set of state for the block reader. + * + * @param readers + * The set of configured block readers. + * + * @param sources + * The set of configured I/O sources. + */ public BlockReaderState(Map readers, Map sources) { this.readers = readers; this.sources = sources; } } + /* Our state. */ private BlockReaderState stat; /** @@ -43,16 +70,33 @@ public class BlockReaderCLI { stat = new BlockReaderState(new HashMap<>(), srcs); } + /** + * Create a new CLI for configuring BlockReaders. + * + * @param state + * The state object to use. + */ + public BlockReaderCLI(BlockReaderState state) { + stat = state; + } + + /* :CLIArgsParsing */ + /** + * Run the command line interface + * + * @param args + * Ignored CLI args. + */ public static void main(String[] args) { - /* - * Create/configure I/O sources. - */ + /* Create/configure I/O sources. */ Map sources = new HashMap<>(); - sources.put("stdio", new InputStreamReader(System.in)); + BlockReaderCLI reader = new BlockReaderCLI(sources); - BlockReaderCLI reader = new BlockReaderCLI(sources); + sources.put("stdio", new InputStreamReader(System.in)); - reader.run(new Scanner(System.in), "console", true); + Scanner input = new Scanner(System.in); + reader.run(input, "console", true); + input.close(); } /** @@ -60,61 +104,79 @@ public class BlockReaderCLI { * * @param input * The place to read input from. + * * @param ioSource * The name of the place to read input from. + * * @param interactive * Whether or not the source is interactive */ public void run(Scanner input, String ioSource, boolean interactive) { int lno = 0; - while(input.hasNextLine()) { - if(interactive) - System.out.printf("reader-conf(%d)>", lno); + /* Print a prompt. */ + if(interactive) { + System.out.printf("reader-conf(%d)>", lno); + } + while(input.hasNextLine()) { + /* Read a line. */ String ln = input.nextLine(); - lno += 1; + /* Parse the command. */ Command com = Command.fromString(ln, lno, ioSource); + /* Ignore blank commands. */ if(com == null) continue; + /* Handle a command. */ CommandStatus stat = handleCommand(com, interactive); + /* Exit if we finished or encountered a fatal error. */ if(stat == FINISH || stat == ERROR) { return; } - } - input.close(); + /* Print a prompt. */ + if(interactive) { + System.out.printf("reader-conf(%d)>", lno); + } + + } } - /* + /** * Handle a command. + * + * @param com + * The command to handle + * + * @param interactive + * Whether the current input source is interactive or not. */ public CommandStatus handleCommand(Command com, boolean interactive) { switch(com.nameCommand) { - case "def-filtered": - return defFiltered(com); - case "def-layered": - return defLayered(com); - case "def-pushback": - return defPushback(com); - case "def-simple": - return defSimple(com); - case "def-serial": - return defSerial(com); - case "def-toggled": - return defToggled(com); - case "}": - case "end": - case "exit": - case "quit": - if(interactive) - System.out.printf("Exiting reader-conf, %d readers configured in %d commands\n", - stat.readers.size(), com.lineNo); - return FINISH; - default: - LOGGER.severe(com.error("Unknown command '%s'\n", com.nameCommand)); - return FAIL; + case "def-filtered": + return defFiltered(com); + case "def-layered": + return defLayered(com); + case "def-pushback": + return defPushback(com); + case "def-simple": + return defSimple(com); + case "def-serial": + return defSerial(com); + case "def-toggled": + return defToggled(com); + case "}": + case "end": + case "exit": + case "quit": + if(interactive) + System.out.printf("Exiting reader-conf, %d readers configured in %d commands\n", + stat.readers.size(), com.lineNo); + return FINISH; + default: + LOGGER.severe(com.error("Unknown command '%s'\n", com.nameCommand)); + return FAIL; } } diff --git a/base/src/main/java/bjc/utils/cli/objects/Command.java b/base/src/main/java/bjc/utils/cli/objects/Command.java index e605a2b..3a7d452 100644 --- a/base/src/main/java/bjc/utils/cli/objects/Command.java +++ b/base/src/main/java/bjc/utils/cli/objects/Command.java @@ -1,8 +1,15 @@ package bjc.utils.cli.objects; +/** + * A single-line command read from the user. + * + * @author Ben Culkin + */ public class Command { /** * Command status values. + * + * @author Ben Culkin */ public static enum CommandStatus { /** @@ -23,21 +30,38 @@ public class Command { FINISH, } + /** + * The line number of this command. + */ public final int lineNo; + /** + * The full text of this command. + */ public final String fullCommand; + /** + * The text of this command without its name. + */ public final String remnCommand; + /** + * The name of this command. + */ public final String nameCommand; + /** + * The name of the I/O source this command was read from. + */ public final String ioSource; /** * Create a new command. * * @param ln - * The line to get the command from. + * The string to get the command from. + * * @param lno * The number of the line the command came from. + * * @param ioSrc * The name of where the I/O came from. */ @@ -55,16 +79,28 @@ public class Command { ioSource = ioSrc; } + /** + * Parse a command from a string. + * + * The main thing this does is ignore blank lines, as well as comments + * marked by #'s either at the start of the line or part of the way + * through the line. + * + * @param ln + * The string to get the command from. + * + * @param lno + * The line number of the command. + * + * @param ioSource + * The name of where the I/O came from. + */ public static Command fromString(String ln, int lno, String ioSource) { - /* - * Ignore blank lines and comments. - */ + /* Ignore blank lines and comments. */ if(ln.equals("")) return null; if(ln.startsWith("#")) return null; - /* - * Trim off comments part-way through the line. - */ + /* Trim off comments part-way through the line. */ int idxHash = ln.indexOf('#'); if(idxHash != -1) { ln = ln.substring(0, idxHash).trim(); @@ -73,12 +109,46 @@ public class Command { return new Command(ln, lno, ioSource); } + /** + * Give an informational message about something in relation to this + * command. + * + * @param info + * The informational message. + * + * @param parms + * The parameters for the informational message. + */ + public String info(String info, Object... parms) { + String msg = String.format(info, parms); + + return String.format("INFO (%s:%d): %s", ioSource, lineNo, msg); + } + + /** + * Warn about something in relation to this command. + * + * @param warning + * The warning message. + * + * @param parms + * The parameters for the warning message. + */ public String warn(String warning, Object... parms) { String msg = String.format(warning, parms); return String.format("WARNING (%s:%d): %s", ioSource, lineNo, msg); } + /** + * Give an error about something in relation to this command. + * + * @param error + * The error message. + * + * @param parms + * The parameters for the error message. + */ public String error(String err, Object... parms) { String msg = String.format(err, parms); diff --git a/base/src/main/java/bjc/utils/cli/objects/DefineCLI.java b/base/src/main/java/bjc/utils/cli/objects/DefineCLI.java index bb2733f..5763a83 100644 --- a/base/src/main/java/bjc/utils/cli/objects/DefineCLI.java +++ b/base/src/main/java/bjc/utils/cli/objects/DefineCLI.java @@ -10,6 +10,16 @@ import java.util.regex.Pattern; import static bjc.utils.cli.objects.Command.CommandStatus; import static bjc.utils.cli.objects.Command.CommandStatus.*; +/* + * @TODO 10/09/17 :DefineCLIFinish + * This got left off about halfway through due to getting distracted + * implementing CL-style format strings. It needs to be finished. + */ +/** + * Command-line interface for building defines. + * + * @author Ben Culkin + */ public class DefineCLI { private final Logger LOGGER = Logger.getLogger(DefineCLI.class.getName()); diff --git a/base/src/main/java/bjc/utils/components/ComponentDescription.java b/base/src/main/java/bjc/utils/components/ComponentDescription.java index 28f81d1..8d44855 100644 --- a/base/src/main/java/bjc/utils/components/ComponentDescription.java +++ b/base/src/main/java/bjc/utils/components/ComponentDescription.java @@ -1,50 +1,47 @@ package bjc.utils.components; /** - * Generic implementation of a description for a component + * Generic implementation of a description for a component. * * @author ben - * */ public class ComponentDescription implements IDescribedComponent { + /* Check arguments are good. */ private static void sanityCheckArgs(final String name, final String author, final String description, final int version) { - if (name == null) + if (name == null) { throw new NullPointerException("Component name can't be null"); - else if (version <= 0) throw new IllegalArgumentException("Component version must be greater than 0"); + } else if (version <= 0) { + throw new IllegalArgumentException("Component version must be greater than 0"); + } } - /** - * The author of the component - */ - private final String author; - /** - * The description of the component - */ - private final String description; - /** - * The name of the component - */ - private final String name; - - /** - * The version of the component - */ + /** The author of the component */ + private final String author; + /** The description of the component */ + private final String description; + /** The name of the component */ + private final String name; + /** The version of the component */ private final int version; /** - * Create a new component description + * Create a new component description. * * @param name - * The name of the component + * The name of the component. + * * @param author - * The author of the component + * The author of the component. + * * @param description - * The description of the component + * The description of the component. + * * @param version - * The version of the component + * The version of the component. + * * @throws IllegalArgumentException - * thrown if version is less than 1 + * Thrown if version is less than 1. */ public ComponentDescription(final String name, final String author, final String description, final int version) { @@ -58,14 +55,18 @@ public class ComponentDescription implements IDescribedComponent { @Override public String getAuthor() { - if (author == null) return IDescribedComponent.super.getAuthor(); + if (author == null) { + return IDescribedComponent.super.getAuthor(); + } return author; } @Override public String getDescription() { - if (description == null) return IDescribedComponent.super.getDescription(); + if (description == null) { + return IDescribedComponent.super.getDescription(); + } return description; } @@ -82,7 +83,7 @@ public class ComponentDescription implements IDescribedComponent { @Override public String toString() { - return name + " component v" + version + ", written by " + author; + return String.format("%s component v%d, written by %s", name, version, author); } /* diff --git a/base/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java b/base/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java index f7ddaff..3855f8f 100644 --- a/base/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java +++ b/base/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java @@ -1,57 +1,63 @@ package bjc.utils.components; -import static bjc.utils.ioutils.RuleBasedReaderPragmas.buildInteger; -import static bjc.utils.ioutils.RuleBasedReaderPragmas.buildStringCollapser; - import java.io.InputStream; import bjc.utils.ioutils.RuleBasedConfigReader; +import static bjc.utils.ioutils.RuleBasedReaderPragmas.buildInteger; +import static bjc.utils.ioutils.RuleBasedReaderPragmas.buildStringCollapser; + /** - * Read a component description from a file + * Read a component description from a file. * * @author ben - * */ public class ComponentDescriptionFileParser { - // The reader used to read in component descriptions + /* The reader used to read in component descriptions */ private static RuleBasedConfigReader reader; - // Initialize the reader and its pragmas + /* Initialize the reader and its pragmas. */ static { - // This reader works entirely off of pragmas, so no need to - // handle - // rules + /* + * This reader works entirely off of pragmas, so no need to + * handle rules. + */ reader = new RuleBasedConfigReader<>((tokenizer, statePair) -> { - // Don't need to do anything on rule start + /* Don't need to do anything on rule start. */ }, (tokenizer, state) -> { - // Don't need to do anything on rule continuation + /* Don't need to do anything on rule continuation. */ }, (state) -> { - // Don't need to do anything on rule end + /* Don't need to do anything on rule end. */ }); + /* Setup reader pragmas. */ setupReaderPragmas(); } /** - * Parse a component description from a stream + * Parse a component description from a stream. * * @param inputSource - * The stream to parse from - * @return The description parsed from the stream + * The stream to parse from. + * + * @return The description parsed from the stream. */ public static ComponentDescription fromStream(final InputStream inputSource) { - if (inputSource == null) throw new NullPointerException("Input source must not be null"); + if (inputSource == null) { + throw new NullPointerException("Input source must not be null"); + } - final ComponentDescriptionState readState = reader.fromStream(inputSource, - new ComponentDescriptionState()); + ComponentDescriptionState state = new ComponentDescriptionState(); + /* + * This is valid, because the thing that is returned is the same + * reference we passed in. + */ + reader.fromStream(inputSource, state); - return readState.toDescription(); + return state.toDescription(); } - /* - * Create all the pragmas the reader needs to function - */ + /* Create all the pragmas the reader needs to function. */ private static void setupReaderPragmas() { reader.addPragma("name", buildStringCollapser("name", (name, state) -> state.setName(name))); diff --git a/base/src/main/java/bjc/utils/components/ComponentDescriptionState.java b/base/src/main/java/bjc/utils/components/ComponentDescriptionState.java index 8d66f85..f944a9e 100644 --- a/base/src/main/java/bjc/utils/components/ComponentDescriptionState.java +++ b/base/src/main/java/bjc/utils/components/ComponentDescriptionState.java @@ -1,68 +1,68 @@ package bjc.utils.components; /** - * Internal state of component description parser + * Internal state of component description parser. * * @author ben - * */ public class ComponentDescriptionState { - // Tentative name of this component + /* Tentative name of this component. */ private String name; - // Tentative description of this componet + /* Tentative description of this component. */ private String description; - // Tentative author of this component + /* Tentative author of this component. */ private String author; - // Tentative version of this component + /* Tentative version of this component. */ private int version; /** - * Set the author of this component + * Set the author of this component. * * @param author - * The author of this component + * The author of this component. */ public void setAuthor(final String author) { this.author = author; } /** - * Set the description of this component + * Set the description of this component. * * @param description - * The description of this component + * The description of this component. */ public void setDescription(final String description) { this.description = description; } /** - * Set the name of this component + * Set the name of this component. * * @param name - * The name of this component + * The name of this component. */ public void setName(final String name) { this.name = name; } /** - * Set the version of this component + * Set the version of this component. * * @param version - * The version of this component + * The version of this component. */ public void setVersion(final int version) { this.version = version; } /** - * Convert this state into the description it represents + * Convert this state into the description it represents. * - * @return The description represented by this state + * @return + * The description represented by this state. */ public ComponentDescription toDescription() { return new ComponentDescription(name, author, description, version); @@ -71,7 +71,7 @@ public class ComponentDescriptionState { @Override public int hashCode() { final int prime = 31; - int result = 1; + int result = 1; result = prime * result + (author == null ? 0 : author.hashCode()); result = prime * result + (description == null ? 0 : description.hashCode()); @@ -140,5 +140,4 @@ public class ComponentDescriptionState { return builder.toString(); } - } diff --git a/base/src/main/java/bjc/utils/components/FileComponentRepository.java b/base/src/main/java/bjc/utils/components/FileComponentRepository.java index efde5c7..284c10c 100644 --- a/base/src/main/java/bjc/utils/components/FileComponentRepository.java +++ b/base/src/main/java/bjc/utils/components/FileComponentRepository.java @@ -17,85 +17,86 @@ import bjc.utils.funcdata.IMap; import bjc.utils.funcutils.FileUtils; /** - * A component repository that loads its components from files in a directory + * A component repository that loads its components from files in a directory. * * @author ben * * @param - * The type of component being read in + * The type of component being read in. */ public class FileComponentRepository implements IComponentRepository { - // The logger to use for storing data about this class + /* The logger to use for storing data about this class. */ private static final Logger CLASS_LOGGER = Logger.getLogger("FileComponentRepository"); - // The internal storage of components + /* The internal storage of components. */ private IMap components; - // The path that all the components came from + /* The path that all the components came from. */ private Path sourceDirectory; /** * Create a new component repository sourcing components from files in a - * directory + * directory. * * An exception thrown during the loading of a component will only cause * the loading of that component to fail, but a warning will be logged. * * @param directory - * The directory to read component files from + * The directory to read component files from. + * * @param componentReader - * The function to use to convert files to components + * The function to use to convert files to components. */ public FileComponentRepository(final File directory, final Function componentReader) { - // Make sure we have valid arguments - if (directory == null) + /* Make sure we have valid arguments. */ + if (directory == null) { throw new NullPointerException("Directory must not be null"); - else if (!directory.isDirectory()) - throw new IllegalArgumentException("File " + directory + " is not a directory.\n" - + "Components can only be read from a directory"); - else if (componentReader == null) throw new NullPointerException("Component reader must not be null"); + } else if (!directory.isDirectory()) { + String msg = String.format("File %s is not a directory. Components can only be read from a directory.", + directory); + + throw new IllegalArgumentException(msg); + } else if (componentReader == null) { + throw new NullPointerException("Component reader must not be null"); + } - // Initialize our fields + /* Initialize our fields. */ components = new FunctionalMap<>(); sourceDirectory = directory.toPath().toAbsolutePath(); - // Marker for making sure we don't skip the parent + /* Marker for making sure we don't skip the parent. */ final IHolder isFirstDir = new Identity<>(true); - // Predicate to use to traverse all the files in a directory, - // but - // not recurse into sub-directories + /* + * Predicate to use to traverse all the files in a directory, + * but not recurse into sub-directories. + */ final BiPredicate firstLevelTraverser = (pth, attr) -> { - if (attr.isDirectory() && !isFirstDir.getValue()) /* - * Skip - * directories, - * they - * probably - * have - * component - * support - * files. - */ + if (attr.isDirectory() && !isFirstDir.getValue()) { + /* + * Skip directories, they probably have + * component support files. + */ return false; + } /* * Don't skip the first directory, that's the parent - * directory + * directory. */ isFirstDir.replace(false); return true; }; - // Try reading components + /* Try reading components. */ try { FileUtils.traverseDirectory(sourceDirectory, firstLevelTraverser, (pth, attr) -> { loadComponent(componentReader, pth); - // Keep loading components, even if this one - // failed + /* Keep loading components, even if this one failed. */ return true; }); } catch (final IOException ioex) { @@ -120,40 +121,48 @@ public class FileComponentRepository @Override public String getSource() { - return "Components read from directory " + sourceDirectory + "."; + return String.format("Components read from directory %s.", sourceDirectory); } - /* - * Load a component from a file - */ + /* Load a component from a file */ private void loadComponent(final Function componentReader, final Path pth) { try { - // Try to load the component + /* Try to load the component. */ final ComponentType component = componentReader.apply(pth.toFile()); - if (component == null) + if (component == null) { throw new NullPointerException("Component reader read null component"); - else if (!components.containsKey(component.getName())) { - // We only care about the latest version of a - // component + } else if (!components.containsKey(component.getName())) { + /* + * We only care about the latest version of a + * component. + */ final ComponentType oldComponent = components.put(component.getName(), component); if (oldComponent.getVersion() > component.getVersion()) { components.put(oldComponent.getName(), oldComponent); } } else { - CLASS_LOGGER.warning("Found a duplicate component.\n" - + "Multiple versions of the same component are not currently supported.\n" - + "Only the latest version of the component" + component - + " will be registered ."); + StringBuilder sb = new StringBuilder(); + sb.append("Found a duplicate component.\n"); + sb.append("Multiple versions of the same component are not currently supported.\n"); + sb.append("Only the latest version of the component "); + sb.append(component); + sb.append(" will be registered."); + + CLASS_LOGGER.warning(sb.toString()); } } catch (final Exception ex) { - CLASS_LOGGER.log(Level.WARNING, ex, () -> "Error found reading component from file " - + pth.toString() + ". This component will not be loaded"); + String msg = String.format("Error found reading component from file %s. It will not be loaded.", pth.toString()); + + CLASS_LOGGER.log(Level.WARNING, ex, () -> msg); } } /* + * @NOTE + * Should this be changed to something more readable? + * * (non-Javadoc) * * @see java.lang.Object#toString() @@ -178,4 +187,4 @@ public class FileComponentRepository return builder.toString(); } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/components/IComponentRepository.java b/base/src/main/java/bjc/utils/components/IComponentRepository.java index 6ee51f3..099693f 100644 --- a/base/src/main/java/bjc/utils/components/IComponentRepository.java +++ b/base/src/main/java/bjc/utils/components/IComponentRepository.java @@ -5,45 +5,49 @@ import bjc.utils.funcdata.IMap; /** * A collection of implementations of a particular type of - * {@link IDescribedComponent} + * {@link IDescribedComponent}. * * @author ben * * @param - * The type of components contained in this repository + * The type of components contained in this repository. */ public interface IComponentRepository { /** - * Get all of the components this repository knows about + * Get all of the components this repository knows about. * - * @return A map from component name to component, containing all of the - * components in the repositories + * @return + * A map from component name to component, containing all of the + * components in the repositories. */ public IMap getAll(); /** - * Get a component with a specific name + * Get a component with a specific name. * * @param name - * The name of the component to retrieve - * @return The named component, or null if no component with that name - * exists + * The name of the component to retrieve. + * + * @return + * The named component, or null if no component with that name exists. */ public ComponentType getByName(String name); /** - * Get a list of all the registered components + * Get a list of all the registered components. * - * @return A list of all the registered components + * @return + * A list of all the registered components. */ public default IList getList() { return getAll().valueList(); } /** - * Get the source from which these components came + * Get the source from which these components came. * - * @return The source from which these components came + * @return + * The source from which these components came. */ public String getSource(); -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/components/IDescribedComponent.java b/base/src/main/java/bjc/utils/components/IDescribedComponent.java index 952b375..78af4bc 100644 --- a/base/src/main/java/bjc/utils/components/IDescribedComponent.java +++ b/base/src/main/java/bjc/utils/components/IDescribedComponent.java @@ -2,30 +2,32 @@ package bjc.utils.components; /** * Represents a optional component that has status information associated with - * it + * it. * * @author ben * */ public interface IDescribedComponent extends Comparable { /** - * Get the author of this component + * Get the author of this component. * - * Providing this is optional, with "Anonymous" as the default author + * Providing this is optional, with "Anonymous" as the default author. * - * @return The author of the component + * @return + * The author of the component. */ default String getAuthor() { return "Anonymous"; } /** - * Get the description of this component + * Get the description of this component. * * Providing this is optional, with the default being a note that no - * description was provided + * description was provided. * - * @return The description of the component + * @return + * The description of the component */ default String getDescription() { return "No description provided."; @@ -34,18 +36,20 @@ public interface IDescribedComponent extends Comparable { /** * Get the name of this component. * - * This is the only thing required of all components + * This is the only thing required of all components. * - * @return The name of the component + * @return + * The name of the component. */ String getName(); /** - * Get the version of this component + * Get the version of this component. * - * Providing this is optional, with "1" as the default version + * Providing this is optional, with "1" as the default version. * - * @return The version of this component + * @return + * The version of this component. */ default int getVersion() { return 1; @@ -61,4 +65,4 @@ public interface IDescribedComponent extends Comparable { return res; } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/BooleanToggle.java b/base/src/main/java/bjc/utils/data/BooleanToggle.java index 12e3b2e..280b90d 100644 --- a/base/src/main/java/bjc/utils/data/BooleanToggle.java +++ b/base/src/main/java/bjc/utils/data/BooleanToggle.java @@ -7,6 +7,7 @@ package bjc.utils.data; * */ public class BooleanToggle implements Toggle { + /* The contained value. */ private boolean val; /** @@ -20,7 +21,7 @@ public class BooleanToggle implements Toggle { * Create a flip-flop with the specified initial value. * * @param initial - * The initial value of the flip-flop. + * The initial value of the flip-flop. */ public BooleanToggle(final boolean initial) { val = initial; @@ -73,4 +74,4 @@ public class BooleanToggle implements Toggle { public String toString() { return String.format("BooleanToggle [val=%s]", val); } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/CircularIterator.java b/base/src/main/java/bjc/utils/data/CircularIterator.java index a708eba..60f815c 100644 --- a/base/src/main/java/bjc/utils/data/CircularIterator.java +++ b/base/src/main/java/bjc/utils/data/CircularIterator.java @@ -8,18 +8,14 @@ import java.util.Iterator; * @author EVE * * @param - * The type of the iterable. + * The type of the iterable. */ public class CircularIterator implements Iterator { - /* - * The iterable, and our current iterator into it. - */ + /* The iterable, and our current iterator into it. */ private Iterable source; private Iterator curr; - /* - * Our current element. - */ + /* Our current element. */ private E curElm; /* @@ -32,11 +28,11 @@ public class CircularIterator implements Iterator { * Create a new circular iterator. * * @param src - * The iterable to iterate from. + * The iterable to iterate from. * * @param circ - * Should we actually do circular iteration, or just - * repeat the terminal element? + * Should we actually do circular iteration, or just + * repeat the terminal element? */ public CircularIterator(final Iterable src, final boolean circ) { source = src; @@ -49,7 +45,7 @@ public class CircularIterator implements Iterator { * Create a new circular iterator that does actual circular iteration. * * @param src - * The iterable to iterate from. + * The iterable to iterate from. */ public CircularIterator(final Iterable src) { this(src, true); @@ -57,7 +53,7 @@ public class CircularIterator implements Iterator { @Override public boolean hasNext() { - // We always have something + /* We always have something. */ return true; } diff --git a/base/src/main/java/bjc/utils/data/Either.java b/base/src/main/java/bjc/utils/data/Either.java index 36b3324..2b64feb 100644 --- a/base/src/main/java/bjc/utils/data/Either.java +++ b/base/src/main/java/bjc/utils/data/Either.java @@ -4,52 +4,64 @@ import java.util.function.BiFunction; import java.util.function.Function; /** - * Represents a pair where only one side has a value + * Represents a pair where only one side has a value. * * @author ben + * * @param - * The type that could be on the left + * The type that could be on the left. + * * @param - * The type that could be on the right + * The type that could be on the right. * */ public class Either implements IPair { /** - * Create a new either with the left value occupied + * Create a new either with the left value occupied. * * @param - * The type of the left value + * The type of the left value. + * * @param - * The type of the empty right value + * The type of the empty right value. + * * @param left - * The value to put on the left - * @return An either with the left side occupied + * The value to put on the left. + * + * @return + * An either with the left side occupied. */ public static Either left(final LeftType left) { return new Either<>(left, null); } /** - * Create a new either with the right value occupied + * Create a new either with the right value occupied. * * @param - * The type of the empty left value + * The type of the empty left value. + * * @param - * The type of the right value + * The type of the right value. + * * @param right - * The value to put on the right - * @return An either with the right side occupied + * The value to put on the right. + * + * @return + * An either with the right side occupied. */ public static Either right(final RightType right) { return new Either<>(null, right); } + /* The left value of the either. */ private LeftType leftVal; - + /* The right value of the either. */ private RightType rightVal; - + /* Whether the left value is the one filled out. */ private boolean isLeft; + /* Create a new either with specifed values. */ private Either(final LeftType left, final RightType right) { if (left == null) { rightVal = right; @@ -93,19 +105,27 @@ public class Either implements IPair { final IPair otherPair, final BiFunction leftCombiner, final BiFunction rightCombiner) { - if (otherPair == null) + if (otherPair == null) { throw new NullPointerException("Other pair must not be null"); - else if (leftCombiner == null) + } else if (leftCombiner == null) { throw new NullPointerException("Left combiner must not be null"); - else if (rightCombiner == null) throw new NullPointerException("Right combiner must not be null"); + } else if (rightCombiner == null) { + throw new NullPointerException("Right combiner must not be null"); + } - if (isLeft) return otherPair.bind((otherLeft, otherRight) -> { - return new Either<>(leftCombiner.apply(leftVal, otherLeft), null); - }); + if (isLeft) { + return otherPair.bind((otherLeft, otherRight) -> { + CombinedLeft cLeft = leftCombiner.apply(leftVal, otherLeft); - return otherPair.bind((otherLeft, otherRight) -> { - return new Either<>(null, rightCombiner.apply(rightVal, otherRight)); - }); + return new Either<>(cLeft, null); + }); + } else { + return otherPair.bind((otherLeft, otherRight) -> { + CombinedRight cRight = rightCombiner.apply(rightVal, otherRight); + + return new Either<>(null, cRight); + }); + } } @Override @@ -170,4 +190,4 @@ public class Either implements IPair { public String toString() { return String.format("Either [leftVal='%s', rightVal='%s', isLeft=%s]", leftVal, rightVal, isLeft); } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/GeneratingIterator.java b/base/src/main/java/bjc/utils/data/GeneratingIterator.java index 9abca7c..92d10a5 100644 --- a/base/src/main/java/bjc/utils/data/GeneratingIterator.java +++ b/base/src/main/java/bjc/utils/data/GeneratingIterator.java @@ -10,27 +10,28 @@ import java.util.function.UnaryOperator; * @author bjculkin * * @param - * The type of element generated. + * The type of element generated. */ public class GeneratingIterator implements Iterator { + /* Our current state. */ private E state; - + /* The function to use to transition states. */ private UnaryOperator transtion; - + /* The predicate to indicate where to stop. */ private Predicate stpper; /** * Create a new generative iterator. * * @param initial - * The initial state of the generator. + * The initial state of the generator. * * @param transition - * The function to apply to the state. + * The function to apply to the state. * * @param stopper - * The predicate applied to the current state to - * determine when to stop. + * The predicate applied to the current state to + * determine when to stop. */ public GeneratingIterator(E initial, UnaryOperator transition, Predicate stopper) { state = initial; @@ -43,11 +44,16 @@ public class GeneratingIterator implements Iterator { return stpper.test(state); } + /* + * @NOTE + * As this currently is, it only works correctly assuming that + * next() is only called when hasNext() is true. Should we + * safeguard against people who are not doing the right thing? + */ @Override public E next() { state = transtion.apply(state); return state; } - } diff --git a/base/src/main/java/bjc/utils/data/IHolder.java b/base/src/main/java/bjc/utils/data/IHolder.java index ca0b2ba..0b0cfd2 100644 --- a/base/src/main/java/bjc/utils/data/IHolder.java +++ b/base/src/main/java/bjc/utils/data/IHolder.java @@ -16,25 +16,28 @@ import bjc.utils.funcdata.theory.Functor; * @author ben * * @param - * The type of value held + * The type of value held. */ public interface IHolder extends Functor { /** - * Bind a function across the value in this container + * Bind a function across the value in this container. * * @param - * The type of value in this container + * The type of value in this container. + * * @param binder - * The function to bind to the value - * @return A holder from binding the value + * The function to bind to the value. + * + * @return + * A holder from binding the value. */ public IHolder bind(Function> binder); /** - * Apply an action to the value + * Apply an action to the value. * * @param action - * The action to apply to the value + * The action to apply to the value. */ public default void doWith(final Consumer action) { transform(value -> { @@ -66,38 +69,44 @@ public interface IHolder extends Functor { } /** - * Lifts a function to bind over this holder + * Lifts a function to bind over this holder. * * @param - * The type of the functions return + * The type of the functions return. + * * @param func - * The function to lift over the holder - * @return The function lifted over the holder + * The function to lift over the holder. + * + * @return + * The function lifted over the holder. */ public Function> lift(Function func); /** - * Make this holder lazy + * Make this holder lazy. * - * @return A lazy version of this holder + * @return + * A lazy version of this holder. */ public default IHolder makeLazy() { return new WrappedLazy<>(this); } /** - * Make this holder a list + * Make this holder a list. * - * @return A list version of this holder + * @return + * A list version of this holder. */ public default IHolder makeList() { return new BoundListHolder<>(new FunctionalList<>(this)); } /** - * Make this holder optional + * Make this holder optional. * - * @return An optional version of this holder + * @return + * An optional version of this holder. */ public default IHolder makeOptional() { return new WrappedOption<>(this); @@ -107,22 +116,27 @@ public interface IHolder extends Functor { * Create a new holder with a mapped version of the value in this * holder. * - * Does not change the internal state of this holder + * Does not change the internal state of this holder. * * @param - * The type of the mapped value + * The type of the mapped value. + * * @param mapper - * The function to do mapping with - * @return A holder with the mapped value + * The function to do mapping with. + * + * @return + * A holder with the mapped value */ public IHolder map(Function mapper); /** - * Replace the held value with a new one + * Replace the held value with a new one. * * @param newValue - * The value to hold instead - * @return The holder itself + * The value to hold instead. + * + * @return + * The holder itself. */ public default IHolder replace(final ContainedType newValue) { return transform(oldValue -> { @@ -131,23 +145,28 @@ public interface IHolder extends Functor { } /** - * Transform the value held in this holder + * Transform the value held in this holder. * * @param transformer - * The function to transform the value with - * @return The holder itself, for easy chaining + * The function to transform the value with. + * + * @return + * The holder itself, for easy chaining. */ public IHolder transform(UnaryOperator transformer); /** * Unwrap the value contained in this holder so that it is no longer - * held + * held. * * @param - * The type of the unwrapped value + * The type of the unwrapped value. + * * @param unwrapper - * The function to use to unwrap the value - * @return The unwrapped held value + * The function to use to unwrap the value. + * + * @return + * The unwrapped held value. */ public UnwrappedType unwrap(Function unwrapper); } diff --git a/base/src/main/java/bjc/utils/data/IPair.java b/base/src/main/java/bjc/utils/data/IPair.java index db8a1cb..75b092d 100644 --- a/base/src/main/java/bjc/utils/data/IPair.java +++ b/base/src/main/java/bjc/utils/data/IPair.java @@ -7,64 +7,80 @@ import java.util.function.Function; import bjc.utils.funcdata.theory.Bifunctor; /** - * Represents a pair of values + * Represents a pair of values. * * @author ben + * * @param - * The type of the left side of the pair + * The type of the left side of the pair. + * * @param - * The type of the right side of the pair + * The type of the right side of the pair. * */ public interface IPair extends Bifunctor { /** - * Bind a function across the values in this pair + * Bind a function across the values in this pair. * * @param - * The type of the bound left + * The type of the bound left. + * * @param - * The type of the bound right + * The type of the bound right. + * * @param binder - * The function to bind with - * @return The bound pair + * The function to bind with. + * + * @return + * The bound pair. */ public IPair bind( BiFunction> binder); /** - * Bind a function to the left value in this pair + * Bind a function to the left value in this pair. * * @param - * The type of the bound value + * The type of the bound value. + * * @param leftBinder - * The function to use to bind - * @return A pair with the left type bound + * The function to use to bind. + * + * @return + * A pair with the left type bound. */ public IPair bindLeft( Function> leftBinder); /** - * Bind a function to the right value in this pair + * Bind a function to the right value in this pair. * * @param - * The type of the bound value + * The type of the bound value. + * * @param rightBinder - * The function to use to bind - * @return A pair with the right type bound + * The function to use to bind. + * + * @return + * A pair with the right type bound. */ public IPair bindRight( Function> rightBinder); /** - * Pairwise combine two pairs together + * Pairwise combine two pairs together. * * @param - * The left type of the other pair + * The left type of the other pair. + * * @param - * The right type of the other pair + * The right type of the other pair. + * * @param otherPair - * The pair to combine with - * @return The pairs, pairwise combined together + * The pair to combine with. + * + * @return + * The pairs, pairwise combined together. */ public default IPair, IPair> combine( final IPair otherPair) { @@ -72,21 +88,31 @@ public interface IPair extends Bifunctor - * The type of the left value of the other pair + * The type of the left value of the other pair. + * * @param - * The type of the right value of the other pair + * The type of the right value of the other pair. + * * @param - * The type of the left value of the combined pair + * The type of the left value of the combined pair. + * * @param - * The type of the right value of the combined pair + * The type of the right value of the combined pair. + * * @param otherPair - * The other pair to combine with + * The other pair to combine with. + * * @param leftCombiner + * The function to combine the left values with. + * * @param rightCombiner - * @return A pair with its values combined + * The function to combine the right values with. + * + * @return + * A pair with its values combined. */ public IPair combine( IPair otherPair, @@ -95,10 +121,10 @@ public interface IPair extends Bifunctor consumer) { merge((leftValue, rightValue) -> { @@ -109,8 +135,8 @@ public interface IPair extends Bifunctor LeftBifunctorMap fmapLeft( - final Function func) { + default LeftBifunctorMap + fmapLeft(final Function func) { return argumentPair -> { if (!(argumentPair instanceof IPair)) { final String msg = "This function can only be applied to instances of IPair"; @@ -125,8 +151,7 @@ public interface IPair extends Bifunctor RightBifunctorMap - + default RightBifunctorMap fmapRight(final Function func) { return argumentPair -> { if (!(argumentPair instanceof IPair)) { @@ -142,9 +167,10 @@ public interface IPair extends Bifunctor extends Bifunctor extends Bifunctor - * The new type of the left part of the pair + * The new type of the left part of the pair. + * * @param mapper - * The function to use to transform the left part of the - * pair - * @return The pair, with its left part transformed + * The function to use to transform the left part of the + * pair. + * + * @return + * The pair, with its left part transformed. */ public IPair mapLeft(Function mapper); /** - * Transform the value on the right side of the pair. Doesn't modify the - * pair + * Transform the value on the right side of the pair. + * + * Doesn't modify the pair. * * @param - * The new type of the right part of the pair + * The new type of the right part of the pair. + * * @param mapper - * The function to use to transform the right part of the - * pair - * @return The pair, with its right part transformed + * The function to use to transform the right part of the + * pair. + * + * @return + * The pair, with its right part transformed. */ public IPair mapRight(Function mapper); /** - * Merge the two values in this pair into a single value + * Merge the two values in this pair into a single value. * * @param - * The type of the single value + * The type of the single value. + * * @param merger - * The function to use for merging - * @return The pair, merged into a single value + * The function to use for merging. + * + * @return + * The pair, merged into a single value. */ public MergedType merge(BiFunction merger); } diff --git a/base/src/main/java/bjc/utils/data/ITree.java b/base/src/main/java/bjc/utils/data/ITree.java index ff374e8..450905b 100644 --- a/base/src/main/java/bjc/utils/data/ITree.java +++ b/base/src/main/java/bjc/utils/data/ITree.java @@ -14,7 +14,7 @@ import bjc.utils.functypes.ListFlattener; * @author ben * * @param - * The type of data contained in the tree nodes. + * The type of data contained in the tree nodes. * */ public interface ITree { @@ -22,7 +22,7 @@ public interface ITree { * Append a child to this node. * * @param child - * The child to append to this node. + * The child to append to this node. */ void addChild(ITree child); @@ -30,7 +30,7 @@ public interface ITree { * Prepend a child to this node. * * @param child - * The child to prepend to this node. + * The child to prepend to this node. */ void prependChild(ITree child); @@ -38,23 +38,24 @@ public interface ITree { * Collapse a tree into a single version. * * @param - * The intermediate type being folded. + * The intermediate type being folded. * * @param - * The type that is the end result. + * The type that is the end result. * * @param leafTransform - * The function to use to convert leaf values. + * The function to use to convert leaf values. * * @param nodeCollapser - * The function to use to convert internal nodes and - * their children. + * The function to use to convert internal nodes and + * their children. * * @param resultTransformer - * The function to use to convert a state to the returned - * version. + * The function to use to convert a state to the returned + * version. * - * @return The final transformed state. + * @return + * The final transformed state. */ ReturnedType collapse(Function leafTransform, Function> nodeCollapser, @@ -64,7 +65,7 @@ public interface ITree { * Execute a given action for each of this tree's children. * * @param action - * The action to execute for each child. + * The action to execute for each child. */ void doForChildren(Consumer> action); @@ -73,9 +74,10 @@ public interface ITree { * those trees into a single tree. * * @param mapper - * The function to use to map values into trees. + * The function to use to map values into trees. * - * @return A tree, with some nodes expanded into trees. + * @return + * A tree, with some nodes expanded into trees. */ default ITree flatMapTree(final Function> mapper) { return topDownTransform(dat -> TopDownTransformResult.PUSHDOWN, node -> { @@ -95,9 +97,10 @@ public interface ITree { * Get the specified child of this tree. * * @param childNo - * The number of the child to get. + * The number of the child to get. * - * @return The specified child of this tree. + * @return + * The specified child of this tree. */ default ITree getChild(final int childNo) { return transformChild(childNo, child -> child); @@ -106,14 +109,16 @@ public interface ITree { /** * Get a count of the number of direct children this node has. * - * @return The number of direct children this node has. + * @return + * The number of direct children this node has. */ int getChildrenCount(); /** * Get the data stored in this node. * - * @return The data stored in this node. + * @return + * The data stored in this node. */ default ContainedType getHead() { return transformHead(head -> head); @@ -123,27 +128,28 @@ public interface ITree { * Rebuild the tree with the same structure, but different nodes. * * @param - * The type of the new tree. + * The type of the new tree. * * @param leafTransformer - * The function to use to transform leaf tokens. + * The function to use to transform leaf tokens. * - * @param operatorTransformer - * The function to use to transform internal tokens. + * @param internalTransformer + * The function to use to transform internal tokens. * - * @return The tree, with the nodes changed. + * @return + * The tree, with the nodes changed. */ ITree rebuildTree(Function leafTransformer, - Function operatorTransformer); + Function internalTransformer); /** * Transform some of the nodes in this tree. * * @param nodePicker - * The predicate to use to pick nodes to transform. + * The predicate to use to pick nodes to transform. * * @param transformer - * The function to use to transform picked nodes. + * The function to use to transform picked nodes. */ void selectiveTransform(Predicate nodePicker, UnaryOperator transformer); @@ -151,12 +157,13 @@ public interface ITree { * Do a top-down transform of the tree. * * @param transformPicker - * The function to use to pick how to progress. + * The function to use to pick how to progress. * * @param transformer - * The function used to transform picked subtrees. + * The function used to transform picked subtrees. * - * @return The tree with the transform applied to picked subtrees. + * @return + * The tree with the transform applied to picked subtrees. */ ITree topDownTransform(Function transformPicker, UnaryOperator> transformer); @@ -165,19 +172,20 @@ public interface ITree { * Transform one of this nodes children. * * @param - * The type of the transformed value. + * The type of the transformed value. * * @param childNo - * The number of the child to transform. + * The number of the child to transform. * * @param transformer - * The function to use to transform the value. + * The function to use to transform the value. * - * @return The transformed value. + * @return + * The transformed value. * * @throws IllegalArgumentException - * if the childNo is out of bounds (0 <= childNo <= - * childCount()). + * if the childNo is out of bounds (0 <= childNo <= + * childCount()). */ TransformedType transformChild(int childNo, Function, TransformedType> transformer); @@ -186,12 +194,13 @@ public interface ITree { * Transform the value that is the head of this node. * * @param - * The type of the transformed value. + * The type of the transformed value. * * @param transformer - * The function to use to transform the value. + * The function to use to transform the value. * - * @return The transformed value. + * @return + * The transformed value. */ TransformedType transformHead(Function transformer); @@ -199,12 +208,13 @@ public interface ITree { * Transform the tree into a tree with a different type of token. * * @param - * The type of the new tree. + * The type of the new tree. * * @param transformer - * The function to use to transform tokens. + * The function to use to transform tokens. * - * @return A tree with the token types transformed. + * @return + * A tree with the token types transformed. */ default ITree transformTree(final Function transformer) { return rebuildTree(transformer, transformer); @@ -214,10 +224,10 @@ public interface ITree { * Perform an action on each part of the tree. * * @param linearizationMethod - * The way to traverse the tree. + * The way to traverse the tree. * * @param action - * The action to perform on each tree node. + * The action to perform on each tree node. */ void traverse(TreeLinearizationMethod linearizationMethod, Consumer action); @@ -225,10 +235,11 @@ public interface ITree { * Find the farthest to right child that satisfies the given predicate. * * @param childPred - * The predicate to satisfy. + * The predicate to satisfy. * - * @return The index of the right-most child that satisfies the - * predicate, or -1 if one doesn't exist. + * @return + * The index of the right-most child that satisfies the predicate, + * or -1 if one doesn't exist. */ int revFind(Predicate> childPred); } diff --git a/base/src/main/java/bjc/utils/data/Identity.java b/base/src/main/java/bjc/utils/data/Identity.java index a8c8d70..3acb5aa 100644 --- a/base/src/main/java/bjc/utils/data/Identity.java +++ b/base/src/main/java/bjc/utils/data/Identity.java @@ -4,33 +4,27 @@ import java.util.function.Function; import java.util.function.UnaryOperator; /** - * @author ben - * - * @param - */ -/** - * Simple implementation of IHolder that has no hidden behavior + * Simple implementation of IHolder that has no hidden behavior. * * @author ben * * @param - * The type contained in the holder + * The type contained in the holder. */ public class Identity implements IHolder { + /* The held value. */ private ContainedType heldValue; - /** - * Create a holder holding null - */ + /** Create a holder holding null */ public Identity() { heldValue = null; } /** - * Create a holder holding the specified value + * Create a holder holding the specified value. * * @param value - * The value to hold + * The value to hold. */ public Identity(final ContainedType value) { heldValue = value; @@ -99,9 +93,10 @@ public class Identity implements IHolder { * Create a new identity container. * * @param val - * The contained value. + * The contained value. * - * @return A new identity container. + * @return + * A new identity container. */ public static Identity id(final ContainedType val) { return new Identity<>(val); @@ -110,9 +105,10 @@ public class Identity implements IHolder { /** * Create a new empty identity container. * - * @return A new empty identity container. + * @return + * A new empty identity container. */ public static Identity id() { return new Identity<>(); } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/Lazy.java b/base/src/main/java/bjc/utils/data/Lazy.java index ca41b62..fcebb70 100644 --- a/base/src/main/java/bjc/utils/data/Lazy.java +++ b/base/src/main/java/bjc/utils/data/Lazy.java @@ -10,26 +10,29 @@ import bjc.utils.funcdata.IList; /** * A holder that holds a means to create a value, but doesn't actually compute - * the value until it's needed + * the value until it's needed. * * @author ben * * @param + * The type of the value being held. */ public class Lazy implements IHolder { + /* The supplier of the type. */ private Supplier valueSupplier; - - private IList> actions = new FunctionalList<>(); - + /* The actual type value. */ + private ContainedType heldValue; + /* Whether the value has been created. */ private boolean valueMaterialized; - private ContainedType heldValue; + /* The list of pending actions on the value. */ + private IList> actions = new FunctionalList<>(); /** - * Create a new lazy value from the specified seed value + * Create a new lazy value from the specified seed value. * * @param value - * The seed value to use + * The seed value to use. */ public Lazy(final ContainedType value) { heldValue = value; @@ -38,10 +41,10 @@ public class Lazy implements IHolder { } /** - * Create a new lazy value from the specified value source + * Create a new lazy value from the specified value source. * * @param supp - * The source of a value to use + * The source of a value to use. */ public Lazy(final Supplier supp) { valueSupplier = new SingleSupplier<>(supp); @@ -49,6 +52,7 @@ public class Lazy implements IHolder { valueMaterialized = false; } + /* Create a new value from a supplier and a list of actions. */ private Lazy(final Supplier supp, final IList> pendingActions) { valueSupplier = supp; @@ -171,9 +175,10 @@ public class Lazy implements IHolder { * Create a new lazy container with an already present value. * * @param val - * The value for the lazy container. + * The value for the lazy container. * - * @return A new lazy container holding that value. + * @return + * A new lazy container holding that value. */ public static Lazy lazy(final ContainedType val) { return new Lazy<>(val); @@ -183,10 +188,11 @@ public class Lazy implements IHolder { * Create a new lazy container with a suspended value. * * @param supp - * The suspended value for the lazy container. + * The suspended value for the lazy container. * - * @return A new lazy container that will un-suspend the value when - * necessary. + * @return + * A new lazy container that will un-suspend the value when + * necessary. */ public static Lazy lazy(final Supplier supp) { return new Lazy<>(supp); diff --git a/base/src/main/java/bjc/utils/data/LazyPair.java b/base/src/main/java/bjc/utils/data/LazyPair.java index 5cb85f3..548a09e 100644 --- a/base/src/main/java/bjc/utils/data/LazyPair.java +++ b/base/src/main/java/bjc/utils/data/LazyPair.java @@ -8,56 +8,63 @@ import bjc.utils.data.internals.BoundLazyPair; import bjc.utils.data.internals.HalfBoundLazyPair; /** - * A lazy implementation of a pair + * A lazy implementation of a pair. * * @author ben * * @param - * The type on the left side of the pair - * @param - * The type on the right side of the pair + * The type on the left side of the pair. * + * @param + * The type on the right side of the pair. */ public class LazyPair implements IPair { - private LeftType leftValue; - private RightType rightValue; - - private Supplier leftSupplier; - private Supplier rightSupplier; - + /* The supplier for the left value. */ + private Supplier leftSupplier; + /* The left value. */ + private LeftType leftValue; + /* Whether the left value has been created. */ private boolean leftMaterialized; + + /* The supplier for the right value. */ + private Supplier rightSupplier; + /* The right value. */ + private RightType rightValue; + /* Whether the right value has been created. */ private boolean rightMaterialized; /** - * Create a new lazy pair, using the set values + * Create a new lazy pair, using the set values. * * @param leftVal - * The value for the left side of the pair + * The value for the left side of the pair. + * * @param rightVal - * The value for the right side of the pair + * The value for the right side of the pair. */ public LazyPair(final LeftType leftVal, final RightType rightVal) { - leftValue = leftVal; + leftValue = leftVal; rightValue = rightVal; - leftMaterialized = true; + leftMaterialized = true; rightMaterialized = true; } /** - * Create a new lazy pair from the given value sources + * Create a new lazy pair from the given value sources. * * @param leftSupp - * The source for a value on the left side of the pair + * The source for a value on the left side of the pair. + * * @param rightSupp - * The source for a value on the right side of the pair + * The source for a value on the right side of the pair. */ public LazyPair(final Supplier leftSupp, final Supplier rightSupp) { - // Use single suppliers to catch double-instantiation bugs - leftSupplier = new SingleSupplier<>(leftSupp); + /* Use single suppliers to catch double-instantiation bugs. */ + leftSupplier = new SingleSupplier<>(leftSupp); rightSupplier = new SingleSupplier<>(rightSupp); - leftMaterialized = false; + leftMaterialized = false; rightMaterialized = false; } @@ -98,7 +105,7 @@ public class LazyPair implements IPair final BiFunction rightCombiner) { return otherPair.bind((otherLeft, otherRight) -> { return bind((leftVal, rightVal) -> { - final CombinedLeft left = leftCombiner.apply(leftVal, otherLeft); + final CombinedLeft left = leftCombiner.apply(leftVal, otherLeft); final CombinedRight right = rightCombiner.apply(rightVal, otherRight); return new LazyPair<>(left, right); diff --git a/base/src/main/java/bjc/utils/data/ListHolder.java b/base/src/main/java/bjc/utils/data/ListHolder.java index 142057c..4564466 100644 --- a/base/src/main/java/bjc/utils/data/ListHolder.java +++ b/base/src/main/java/bjc/utils/data/ListHolder.java @@ -8,21 +8,21 @@ import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.IList; /** - * A holder that represents a set of non-deterministic computations + * A holder that represents a set of non-deterministic computations. * * @author ben * * @param - * The type of contained value + * The type of contained value. */ public class ListHolder implements IHolder { private IList heldValues; /** - * Create a new list holder + * Create a new list holder. * * @param values - * The possible values for the computation + * The possible values for the computation. */ @SafeVarargs public ListHolder(final ContainedType... values) { @@ -35,6 +35,7 @@ public class ListHolder implements IHolder { } } + /* Create a new holder with values. */ private ListHolder(final IList toHold) { heldValues = toHold; } diff --git a/base/src/main/java/bjc/utils/data/Option.java b/base/src/main/java/bjc/utils/data/Option.java index 37e0cde..6eae21f 100644 --- a/base/src/main/java/bjc/utils/data/Option.java +++ b/base/src/main/java/bjc/utils/data/Option.java @@ -4,21 +4,21 @@ import java.util.function.Function; import java.util.function.UnaryOperator; /** - * A holder that may or may not contain a value + * A holder that may or may not contain a value. * * @author ben * * @param - * The type of the value that may or may not be held + * The type of the value that may or may not be held. */ public class Option implements IHolder { private ContainedType held; /** - * Create a new optional, using the given initial value + * Create a new optional, using the given initial value. * * @param seed - * The initial value for the optional + * The initial value for the optional. */ public Option(final ContainedType seed) { held = seed; diff --git a/base/src/main/java/bjc/utils/data/Pair.java b/base/src/main/java/bjc/utils/data/Pair.java index e6796ba..fb81e17 100644 --- a/base/src/main/java/bjc/utils/data/Pair.java +++ b/base/src/main/java/bjc/utils/data/Pair.java @@ -9,34 +9,33 @@ import java.util.function.Function; * @author ben * * @param - * The type of the left value + * The type of the left value. + * * @param - * The type of the right value + * The type of the right value. */ public class Pair implements IPair { - // The left value + /* The left value. */ private LeftType leftValue; - - // The right value + /* The right value. */ private RightType rightValue; - /** - * Create a new pair with both sides set to null - */ + /** Create a new pair with both sides set to null. */ public Pair() { } /** - * Create a new pair with both sides set to the specified values + * Create a new pair with both sides set to the specified values. * * @param left - * The value of the left side + * The value of the left side. + * * @param right - * The value of the right side + * The value of the right side. */ public Pair(final LeftType left, final RightType right) { - leftValue = left; + leftValue = left; rightValue = right; } @@ -70,7 +69,7 @@ public class Pair implements IPair { final BiFunction leftCombiner, final BiFunction rightCombiner) { return otherPair.bind((otherLeft, otherRight) -> { - final CombinedLeft left = leftCombiner.apply(leftValue, otherLeft); + final CombinedLeft left = leftCombiner.apply(leftValue, otherLeft); final CombinedRight right = rightCombiner.apply(rightValue, otherRight); return new Pair<>(left, right); diff --git a/base/src/main/java/bjc/utils/data/SingleIterator.java b/base/src/main/java/bjc/utils/data/SingleIterator.java index 4069c3f..1241a68 100644 --- a/base/src/main/java/bjc/utils/data/SingleIterator.java +++ b/base/src/main/java/bjc/utils/data/SingleIterator.java @@ -8,18 +8,19 @@ import java.util.Iterator; * @author EVE * * @param - * The type of the item. + * The type of the item. */ public class SingleIterator implements Iterator { + /* The item being held. */ private final T itm; - + /* Whether we've yielded the item yet. */ private boolean yielded; /** * Create a iterator that yields a single item. * * @param item - * The item to yield. + * The item to yield. */ public SingleIterator(final T item) { itm = item; diff --git a/base/src/main/java/bjc/utils/data/SingleSupplier.java b/base/src/main/java/bjc/utils/data/SingleSupplier.java index c675ebf..60f9136 100644 --- a/base/src/main/java/bjc/utils/data/SingleSupplier.java +++ b/base/src/main/java/bjc/utils/data/SingleSupplier.java @@ -10,28 +10,33 @@ import java.util.function.Supplier; * @author ben * * @param - * The supplied type + * The supplied type */ public class SingleSupplier implements Supplier { + /* The next supplier ID. */ private static long nextID = 0; - + /* The supplier to yield from. */ private final Supplier source; - + /* Whether this value has been retrieved yet. */ private boolean gotten; - + /* The ID of this supplier. */ private final long id; /* - * This is bad practice, but I want to know where the single - * instantiation was, in case of duplicate initiations. + * The place where the supplier was instantiated. + * + * @NOTE + * This is both slow to create, and generally bad practice to keep + * exceptions around without throwing them. However, it is very + * useful to find where the first instantiation was. */ private Exception instSite; /** - * Create a new single supplier from an existing value + * Create a new single supplier from an existing value. * * @param supp - * The supplier to give a single value from + * The supplier to give a single value from. */ public SingleSupplier(final Supplier supp) { source = supp; diff --git a/base/src/main/java/bjc/utils/data/Toggle.java b/base/src/main/java/bjc/utils/data/Toggle.java index 1e10dae..a1467e4 100644 --- a/base/src/main/java/bjc/utils/data/Toggle.java +++ b/base/src/main/java/bjc/utils/data/Toggle.java @@ -6,21 +6,23 @@ package bjc.utils.data; * @author EVE * * @param - * The value stored in the toggle. + * The value stored in the toggle. */ public interface Toggle { /** * Retrieve the currently-aligned value of this toggle, and swap the - * alignment. + * value to the new one. * - * @return The previously-aligned value. + * @return + * The previously-aligned value. */ E get(); /** * Retrieve the currently-aligned value without altering the alignment. * - * @return The currently-aligned value. + * @return + * The currently-aligned value. */ E peek(); @@ -28,8 +30,7 @@ public interface Toggle { * Change the alignment of the toggle. * * @param isLeft - * Whether the toggle should be left-aligned or not. + * Whether the toggle should be left-aligned or not. */ void set(boolean isLeft); - -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/TopDownTransformIterator.java b/base/src/main/java/bjc/utils/data/TopDownTransformIterator.java index 1b87e52..c6b7d31 100644 --- a/base/src/main/java/bjc/utils/data/TopDownTransformIterator.java +++ b/base/src/main/java/bjc/utils/data/TopDownTransformIterator.java @@ -11,7 +11,9 @@ import java.util.function.Consumer; import java.util.function.Function; /* - * FIXME something is broken in here. fix it. + * @TODO 10/11/17 Ben Culkin :TopDownStep + * Figure out what is broken with this, and fix it so that step-wise + * iteration works correctly. */ public class TopDownTransformIterator implements Iterator> { private final Function picker; diff --git a/base/src/main/java/bjc/utils/data/TopDownTransformResult.java b/base/src/main/java/bjc/utils/data/TopDownTransformResult.java index ed41eae..3907df2 100644 --- a/base/src/main/java/bjc/utils/data/TopDownTransformResult.java +++ b/base/src/main/java/bjc/utils/data/TopDownTransformResult.java @@ -1,34 +1,22 @@ package bjc.utils.data; /** - * Represents the results for doing a top-down transform of a tree + * Represents the results for doing a top-down transform of a tree. * * @author ben * */ public enum TopDownTransformResult { - /** - * Do not do anything to this node, and ignore its children - */ + /** Do not do anything to this node, and ignore its children. */ SKIP, - /** - * Transform this node, and don't touch its children - */ + /** Transform this node, and don't touch its children. */ TRANSFORM, - /** - * Transform this node, then do a top-down transform on the result - */ + /** Transform this node, then recursively transform the result. */ RTRANSFORM, - /** - * Ignore this node, and traverse its children - */ + /** Ignore this node, and traverse its children. */ PASSTHROUGH, - /** - * Traverse the nodes of this children, then transform it - */ + /** Traverse the nodes of this children, then transform it. */ PUSHDOWN, - /** - * Transform this node, then traverse its children - */ + /** Transform this node, then traverse its children. */ PULLUP; } diff --git a/base/src/main/java/bjc/utils/data/TransformIterator.java b/base/src/main/java/bjc/utils/data/TransformIterator.java index 50f28b1..5a6ac85 100644 --- a/base/src/main/java/bjc/utils/data/TransformIterator.java +++ b/base/src/main/java/bjc/utils/data/TransformIterator.java @@ -9,24 +9,25 @@ import java.util.function.Function; * @author EVE * * @param - * The source iterator type. + * The source iterator type. * * @param - * The destination iterator type. + * The destination iterator type. */ public class TransformIterator implements Iterator { + /* Our source of values. */ private final Iterator source; - + /* Transform function. */ private final Function transform; /** * Create a new transform iterator. * * @param source - * The source iterator to use. + * The source iterator to use. * * @param transform - * The transform to apply. + * The transform to apply. */ public TransformIterator(final Iterator source, final Function transform) { this.source = source; @@ -42,5 +43,4 @@ public class TransformIterator implements Iterator { public D next() { return transform.apply(source.next()); } - } diff --git a/base/src/main/java/bjc/utils/data/Tree.java b/base/src/main/java/bjc/utils/data/Tree.java index a52f699..386153b 100644 --- a/base/src/main/java/bjc/utils/data/Tree.java +++ b/base/src/main/java/bjc/utils/data/Tree.java @@ -16,22 +16,35 @@ import bjc.utils.functypes.ListFlattener; * @author ben * * @param + * The type contained in the tree. */ public class Tree implements ITree { + /* The data/label for this node. */ private ContainedType data; - private IList> children; - private boolean hasChildren; - private int childCount = 0; + /* The children of this node. */ + private IList> children; - private int ID; - private static int nextID = 0; + /* Whether this node has children. */ + /* @NOTE + * Why have both this boolean and childCount? Why not just do a + * childCount == 0 + * whenever you'd check hasChildren? + */ + private boolean hasChildren; + /* The number of children this node has. */ + private int childCount = 0; + + /* The ID of this node. */ + private int ID; + /* The next ID to assign to a node. */ + private static int nextID = 0; /** * Create a new leaf node in a tree. * * @param leaf - * The data to store as a leaf node. + * The data to store as a leaf node. */ public Tree(final ContainedType leaf) { data = leaf; @@ -45,10 +58,10 @@ public class Tree implements ITree { * Create a new tree node with the specified children. * * @param leaf - * The data to hold in this node. + * The data to hold in this node. * * @param childrn - * A list of children for this node. + * A list of children for this node. */ public Tree(final ContainedType leaf, final IList> childrn) { this(leaf); @@ -64,10 +77,10 @@ public class Tree implements ITree { * Create a new tree node with the specified children. * * @param leaf - * The data to hold in this node. + * The data to hold in this node. * * @param childrn - * A list of children for this node. + * A list of children for this node. */ @SafeVarargs public Tree(final ContainedType leaf, final ITree... childrn) { @@ -126,15 +139,15 @@ public class Tree implements ITree { @Override public int revFind(final Predicate> childPred) { - if (childCount == 0) + if (childCount == 0) { return -1; - else { + } else { for (int i = childCount - 1; i >= 0; i--) { if (childPred.test(getChild(i))) return i; } - } - return -1; + return -1; + } } @Override @@ -188,7 +201,7 @@ public class Tree implements ITree { final IList> mappedChildren = children .map(child -> child.flatMapTree(mapper)); - mappedChildren.forEach(child -> flatMappedData.addChild(child)); + mappedChildren.forEach(flatMappedData::addChild); return flatMappedData; } @@ -196,6 +209,14 @@ public class Tree implements ITree { return mapper.apply(data); } + /* + * Do a collapse of this tree. + * + * @NOTE + * Why is this protected? I can't see any good reason someone'd + * want to override it. + */ + protected NewType internalCollapse(final Function leafTransform, final Function> nodeCollapser) { if (hasChildren) { @@ -236,7 +257,9 @@ public class Tree implements ITree { builder.append(">\t"); } - builder.append("Unknown node\n"); + builder.append("Unknown node of type "); + builder.append(child.getClass().getName()); + builder.append("\n"); } }); } @@ -250,7 +273,8 @@ public class Tree implements ITree { return child.rebuildTree(leafTransformer, operatorTransformer); }); - return new Tree<>(operatorTransformer.apply(data), mappedChildren); + final MappedType mapData = operatorTransformer.apply(data); + return new Tree<>(mapData, mappedChildren); } return new Tree<>(leafTransformer.apply(data)); @@ -318,7 +342,7 @@ public class Tree implements ITree { return result; default: - final String msg = String.format("Recieved unknown transform result %s", transformResult); + final String msg = String.format("Recieved unknown transform result type %s", transformResult); throw new IllegalArgumentException(msg); } @@ -362,6 +386,7 @@ public class Tree implements ITree { internalToString(builder, 1, true); + /* Delete a trailing nl. */ builder.deleteCharAt(builder.length() - 1); return builder.toString(); @@ -387,4 +412,4 @@ public class Tree implements ITree { return true; } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/ValueToggle.java b/base/src/main/java/bjc/utils/data/ValueToggle.java index 9193896..54c7a57 100644 --- a/base/src/main/java/bjc/utils/data/ValueToggle.java +++ b/base/src/main/java/bjc/utils/data/ValueToggle.java @@ -6,12 +6,14 @@ package bjc.utils.data; * @author EVE * * @param - * The type of value to toggle between. + * The type of value to toggle between. */ public class ValueToggle implements Toggle { + /* Our left value. */ private final E lft; + /* Our right value. */ private final E rght; - + /* Our alignment. */ private final BooleanToggle alignment; /** @@ -20,10 +22,10 @@ public class ValueToggle implements Toggle { * All toggles start right-aligned. * * @param left - * The value when the toggle is left-aligned. + * The value when the toggle is left-aligned. * * @param right - * The value when the toggle is right-aligned. + * The value when the toggle is right-aligned. */ public ValueToggle(final E left, final E right) { lft = left; @@ -35,16 +37,20 @@ public class ValueToggle implements Toggle { @Override public E get() { - if (alignment.get()) + if (alignment.get()) { return lft; - else return rght; + } else { + return rght; + } } @Override public E peek() { - if (alignment.peek()) + if (alignment.peek()) { return lft; - else return rght; + } else { + return rght; + } } @Override diff --git a/base/src/main/java/bjc/utils/data/internals/BoundLazy.java b/base/src/main/java/bjc/utils/data/internals/BoundLazy.java index f71d32b..b160c0c 100644 --- a/base/src/main/java/bjc/utils/data/internals/BoundLazy.java +++ b/base/src/main/java/bjc/utils/data/internals/BoundLazy.java @@ -9,37 +9,35 @@ import bjc.utils.data.Lazy; import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.IList; -/* - * Implements a lazy holder that has been bound +/** + * Implements a lazy holder that has been bound. + * + * @author Ben Culkin */ public class BoundLazy implements IHolder { - /* - * The old value - */ + /* The old value. */ private final Supplier> oldSupplier; - /* - * The function to use to transform the old value into a new value - */ + /* The function to use to transform the old value into a new value. */ private final Function> binder; - /* - * The bound value being held - */ + /* The bound value being held. */ private IHolder boundHolder; - /* - * Whether the bound value has been actualized or not - */ + /* Whether the bound value has been actualized or not. */ private boolean holderBound; - /* - * Transformations currently pending on the bound value - */ + /* Transformations currently pending on the bound value. */ private final IList> actions = new FunctionalList<>(); - /* - * Create a new bound lazy value + /** + * Create a new bound lazy value. + * + * @param supp + * The supplier of the old value. + * + * @param binder + * The function to use to bind the old value to the new one. */ public BoundLazy(final Supplier> supp, final Function> binder) { @@ -51,28 +49,20 @@ public class BoundLazy implements IHolder IHolder bind(final Function> bindr) { if (bindr == null) throw new NullPointerException("Binder must not be null"); - /* - * Prepare a list of pending actions - */ + /* Prepare a list of pending actions. */ final IList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); - /* - * Create the new supplier of a value - */ + /* Create the new supplier of a value. */ final Supplier> typeSupplier = () -> { IHolder oldHolder = boundHolder; - /* - * Bind the value if it hasn't been bound before - */ + /* Bind the value if it hasn't been bound before. */ if (!holderBound) { oldHolder = oldSupplier.get().unwrap(binder); } - /* - * Apply all the pending actions - */ + /* Apply all the pending actions. */ return pendingActions.reduceAux(oldHolder, (action, state) -> { return state.transform(action); }, (value) -> value); @@ -95,19 +85,20 @@ public class BoundLazy implements IHolder IHolder map(final Function mapper) { if (mapper == null) throw new NullPointerException("Mapper must not be null"); - // Prepare a list of pending actions + /* Prepare a list of pending actions. */ final IList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); - // Prepare the new supplier + /* Prepare the new supplier. */ final Supplier typeSupplier = () -> { IHolder oldHolder = boundHolder; - // Bound the value if it hasn't been bound + /* Bound the value if it hasn't been bound. */ if (!holderBound) { oldHolder = oldSupplier.get().unwrap(binder); } + /* Apply pending actions. */ return pendingActions.reduceAux(oldHolder.getValue(), (action, state) -> { return action.apply(state); }, (value) -> mapper.apply(value)); @@ -142,4 +133,4 @@ public class BoundLazy implements IHolder implements IPair { - /* - * The supplier of the left value - */ + /* The supplier of the left value. */ private final Supplier leftSupplier; - /* - * The supplier of the right value - */ + /* The supplier of the right value. */ private final Supplier rightSupplier; - /* - * The binder to transform values - */ + /* The binder to transform values. */ private final BiFunction> binder; - /* - * The bound pair - */ + /* The bound pair. */ private IPair boundPair; - /* - * Whether the pair has been bound yet - */ + /* Whether the pair has been bound yet. */ private boolean pairBound; + /** + * Create a new bound lazy pair. + * + * @param leftSupp + * The supplier for the left value. + * + * @param rightSupp + * The supplier for the right value. + * + * @param bindr + * The function to use to bind the left and right into a new pair. + */ public BoundLazyPair(final Supplier leftSupp, final Supplier rightSupp, final BiFunction> bindr) { leftSupplier = leftSupp; @@ -50,10 +54,14 @@ public class BoundLazyPair implements IPai if (bindr == null) throw new NullPointerException("Binder must not be null"); final IHolder> newPair = new Identity<>(boundPair); - final IHolder newPairMade = new Identity<>(pairBound); + final IHolder newPairMade = new Identity<>(pairBound); final Supplier leftSupp = () -> { if (!newPairMade.getValue()) { + /* + * If the pair hasn't been bound before, bind + * it. + */ newPair.replace(binder.apply(leftSupplier.get(), rightSupplier.get())); newPairMade.replace(true); @@ -64,6 +72,10 @@ public class BoundLazyPair implements IPai final Supplier rightSupp = () -> { if (!newPairMade.getValue()) { + /* + * If the pair hasn't been bound before, bind + * it. + */ newPair.replace(binder.apply(leftSupplier.get(), rightSupplier.get())); newPairMade.replace(true); @@ -84,6 +96,10 @@ public class BoundLazyPair implements IPai IPair newPair = boundPair; if (!pairBound) { + /* + * If the pair hasn't been bound before, bind + * it. + */ newPair = binder.apply(leftSupplier.get(), rightSupplier.get()); } @@ -102,6 +118,10 @@ public class BoundLazyPair implements IPai IPair newPair = boundPair; if (!pairBound) { + /* + * If the pair hasn't been bound before, bind + * it. + */ newPair = binder.apply(leftSupplier.get(), rightSupplier.get()); } @@ -116,16 +136,20 @@ public class BoundLazyPair implements IPai final IPair otherPair, final BiFunction leftCombiner, final BiFunction rightCombiner) { - if (otherPair == null) + if (otherPair == null) { throw new NullPointerException("Other pair must not be null"); - else if (leftCombiner == null) + } else if (leftCombiner == null) { throw new NullPointerException("Left combiner must not be null"); - else if (rightCombiner == null) throw new NullPointerException("Right combiner must not be null"); + } else if (rightCombiner == null) { + throw new NullPointerException("Right combiner must not be null"); + } return otherPair.bind((otherLeft, otherRight) -> { return bind((leftVal, rightVal) -> { - return new LazyPair<>(leftCombiner.apply(leftVal, otherLeft), - rightCombiner.apply(rightVal, otherRight)); + CombinedLeft cLeft = leftCombiner.apply(leftVal, otherLeft); + CombinedRight cRight = rightCombiner.apply(rightVal, otherRight); + + return new LazyPair<>(cLeft, cRight); }); }); } @@ -182,6 +206,9 @@ public class BoundLazyPair implements IPai if (merger == null) throw new NullPointerException("Merger must not be null"); if (!pairBound) { + /* + * If the pair isn't bound yet, bind it. + */ boundPair = binder.apply(leftSupplier.get(), rightSupplier.get()); pairBound = true; @@ -196,4 +223,4 @@ public class BoundLazyPair implements IPai return "(un-materialized)"; } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/internals/BoundListHolder.java b/base/src/main/java/bjc/utils/data/internals/BoundListHolder.java index f3799fd..8f9e87f 100644 --- a/base/src/main/java/bjc/utils/data/internals/BoundListHolder.java +++ b/base/src/main/java/bjc/utils/data/internals/BoundListHolder.java @@ -7,12 +7,21 @@ import bjc.utils.data.IHolder; import bjc.utils.data.ListHolder; import bjc.utils.funcdata.IList; -/* - * Holds a list, converted into a holder +/** + * Holds a list, converted into a holder. + * + * @author Ben Culkin */ public class BoundListHolder implements IHolder { + /* The list of contained holders. */ private final IList> heldHolders; + /** + * Create a new list of holders. + * + * @param toHold + * The list of holders to, well, hold. + */ public BoundListHolder(final IList> toHold) { heldHolders = toHold; } @@ -63,6 +72,10 @@ public class BoundListHolder implements IHolder { public UnwrappedType unwrap(final Function unwrapper) { if (unwrapper == null) throw new NullPointerException("Unwrapper must not be null"); + /* + * @NOTE + * Is there another way we could want to do this? + */ return heldHolders.randItem().unwrap(unwrapper); } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java b/base/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java index 8cac38b..c3606ef 100644 --- a/base/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java +++ b/base/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java @@ -10,16 +10,39 @@ import bjc.utils.data.Identity; import bjc.utils.data.LazyPair; /* - * A lazy pair, with only one side bound + * @NOTE + * I am not convinced that this code works correctly. Tests should be + * written to make sure things only ever get instantiated once. + * + * Namely, my main concern is to whether the places that bind the pair + * without setting pairBound are doing the right thing. + */ +/** + * A lazy pair, with only one side bound. + * + * @author Ben Culkin */ public class HalfBoundLazyPair implements IPair { + /* The supplier of the old value. */ private final Supplier oldSupplier; + /* The function to transform the old value into a new pair. */ private final Function> binder; + /* The new bound pair. */ private IPair boundPair; + /* Has the pair been bound yet or not? */ private boolean pairBound; + /** + * Create a new half-bound lazy pair. + * + * @param oldSupp + * The supplier of the old value. + * + * @param bindr + * The function to use to create the pair from the old value. + */ public HalfBoundLazyPair(final Supplier oldSupp, final Function> bindr) { oldSupplier = oldSupp; @@ -34,6 +57,7 @@ public class HalfBoundLazyPair implements IPair leftSupp = () -> { if (!newPairMade.getValue()) { + /* Bind the pair if it hasn't been bound yet. */ newPair.replace(binder.apply(oldSupplier.get())); newPairMade.replace(true); } @@ -43,6 +67,7 @@ public class HalfBoundLazyPair implements IPair rightSupp = () -> { if (!newPairMade.getValue()) { + /* Bind the pair if it hasn't been bound yet. */ newPair.replace(binder.apply(oldSupplier.get())); newPairMade.replace(true); } @@ -92,8 +117,10 @@ public class HalfBoundLazyPair implements IPair rightCombiner) { return otherPair.bind((otherLeft, otherRight) -> { return bind((leftVal, rightVal) -> { - return new LazyPair<>(leftCombiner.apply(leftVal, otherLeft), - rightCombiner.apply(rightVal, otherRight)); + CombinedLeft cLeft = leftCombiner.apply(leftVal, otherLeft); + CombinedRight cRight = rightCombiner.apply(rightVal, otherRight); + + return new LazyPair<>(cLeft, cRight); }); }); } @@ -146,4 +173,4 @@ public class HalfBoundLazyPair implements IPair implements IHolder { + /* Held value. */ private final IHolder> held; + /** + * Create a new wrapped lazy value. + * + * @param wrappedHolder + * The holder to make lazy. + */ public WrappedLazy(final IHolder wrappedHolder) { held = new Lazy<>(wrappedHolder); } - // This has an extra parameter, because otherwise it erases to the same - // as the public one + /* + * This has an extra parameter, because otherwise it erases to the same + * as the public one. + * + * This is a case where reified generics would be useful, because then + * the compiler could know which one we meant without the dummy + * parameter. + */ private WrappedLazy(final IHolder> wrappedHolder, final boolean dummy) { held = wrappedHolder; } diff --git a/base/src/main/java/bjc/utils/data/internals/WrappedOption.java b/base/src/main/java/bjc/utils/data/internals/WrappedOption.java index 512c699..872295f 100644 --- a/base/src/main/java/bjc/utils/data/internals/WrappedOption.java +++ b/base/src/main/java/bjc/utils/data/internals/WrappedOption.java @@ -6,13 +6,30 @@ import java.util.function.UnaryOperator; import bjc.utils.data.IHolder; import bjc.utils.data.Option; +/** + * A wrapped optional value. + * + * @author Ben Culkin. + */ public class WrappedOption implements IHolder { + /* The held value. */ private final IHolder> held; + /** + * Create a new wrapped option. + * + * @param seedValue + * The value to wrap. + */ public WrappedOption(final IHolder seedValue) { held = new Option<>(seedValue); } + /* + * The dummy parameter is to ensure the compiler can pick the right + * method, because without this method erases to the same type as the + * public one. + */ private WrappedOption(final IHolder> toHold, final boolean dummy) { held = toHold; } diff --git a/base/src/main/java/bjc/utils/esodata/AbbrevMap.java b/base/src/main/java/bjc/utils/esodata/AbbrevMap.java index 0d54471..5aa44fc 100644 --- a/base/src/main/java/bjc/utils/esodata/AbbrevMap.java +++ b/base/src/main/java/bjc/utils/esodata/AbbrevMap.java @@ -14,37 +14,28 @@ import bjc.utils.funcdata.IMap; * Represents a mapping from a set of strings to a mapping of all unambiguous * prefixes of their respective strings. * - * This works the same as Ruby's Abbrev. + * This works the same as Ruby's Abbrev module. * * @author EVE - * */ public class AbbrevMap { - /* - * All of the words we have abbreviations for. - */ + /* All of the words we have abbreviations for. */ private final Set wrds; - /* - * Maps abbreviations to their strings. - */ + /* Maps abbreviations to their strings. */ private IMap abbrevMap; - /* - * Counts how many times we've seen a substring. - */ + /* Counts how many times we've seen a substring. */ private Set seen; - /* - * Maps ambiguous abbreviations to the strings they could be. - */ + /* Maps ambiguous abbreviations to the strings they could be. */ private SetMultimap ambMap; /** * Create a new abbreviation map. * * @param words - * The initial set of words to put in the map. + * The initial set of words to put in the map. */ public AbbrevMap(final String... words) { wrds = new HashSet<>(Arrays.asList(words)); @@ -54,6 +45,9 @@ public class AbbrevMap { /** * Recalculate all the abbreviations in this map. + * + * This may be needed after certain operations to ensure that all of the + * results are correct. */ public void recalculate() { abbrevMap = new FunctionalMap<>(); @@ -63,11 +57,6 @@ public class AbbrevMap { seen = new HashSet<>(); for (final String word : wrds) { - /* - * A word always abbreviates to itself. - */ - abbrevMap.put(word, word); - intAddWord(word); } } @@ -76,33 +65,25 @@ public class AbbrevMap { * Adds words to the abbreviation map. * * @param words - * The words to add to the abbreviation map. + * The words to add to the abbreviation map. */ public void addWords(final String... words) { wrds.addAll(Arrays.asList(words)); for (final String word : words) { - /* - * A word always abbreviates to itself. - */ - abbrevMap.put(word, word); - intAddWord(word); } } - /* - * Actually add abbreviations of a word. - */ + /* Actually add abbreviations of a word. */ private void intAddWord(final String word) { - /* - * Skip blank words. - */ + /* A word always abbreviates to itself. */ + abbrevMap.put(word, word); + + /* Skip blank words. */ if (word.equals("")) return; - /* - * Handle each possible abbreviation. - */ + /* Handle each possible abbreviation. */ for (int i = word.length(); i > 0; i--) { final String subword = word.substring(0, i); @@ -134,7 +115,7 @@ public class AbbrevMap { * the map. Use {@link AbbrevMap#recalculate()} to fix it if it occurs. * * @param words - * The words to remove. + * The words to remove. */ public void removeWords(final String... words) { wrds.removeAll(Arrays.asList(words)); @@ -144,18 +125,12 @@ public class AbbrevMap { } } - /* - * Actually remove a word. - */ + /* Actually remove a word. */ private void intRemoveWord(final String word) { - /* - * Skip blank words. - */ + /* Skip blank words. */ if (word.equals("")) return; - /* - * Handle each possible abbreviation. - */ + /* Handle each possible abbreviation. */ for (int i = word.length(); i > 0; i--) { final String subword = word.substring(0, i); @@ -169,6 +144,10 @@ public class AbbrevMap { if (possWords.size() == 0) { seen.remove(subword); } else if (possWords.size() == 1) { + /* + * An abbreviation went from ambiguous + * to non-ambiguous. + */ final String newWord = possWords.iterator().next(); abbrevMap.put(subword, newWord); @@ -183,14 +162,17 @@ public class AbbrevMap { * into. * * @param abbrev - * The abbreviation to convert. + * The abbreviation to convert. * - * @return All the expansions for the provided abbreviation. + * @return + * All the expansions for the provided abbreviation. */ public String[] deabbrev(final String abbrev) { - if (abbrevMap.containsKey(abbrev)) + if (abbrevMap.containsKey(abbrev)) { return new String[] { abbrevMap.get(abbrev) }; - else return ambMap.get(abbrev).toArray(new String[0]); + } else { + return ambMap.get(abbrev).toArray(new String[0]); + } } @Override diff --git a/base/src/main/java/bjc/utils/esodata/Directory.java b/base/src/main/java/bjc/utils/esodata/Directory.java index 17b70f5..4b25cda 100644 --- a/base/src/main/java/bjc/utils/esodata/Directory.java +++ b/base/src/main/java/bjc/utils/esodata/Directory.java @@ -7,21 +7,22 @@ package bjc.utils.esodata; * be able to ensure that they can't write outside of it. * * @param - * The key type of the map. + * The key type of the map. * @param - * The value type of the map. + * The value type of the map. */ public interface Directory { /** * Retrieves a given sub-directory. * * @param key - * The key to retrieve the sub-directory for. + * The key to retrieve the sub-directory for. * - * @return The sub-directory under that name. + * @return + * The sub-directory under that name. * * @throws IllegalArgumentException - * If the given sub-directory doesn't exist. + * If the given sub-directory doesn't exist. */ Directory getSubdirectory(K key); @@ -29,9 +30,10 @@ public interface Directory { * Check if a given sub-directory exists. * * @param key - * The key to look for the sub-directory under. + * The key to look for the sub-directory under. * - * @return Whether or not a sub-directory of that name exists. + * @return + * Whether or not a sub-directory of that name exists. */ boolean hasSubdirectory(K key); @@ -39,12 +41,13 @@ public interface Directory { * Insert a sub-directory into the dictionary. * * @param key - * The name of the new sub-directory + * The name of the new sub-directory * @param value - * The sub-directory to insert + * The sub-directory to insert * - * @return The old sub-directory attached to this key, or null if such a - * sub-directory didn't exist + * @return + * The old sub-directory attached to this key, or null if such a + * sub-directory didn't exist */ Directory putSubdirectory(K key, Directory value); @@ -54,10 +57,11 @@ public interface Directory { * Will fail if a sub-directory of that name already exists. * * @param key - * The name of the new sub-directory. + * The name of the new sub-directory. * - * @return The new sub-directory, or null if one by that name already - * exists. + * @return + * The new sub-directory, or null if one by that name already + * exists. */ default Directory newSubdirectory(final K key) { if (hasSubdirectory(key)) return null; @@ -73,9 +77,10 @@ public interface Directory { * Check if the directory contains a data-item under the given key. * * @param key - * The key to check for. + * The key to check for. * - * @return Whether or not there is a data item for the given key. + * @return + * Whether or not there is a data item for the given key. */ boolean containsKey(K key); @@ -83,12 +88,13 @@ public interface Directory { * Retrieve a given data-item from the directory. * * @param key - * The key to retrieve data for. + * The key to retrieve data for. * - * @return The value for the given key. + * @return + * The value for the given key. * * @throws IllegalArgumentException - * If no value exists for the given key. + * If no value exists for the given key. */ V getKey(K key); @@ -96,11 +102,13 @@ public interface Directory { * Insert a data-item into the directory. * * @param key - * The key to insert into. + * The key to insert into. + * * @param val - * The value to insert. + * The value to insert. * - * @return The old value of key, or null if such a value didn't exist. + * @return + * The old value of key, or null if such a value didn't exist. */ V putKey(K key, V val); -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/esodata/DoubleTape.java b/base/src/main/java/bjc/utils/esodata/DoubleTape.java index 5c463c6..a0031ec 100644 --- a/base/src/main/java/bjc/utils/esodata/DoubleTape.java +++ b/base/src/main/java/bjc/utils/esodata/DoubleTape.java @@ -20,16 +20,17 @@ package bjc.utils.esodata; * Flip refers to the entire tape for 'obvious' reasons. * * @param - * The element type of the tape. + * The element type of the tape. + * * @author bjculkin */ public class DoubleTape implements Tape { + /* The front-side of the tape. */ private Tape front; + /* The back-side of the tape. */ private Tape back; - /** - * Create a new empty double-sided tape that doesn't autoextend. - */ + /** Create a new empty double-sided tape that doesn't autoextend. */ public DoubleTape() { this(false); } @@ -39,40 +40,23 @@ public class DoubleTape implements Tape { * auto-extension policy. * * @param autoExtnd - * Whether or not to auto-extend the tape to the right w/ - * nulls. + * Whether or not to auto-extend the tape to the right w/ nulls. */ public DoubleTape(final boolean autoExtnd) { front = new SingleTape<>(autoExtnd); back = new SingleTape<>(autoExtnd); } - /** - * Get the item the tape is currently on. - * - * @return The item the tape is on. - */ @Override public T item() { return front.item(); } - /** - * Set the item the tape is currently on. - * - * @param itm - * The new value for the tape item. - */ @Override public void item(final T itm) { front.item(itm); } - /** - * Get the current number of elements in the tape. - * - * @return The current number of elements in the tape. - */ @Override public int size() { return front.size(); @@ -83,35 +67,18 @@ public class DoubleTape implements Tape { return front.position(); } - /** - * Insert an element before the current item. - * - * @param itm - * The item to add. - */ @Override public void insertBefore(final T itm) { front.insertBefore(itm); back.insertAfter(null); } - /** - * Insert an element after the current item. - */ @Override public void insertAfter(final T itm) { front.insertAfter(itm); back.insertBefore(itm); } - /** - * Remove the current element. - * - * Also moves the cursor back one step if possible to maintain relative - * position, and removes the corresponding item from the non-active side - * - * @return The removed item from the active side. - */ @Override public T remove() { back.remove(); @@ -119,47 +86,23 @@ public class DoubleTape implements Tape { return front.remove(); } - /** - * Move the cursor to the left-most position. - */ @Override public void first() { front.first(); back.last(); } - /** - * Move the cursor the right-most position. - */ @Override public void last() { front.last(); back.first(); } - /** - * Move the cursor one space left. - * - * The cursor can't go past zero. - * - * @return True if the cursor was moved left. - */ @Override public boolean left() { return left(1); } - /** - * Move the cursor the specified amount left. - * - * The cursor can't go past zero. Attempts to move the cursor by amounts - * that would exceed zero don't move the cursor at all. - * - * @param amt - * The amount to attempt to move the cursor left. - * - * @return True if the cursor was moved left. - */ @Override public boolean left(final int amt) { final boolean succ = front.left(amt); @@ -171,28 +114,11 @@ public class DoubleTape implements Tape { return succ; } - /** - * Move the cursor one space right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right() { return right(1); } - /** - * Move the cursor the specified amount right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @param amt - * The amount to move the cursor right by. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right(final int amt) { final boolean succ = front.right(amt); diff --git a/base/src/main/java/bjc/utils/esodata/PushdownMap.java b/base/src/main/java/bjc/utils/esodata/PushdownMap.java index a631704..18a9b46 100644 --- a/base/src/main/java/bjc/utils/esodata/PushdownMap.java +++ b/base/src/main/java/bjc/utils/esodata/PushdownMap.java @@ -12,23 +12,26 @@ import bjc.utils.funcdata.IMap; * A variant of a map where inserting a duplicate key shadows the existing value * instead of replacing it. * + * This could be useful for things like variable scopes. + * * @author EVE * * @param - * The key of the map. + * The key of the map. + * * @param - * The values in the map. + * The values in the map. */ public class PushdownMap implements IMap { + /* Our backing storage. */ private final IMap> backing; - /** - * Create a new empty stack-based map. - */ + /** Create a new empty stack-based map. */ public PushdownMap() { backing = new FunctionalMap<>(); } + /** Create a new empty stack-based map using the specified backing. */ private PushdownMap(final IMap> back) { backing = back; } @@ -80,6 +83,12 @@ public class PushdownMap implements IMap @Override public IMap transform(final Function transformer) { + /* + * @NOTE + * Can and should we support this? + * More to the point, maybe this should be a map sub-type + * that does what it needs to? + */ throw new UnsupportedOperationException("Cannot transform pushdown maps."); } @@ -106,14 +115,16 @@ public class PushdownMap implements IMap public ValueType remove(final KeyType key) { final Stack stk = backing.get(key); - if (stk.size() > 1) + if (stk.size() > 1) { return stk.pop(); - else return backing.remove(key).top(); + } else { + return backing.remove(key).top(); + } } @Override public IList valueList() { - return backing.valueList().map(stk -> stk.top()); + return backing.valueList().map(Stack::top); } @Override diff --git a/base/src/main/java/bjc/utils/esodata/QueueStack.java b/base/src/main/java/bjc/utils/esodata/QueueStack.java index 850598a..be393a3 100644 --- a/base/src/main/java/bjc/utils/esodata/QueueStack.java +++ b/base/src/main/java/bjc/utils/esodata/QueueStack.java @@ -5,18 +5,19 @@ import java.util.LinkedList; /** * A FIFO implementation of a stack. + * + * Basically, a stack that actually acts like a queue. * * @param - * The datatype stored in the stack. + * The datatype stored in the stack. + * * @author Ben Culkin */ public class QueueStack extends Stack { + /* Our backing queue. */ private final Deque backing; - /** - * Create a new empty stack queue. - * - */ + /** Create a new empty stack queue. */ public QueueStack() { backing = new LinkedList<>(); } diff --git a/base/src/main/java/bjc/utils/esodata/SimpleDirectory.java b/base/src/main/java/bjc/utils/esodata/SimpleDirectory.java index 69fd019..5e7f480 100644 --- a/base/src/main/java/bjc/utils/esodata/SimpleDirectory.java +++ b/base/src/main/java/bjc/utils/esodata/SimpleDirectory.java @@ -11,21 +11,21 @@ import bjc.utils.funcdata.IMap; * @author EVE * * @param - * The key type of the directory. + * The key type of the directory. + * * @param - * The value type of the directory. + * The value type of the directory. */ public class SimpleDirectory implements Directory { + /* Our sub-directories. */ private final IMap> children; - + /* Our data. */ private final IMap data; - /** - * Create a new directory. - */ + /** Create a new directory. */ public SimpleDirectory() { children = new FunctionalMap<>(); - data = new FunctionalMap<>(); + data = new FunctionalMap<>(); } @Override @@ -92,4 +92,4 @@ public class SimpleDirectory implements Directory { public String toString() { return String.format("SimpleDirectory [children=%s, data=%s]", children, data); } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/esodata/SimpleStack.java b/base/src/main/java/bjc/utils/esodata/SimpleStack.java index fdb3300..72fb343 100644 --- a/base/src/main/java/bjc/utils/esodata/SimpleStack.java +++ b/base/src/main/java/bjc/utils/esodata/SimpleStack.java @@ -7,16 +7,15 @@ import java.util.LinkedList; * Simple implementation of a stack. * * @param - * The datatype stored in the stack. + * The datatype stored in the stack. + * * @author Ben Culkin */ public class SimpleStack extends Stack { + /* Our backing stack. */ private final Deque backing; - /** - * Create a new empty stack. - * - */ + /** Create a new empty stack. */ public SimpleStack() { backing = new LinkedList<>(); } diff --git a/base/src/main/java/bjc/utils/esodata/SingleTape.java b/base/src/main/java/bjc/utils/esodata/SingleTape.java index c50be92..c7bf6ee 100644 --- a/base/src/main/java/bjc/utils/esodata/SingleTape.java +++ b/base/src/main/java/bjc/utils/esodata/SingleTape.java @@ -15,14 +15,21 @@ import java.util.ArrayList; * policy. * * @param - * The element type of the tape. + * The element type of the tape. * * @author bjculkin */ public class SingleTape implements Tape { + /* @NOTE + * Does this stuff still need to be protected? We're not trying to + * use inheritance to implement tape types any more, so I don't see + * any reason to not have it be private. + */ + /* Our backing store. */ protected ArrayList backing; + /* Our position in the list. */ protected int pos; - + /* Whether to auto-extend the list on the left with nulls. */ protected boolean autoExtend; /** @@ -38,9 +45,8 @@ public class SingleTape implements Tape { backing.add(val); } } - /** - * Create a new empty tape that doesn't autoextend. - */ + + /** Create a new empty tape that doesn't autoextend. */ public SingleTape() { this(false); } @@ -50,8 +56,7 @@ public class SingleTape implements Tape { * policy. * * @param autoExtnd - * Whether or not to auto-extend the tape to the right w/ - * nulls. + * Whether or not to auto-extend the tape to the right w/ nulls. */ public SingleTape(final boolean autoExtnd) { autoExtend = autoExtnd; @@ -59,32 +64,16 @@ public class SingleTape implements Tape { backing = new ArrayList<>(); } - /** - * Get the item the tape is currently on. - * - * @return The item the tape is on. - */ @Override public T item() { return backing.get(pos); } - /** - * Set the item the tape is currently on. - * - * @param itm - * The new value for the tape item. - */ @Override public void item(final T itm) { backing.set(pos, itm); } - /** - * Get the current number of elements in the tape. - * - * @return The current number of elements in the tape. - */ @Override public int size() { return backing.size(); @@ -95,20 +84,11 @@ public class SingleTape implements Tape { return pos; } - /** - * Insert an element before the current item. - * - * @param itm - * The item to add. - */ @Override public void insertBefore(final T itm) { backing.add(pos, itm); } - /** - * Insert an element after the current item. - */ @Override public void insertAfter(final T itm) { if (pos == backing.size() - 1) { @@ -118,14 +98,6 @@ public class SingleTape implements Tape { } } - /** - * Remove the current element. - * - * Also moves the cursor back one step if possible to maintain relative - * position. - * - * @return The removed item. - */ @Override public T remove() { final T res = backing.remove(pos); @@ -135,45 +107,21 @@ public class SingleTape implements Tape { return res; } - /** - * Move the cursor to the left-most position. - */ @Override public void first() { pos = 0; } - /** - * Move the cursor the right-most position. - */ @Override public void last() { pos = backing.size() - 1; } - /** - * Move the cursor one space left. - * - * The cursor can't go past zero. - * - * @return True if the cursor was moved left. - */ @Override public boolean left() { return left(1); } - /** - * Move the cursor the specified amount left. - * - * The cursor can't go past zero. Attempts to move the cursor by amounts - * that would exceed zero don't move the cursor at all. - * - * @param amt - * The amount to attempt to move the cursor left. - * - * @return True if the cursor was moved left. - */ @Override public boolean left(final int amt) { if (pos - amt < 0) return false; @@ -182,28 +130,11 @@ public class SingleTape implements Tape { return true; } - /** - * Move the cursor one space right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right() { return right(1); } - /** - * Move the cursor the specified amount right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @param amt - * The amount to move the cursor right by. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right(final int amt) { if (pos + amt >= backing.size() - 1) { diff --git a/base/src/main/java/bjc/utils/esodata/SpaghettiStack.java b/base/src/main/java/bjc/utils/esodata/SpaghettiStack.java index 7c8c757..f445f75 100644 --- a/base/src/main/java/bjc/utils/esodata/SpaghettiStack.java +++ b/base/src/main/java/bjc/utils/esodata/SpaghettiStack.java @@ -3,23 +3,26 @@ package bjc.utils.esodata; import java.util.Arrays; import java.util.stream.Stream; -/* +/** * Implements a spaghetti stack, which is a stack that is branched off of a * parent stack. * - * @param T The datatype stored in the stack. + * @param + * The datatype stored in the stack. + * * @author Ben Culkin */ class SpaghettiStack extends Stack { + /* Our backing stack. */ private final Stack backing; - + /* The stack we branched off of. */ private final Stack parent; /** * Create a new empty spaghetti stack, off of the specified parent. * * @param par - * The parent stack + * The parent stack */ public SpaghettiStack(final Stack par) { backing = new SimpleStack<>(); diff --git a/base/src/main/java/bjc/utils/esodata/Stack.java b/base/src/main/java/bjc/utils/esodata/Stack.java index 9d74e9a..9bb61dc 100644 --- a/base/src/main/java/bjc/utils/esodata/Stack.java +++ b/base/src/main/java/bjc/utils/esodata/Stack.java @@ -4,10 +4,12 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +/* + * @TODO 10/11/17 Ben Culkin :StackCombinators + * Implement more combinators for the stack. + */ /** - * A stack, with support for combinators. - * - * A FILO stack with support for forth/factor style combinators. + * A stack, with support for forth/factor style stack combinators. * *

*

Stack underflow

@@ -19,7 +21,7 @@ import java.util.function.Consumer; *

* * @param - * The datatype stored in the stack. + * The datatype stored in the stack. * * @author Ben Culkin */ @@ -29,13 +31,9 @@ public abstract class Stack { * stack that isn't there. * * @author EVE - * */ public static class StackUnderflowException extends RuntimeException { - - /** - * - */ + /* The ID of the exception */ private static final long serialVersionUID = 1423867176204571539L; } @@ -43,14 +41,15 @@ public abstract class Stack { * Push an element onto the stack. * * @param elm - * The element to insert. + * The element to insert. */ public abstract void push(T elm); /** * Pop an element off of the stack. * - * @return The element on top of the stack. + * @return + * The element on top of the stack. */ public abstract T pop(); @@ -58,28 +57,32 @@ public abstract class Stack { * Retrieve the top element of this stack without removing it from the * stack. * - * @return The top element of this stack. + * @return + * The top element of this stack. */ public abstract T top(); /** * Get the number of elements in the stack. * - * @return the number of elements in the stack. + * @return + * the number of elements in the stack. */ public abstract int size(); /** * Check if the stack is empty. * - * @return Whether or not the stack is empty. + * @return + * Whether or not the stack is empty. */ public abstract boolean empty(); /** * Create a spaghetti stack branching off of this one. * - * @return A spaghetti stack with this stack as a parent. + * @return + * A spaghetti stack with this stack as a parent. */ public Stack spaghettify() { return new SpaghettiStack<>(this); @@ -93,7 +96,7 @@ public abstract class Stack { * Drop n items from the stack. * * @param n - * The number of items to drop. + * The number of items to drop. */ public void drop(final int n) { for (int i = 0; i < n; i++) { @@ -101,9 +104,7 @@ public abstract class Stack { } } - /** - * Drop one item from the stack. - */ + /** Drop one item from the stack. */ public void drop() { drop(1); } @@ -112,7 +113,7 @@ public abstract class Stack { * Delete n items below the current one. * * @param n - * The number of items below the top to delete. + * The number of items below the top to delete. */ public void nip(final int n) { final T elm = pop(); @@ -122,9 +123,7 @@ public abstract class Stack { push(elm); } - /** - * Delete the second element in the stack. - */ + /** Delete the second element in the stack. */ public void nip() { nip(1); } @@ -133,9 +132,10 @@ public abstract class Stack { * Replicate the top n items of the stack m times. * * @param n - * The number of items to duplicate. + * The number of items to duplicate. + * * @param m - * The number of times to duplicate items. + * The number of times to duplicate items. */ public void multidup(final int n, final int m) { final List lst = new ArrayList<>(n); @@ -155,15 +155,13 @@ public abstract class Stack { * Duplicate the top n items of the stack. * * @param n - * The number of items to duplicate. + * The number of items to duplicate. */ public void dup(final int n) { multidup(n, 2); } - /** - * Duplicate the top item on the stack. - */ + /** Duplicate the top item on the stack. */ public void dup() { dup(1); } @@ -172,9 +170,10 @@ public abstract class Stack { * Replicate the n elements below the top one m times. * * @param n - * The number of items to duplicate. + * The number of items to duplicate. + * * @param m - * The number of times to duplicate items. + * The number of times to duplicate items. */ public void multiover(final int n, final int m) { final List lst = new ArrayList<>(n); @@ -201,22 +200,18 @@ public abstract class Stack { * Duplicate the n elements below the top one. * * @param n - * The number of items to duplicate. + * The number of items to duplicate. */ public void over(final int n) { multiover(n, 2); } - /** - * Duplicate the second item in the stack. - */ + /** Duplicate the second item in the stack. */ public void over() { over(1); } - /** - * Duplicate the third item in the stack. - */ + /** Duplicate the third item in the stack. */ public void pick() { final T z = pop(); final T y = pop(); @@ -228,9 +223,7 @@ public abstract class Stack { push(x); } - /** - * Swap the top two items on the stack. - */ + /** Swap the top two items on the stack. */ public void swap() { final T y = pop(); final T x = pop(); @@ -239,9 +232,7 @@ public abstract class Stack { push(x); } - /** - * Duplicate the second item below the first item. - */ + /** Duplicate the second item below the first item. */ public void deepdup() { final T y = pop(); final T x = pop(); @@ -251,9 +242,7 @@ public abstract class Stack { push(y); } - /** - * Swap the second and third items in the stack. - */ + /** Swap the second and third items in the stack. */ public void deepswap() { final T z = pop(); final T y = pop(); @@ -264,9 +253,7 @@ public abstract class Stack { push(z); } - /** - * Rotate the top three items on the stack - */ + /** Rotate the top three items on the stack */ public void rot() { final T z = pop(); final T y = pop(); @@ -277,9 +264,7 @@ public abstract class Stack { push(x); } - /** - * Inversely rotate the top three items on the stack - */ + /** Inversely rotate the top three items on the stack */ public void invrot() { final T z = pop(); final T y = pop(); @@ -290,25 +275,32 @@ public abstract class Stack { push(y); } + /* + * :StackCombinators + * Add a general rotate/roll operator. + */ + /* * Dataflow Combinators */ + /** - * Hides the top n elements on the stack from cons. + * Hides the top n elements on the stack from an action. * * @param n - * The number of elements to hide. - * @param cons - * The action to hide the elements from + * The number of elements to hide. + * + * @param action + * The action to hide the elements from */ - public void dip(final int n, final Consumer> cons) { + public void dip(final int n, final Consumer> action) { final List elms = new ArrayList<>(n); for (int i = n; i > 0; i--) { elms.set(i - 1, pop()); } - cons.accept(this); + action.accept(this); for (final T elm : elms) { push(elm); @@ -316,75 +308,82 @@ public abstract class Stack { } /** - * Hide the top element of the stack from cons. + * Hide the top element of the stack from an action. * - * @param cons - * The action to hide the top from + * @param action + * The action to hide the top from */ - public void dip(final Consumer> cons) { - dip(1, cons); + public void dip(final Consumer> action) { + dip(1, action); } /** - * Copy the top n elements on the stack, replacing them once cons is + * Copy the top n elements on the stack, replacing them once an action is * done. * * @param n - * The number of elements to copy. - * @param cons - * The action to execute. + * The number of elements to copy. + * + * @param action + * The action to execute. */ - public void keep(final int n, final Consumer> cons) { + public void keep(final int n, final Consumer> action) { + /* + * @NOTE + * Is this correct? + */ dup(n); - dip(n, cons); + dip(n, action); } /** - * Apply all the actions in conses to the top n elements of the stack. + * Apply all the actions in a list to the top n elements of the stack. * * @param n - * The number of elements to give to cons. - * @param conses - * The actions to execute. + * The number of elements to give to cons. + * + * @param actions + * The actions to execute. */ - public void multicleave(final int n, final List>> conses) { + public void multicleave(final int n, final List>> actions) { final List elms = new ArrayList<>(n); for (int i = n; i > 0; i--) { elms.set(i - 1, pop()); } - for (final Consumer> cons : conses) { + for (final Consumer> action : actions) { for (final T elm : elms) { push(elm); } - cons.accept(this); + action.accept(this); } } /** - * Apply all the actions in conses to the top element of the stack. + * Apply all the actions in a list to the top element of the stack. * - * @param conses - * The actions to execute. + * @param actions + * The actions to execute. */ - public void cleave(final List>> conses) { - multicleave(1, conses); + public void cleave(final List>> actions) { + multicleave(1, actions); } /** - * Apply every action in cons to n arguments. + * Apply every action in a list of actions to n arguments. * * @param n - * The number of parameters each action takes. - * @param conses - * The actions to execute. + * The number of parameters each action takes. + * + * @param actions + * The actions to execute. */ - public void multispread(final int n, final List>> conses) { - final List> nelms = new ArrayList<>(conses.size()); + public void multispread(final int n, final List>> actions) { + final List> nelms = new ArrayList<>(actions.size()); - for (int i = conses.size(); i > 0; i--) { + for (int i = actions.size(); i > 0; i--) { final List elms = new ArrayList<>(n); for (int j = n; j > 0; j--) { @@ -400,60 +399,66 @@ public abstract class Stack { push(elm); } - conses.get(i).accept(this); + actions.get(i).accept(this); i += 1; } } /** - * Apply the actions in cons to corresponding elements from the stack. + * Apply the actions in a list of actions to corresponding elements from + * the stack. * * @param conses - * The actions to execute. + * The actions to execute. */ public void spread(final List>> conses) { multispread(1, conses); } /** - * Apply the action in cons to the first m groups of n arguments. + * Apply an action to the first m groups of n arguments. * * @param n - * The number of arguments cons takes. + * The number of arguments cons takes. + * * @param m - * The number of time to call cons. - * @param cons - * The action to execute. + * The number of time to call cons. + * + * @param action + * The action to execute. */ - public void multiapply(final int n, final int m, final Consumer> cons) { - final List>> conses = new ArrayList<>(m); + public void multiapply(final int n, final int m, final Consumer> action) { + final List>> actions = new ArrayList<>(m); for (int i = 0; i < m; i++) { - conses.add(cons); + actions.add(action); } - multispread(n, conses); + multispread(n, actions); } /** - * Apply cons n times to the corresponding elements in the stack. + * Apply an action n times to the corresponding elements in the stack. * * @param n - * The number of times to execute cons. - * @param cons - * The action to execute. + * The number of times to execute cons. + * + * @param action + * The action to execute. */ - public void apply(final int n, final Consumer> cons) { - multiapply(1, n, cons); + public void apply(final int n, final Consumer> action) { + multiapply(1, n, action); } /* * Misc. functions */ + /** * Get an array representing this stack. * - * @return The stack as an array. + * @return + * The stack as an array. */ public abstract T[] toArray(); } diff --git a/base/src/main/java/bjc/utils/esodata/Tape.java b/base/src/main/java/bjc/utils/esodata/Tape.java index b6a2c01..dab027f 100644 --- a/base/src/main/java/bjc/utils/esodata/Tape.java +++ b/base/src/main/java/bjc/utils/esodata/Tape.java @@ -8,7 +8,7 @@ package bjc.utils.esodata; * unbounded to the right, but in practice bounded by available memory. * * @param - * The element type of the tape. + * The element type of the tape. * * @author bjculkin */ @@ -16,7 +16,8 @@ public interface Tape { /** * Get the item the tape is currently on. * - * @return The item the tape is on. + * @return + * The item the tape is on. */ T item(); @@ -24,21 +25,23 @@ public interface Tape { * Set the item the tape is currently on. * * @param itm - * The new value for the tape item. + * The new value for the tape item. */ void item(T itm); /** * Get the current number of elements in the tape. * - * @return The current number of elements in the tape. + * @return + * The current number of elements in the tape. */ int size(); /** * Get the position of the current item. * - * @return The position of the current item. + * @return + * The position of the current item. */ int position(); @@ -46,7 +49,7 @@ public interface Tape { * Insert an element before the current item. * * @param itm - * The item to add. + * The item to add. */ void insertBefore(T itm); @@ -54,7 +57,7 @@ public interface Tape { * Insert an element after the current item. * * @param itm - * The item to insert. + * The item to insert. */ void insertAfter(T itm); @@ -64,18 +67,15 @@ public interface Tape { * Also moves the cursor back one step if possible to maintain relative * position. * - * @return The removed item. + * @return + * The removed item. */ T remove(); - /** - * Move the cursor to the left-most position. - */ + /** Move the cursor to the left-most position. */ void first(); - /** - * Move the cursor the right-most position. - */ + /** Move the cursor to the right-most position. */ void last(); /** @@ -83,7 +83,8 @@ public interface Tape { * * The cursor can't go past zero. * - * @return True if the cursor was moved left. + * @return + * True if the cursor was moved left. */ boolean left(); @@ -94,16 +95,18 @@ public interface Tape { * that would exceed zero don't move the cursor at all. * * @param amt - * The amount to attempt to move the cursor left. + * The amount to attempt to move the cursor left. * - * @return True if the cursor was moved left. + * @return + * True if the cursor was moved left. */ boolean left(int amt); /** * Move the cursor one space right. * - * @return Whether the cursor was moved right. + * @return + * Whether the cursor was moved right. */ boolean right(); @@ -111,16 +114,18 @@ public interface Tape { * Move the cursor the specified amount right. * * @param amt - * The amount to move the cursor right by. + * The amount to move the cursor right by. * - * @return Whether the cursor was moved right. + * @return + * Whether the cursor was moved right. */ boolean right(int amt); /** * Is this tape double sided? * - * @return Whether or not this tape is double-sided. + * @return + * Whether or not this tape is double-sided. */ boolean isDoubleSided(); } diff --git a/base/src/main/java/bjc/utils/esodata/TapeChanger.java b/base/src/main/java/bjc/utils/esodata/TapeChanger.java index dc885bc..08f56c1 100644 --- a/base/src/main/java/bjc/utils/esodata/TapeChanger.java +++ b/base/src/main/java/bjc/utils/esodata/TapeChanger.java @@ -10,15 +10,15 @@ package bjc.utils.esodata; * either return null/false. * * @param - * The element type of the tapes. + * The element type of the tapes. */ public class TapeChanger implements Tape { - private Tape> tapes; - private Tape currentTape; + /* Our list of tapes. */ + private Tape> tapes; + /* The current tape. */ + private Tape currentTape; - /** - * Create a new empty tape changer. - */ + /** Create a new empty tape changer. */ public TapeChanger() { tapes = new SingleTape<>(); } @@ -27,9 +27,10 @@ public class TapeChanger implements Tape { * Create a new tape changer with the specified tapes. * * @param current - * The tape to mount first. + * The tape to mount first. + * * @param others - * The tapes to put in this tape changer. + * The tapes to put in this tape changer. */ @SafeVarargs public TapeChanger(final Tape current, final Tape... others) { @@ -46,11 +47,6 @@ public class TapeChanger implements Tape { currentTape = tapes.item(); } - /** - * Get the item the tape is currently on. - * - * @return The item the tape is on. - */ @Override public T item() { if (currentTape == null) return null; @@ -58,12 +54,6 @@ public class TapeChanger implements Tape { return currentTape.item(); } - /** - * Set the item the tape is currently on. - * - * @param itm - * The new value for the tape item. - */ @Override public void item(final T itm) { if (currentTape == null) return; @@ -71,11 +61,6 @@ public class TapeChanger implements Tape { currentTape.item(itm); } - /** - * Get the current number of elements in the tape. - * - * @return The current number of elements in the tape. - */ @Override public int size() { if (currentTape == null) return 0; @@ -90,12 +75,6 @@ public class TapeChanger implements Tape { return currentTape.position(); } - /** - * Insert an element before the current item. - * - * @param itm - * The item to add. - */ @Override public void insertBefore(final T itm) { if (currentTape == null) return; @@ -103,9 +82,6 @@ public class TapeChanger implements Tape { currentTape.insertBefore(itm); } - /** - * Insert an element after the current item. - */ @Override public void insertAfter(final T itm) { if (currentTape == null) return; @@ -113,14 +89,6 @@ public class TapeChanger implements Tape { currentTape.insertAfter(itm); } - /** - * Remove the current element. - * - * Also moves the cursor back one step if possible to maintain relative - * position, and removes the corresponding item from the non-active side - * - * @return The removed item from the active side. - */ @Override public T remove() { if (currentTape == null) return null; @@ -128,9 +96,6 @@ public class TapeChanger implements Tape { return currentTape.remove(); } - /** - * Move the cursor to the left-most position. - */ @Override public void first() { if (currentTape == null) return; @@ -138,9 +103,6 @@ public class TapeChanger implements Tape { currentTape.first(); } - /** - * Move the cursor the right-most position. - */ @Override public void last() { if (currentTape == null) return; @@ -148,29 +110,11 @@ public class TapeChanger implements Tape { currentTape.last(); } - /** - * Move the cursor one space left. - * - * The cursor can't go past zero. - * - * @return True if the cursor was moved left. - */ @Override public boolean left() { return left(1); } - /** - * Move the cursor the specified amount left. - * - * The cursor can't go past zero. Attempts to move the cursor by amounts - * that would exceed zero don't move the cursor at all. - * - * @param amt - * The amount to attempt to move the cursor left. - * - * @return True if the cursor was moved left. - */ @Override public boolean left(final int amt) { if (currentTape == null) return false; @@ -178,28 +122,11 @@ public class TapeChanger implements Tape { return currentTape.left(amt); } - /** - * Move the cursor one space right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right() { return right(1); } - /** - * Move the cursor the specified amount right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @param amt - * The amount to move the cursor right by. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right(final int amt) { if (currentTape == null) return false; @@ -233,7 +160,8 @@ public class TapeChanger implements Tape { /** * Check if a tape is currently loaded. * - * @return Whether or not a tape is loaded. + * @return + * Whether or not a tape is loaded. */ public boolean isLoaded() { return currentTape != null; @@ -245,7 +173,8 @@ public class TapeChanger implements Tape { * Attempting to load a tape that isn't there won't eject the current * tape. * - * @return Whether or not the next tape was loaded. + * @return + * Whether or not the next tape was loaded. */ public boolean nextTape() { final boolean succ = tapes.right(); @@ -263,7 +192,8 @@ public class TapeChanger implements Tape { * Attempting to load a tape that isn't there won't eject the current * tape. * - * @return Whether or not the previous tape was loaded. + * @return + * Whether or not the previous tape was loaded. */ public boolean prevTape() { final boolean succ = tapes.left(); @@ -283,7 +213,7 @@ public class TapeChanger implements Tape { * The specified tape is loaded. * * @param tp - * The tape to insert and load. + * The tape to insert and load. */ public void insertTape(final Tape tp) { tapes.insertAfter(tp); @@ -299,7 +229,8 @@ public class TapeChanger implements Tape { * * Loads the previous tape, if there is one. * - * @return The removed tape. + * @return + * The removed tape. */ public Tape removeTape() { if (currentTape == null) return null; @@ -322,7 +253,8 @@ public class TapeChanger implements Tape { /** * Get how many tapes are currently in the changer. * - * @return How many tapes are currently in the changer. + * @return + * How many tapes are currently in the changer. */ public int tapeCount() { return tapes.size(); diff --git a/base/src/main/java/bjc/utils/esodata/TapeLibrary.java b/base/src/main/java/bjc/utils/esodata/TapeLibrary.java index 2dbc70b..00e2e99 100644 --- a/base/src/main/java/bjc/utils/esodata/TapeLibrary.java +++ b/base/src/main/java/bjc/utils/esodata/TapeLibrary.java @@ -13,24 +13,19 @@ import java.util.Map; * either return null/false. * * @param - * The element type of the tapes. + * The element type of the tapes. */ public class TapeLibrary implements Tape { - private final Map> tapes; - private Tape currentTape; + /* Our backing store of tapes. */ + private final Map> tapes; + /* The current tape. */ + private Tape currentTape; - /** - * Create a new empty tape library. - */ + /** Create a new empty tape library. */ public TapeLibrary() { tapes = new HashMap<>(); } - /** - * Get the item the tape is currently on. - * - * @return The item the tape is on. - */ @Override public T item() { if (currentTape == null) return null; @@ -38,12 +33,6 @@ public class TapeLibrary implements Tape { return currentTape.item(); } - /** - * Set the item the tape is currently on. - * - * @param itm - * The new value for the tape item. - */ @Override public void item(final T itm) { if (currentTape == null) return; @@ -51,11 +40,6 @@ public class TapeLibrary implements Tape { currentTape.item(itm); } - /** - * Get the current number of elements in the tape. - * - * @return The current number of elements in the tape. - */ @Override public int size() { if (currentTape == null) return 0; @@ -69,12 +53,7 @@ public class TapeLibrary implements Tape { return currentTape.position(); } - /** - * Insert an element before the current item. - * - * @param itm - * The item to add. - */ + @Override public void insertBefore(final T itm) { if (currentTape == null) return; @@ -82,9 +61,6 @@ public class TapeLibrary implements Tape { currentTape.insertBefore(itm); } - /** - * Insert an element after the current item. - */ @Override public void insertAfter(final T itm) { if (currentTape == null) return; @@ -92,14 +68,6 @@ public class TapeLibrary implements Tape { currentTape.insertAfter(itm); } - /** - * Remove the current element. - * - * Also moves the cursor back one step if possible to maintain relative - * position, and removes the corresponding item from the non-active side - * - * @return The removed item from the active side. - */ @Override public T remove() { if (currentTape == null) return null; @@ -107,9 +75,6 @@ public class TapeLibrary implements Tape { return currentTape.remove(); } - /** - * Move the cursor to the left-most position. - */ @Override public void first() { if (currentTape == null) return; @@ -117,9 +82,6 @@ public class TapeLibrary implements Tape { currentTape.first(); } - /** - * Move the cursor the right-most position. - */ @Override public void last() { if (currentTape == null) return; @@ -127,29 +89,11 @@ public class TapeLibrary implements Tape { currentTape.last(); } - /** - * Move the cursor one space left. - * - * The cursor can't go past zero. - * - * @return True if the cursor was moved left. - */ @Override public boolean left() { return left(1); } - /** - * Move the cursor the specified amount left. - * - * The cursor can't go past zero. Attempts to move the cursor by amounts - * that would exceed zero don't move the cursor at all. - * - * @param amt - * The amount to attempt to move the cursor left. - * - * @return True if the cursor was moved left. - */ @Override public boolean left(final int amt) { if (currentTape == null) return false; @@ -157,28 +101,11 @@ public class TapeLibrary implements Tape { return currentTape.left(amt); } - /** - * Move the cursor one space right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right() { return right(1); } - /** - * Move the cursor the specified amount right. - * - * Moving the cursor right will auto-extend the tape if that is enabled. - * - * @param amt - * The amount to move the cursor right by. - * - * @return Whether the cursor was moved right. - */ @Override public boolean right(final int amt) { if (currentTape == null) return false; @@ -212,7 +139,8 @@ public class TapeLibrary implements Tape { /** * Check if a tape is currently loaded. * - * @return Whether or not a tape is loaded. + * @return + * Whether or not a tape is loaded. */ public boolean isLoaded() { return currentTape != null; @@ -225,9 +153,10 @@ public class TapeLibrary implements Tape { * tape. * * @param label - * The label of the tape to load. + * The label of the tape to load. * - * @return Whether or not the next tape was loaded. + * @return + * Whether or not the next tape was loaded. */ public boolean switchTape(final String label) { if (tapes.containsKey(label)) { @@ -248,10 +177,10 @@ public class TapeLibrary implements Tape { * Adding a duplicate tape will overwrite any existing types. * * @param label - * The label of the tape to add. + * The label of the tape to add. * * @param tp - * The tape to insert and load. + * The tape to insert and load. */ public void insertTape(final String label, final Tape tp) { tapes.put(label, tp); @@ -265,9 +194,10 @@ public class TapeLibrary implements Tape { * Does nothing if there is not a tape of that name loaded. * * @param label - * The tape to remove. + * The tape to remove. * - * @return The removed tape. + * @return + * The removed tape. */ public Tape removeTape(final String label) { return tapes.remove(label); @@ -285,7 +215,8 @@ public class TapeLibrary implements Tape { /** * Get how many tapes are currently in the library. * - * @return How many tapes are currently in the library. + * @return + * How many tapes are currently in the library. */ public int tapeCount() { return tapes.size(); @@ -295,9 +226,10 @@ public class TapeLibrary implements Tape { * Check if a specific tape is loaded into the library. * * @param label - * The tape to check for. + * The tape to check for. * - * @return Whether or not a tape of that name exists + * @return + * Whether or not a tape of that name exists */ public boolean hasTape(final String label) { return tapes.containsKey(label); diff --git a/base/src/main/java/bjc/utils/esodata/UnifiedDirectory.java b/base/src/main/java/bjc/utils/esodata/UnifiedDirectory.java index ffb639f..ed71512 100644 --- a/base/src/main/java/bjc/utils/esodata/UnifiedDirectory.java +++ b/base/src/main/java/bjc/utils/esodata/UnifiedDirectory.java @@ -11,18 +11,18 @@ import bjc.utils.funcdata.IMap; * @author EVE * * @param - * The key type of the directory. + * The key type of the directory. + * * @param - * The value type of the directory. + * The value type of the directory. */ public class UnifiedDirectory implements Directory { + /* Our directory children. */ private final IMap> children; - + /* Our data children. */ private final IMap data; - /** - * Create a new directory. - */ + /** Create a new directory. */ public UnifiedDirectory() { children = new FunctionalMap<>(); data = new FunctionalMap<>(); @@ -102,4 +102,4 @@ public class UnifiedDirectory implements Directory { public String toString() { return String.format("UnifiedDirectory [children=%s, data=%s]", children, data); } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/esodata/todos.txt b/base/src/main/java/bjc/utils/esodata/todos.txt new file mode 100644 index 0000000..5382ade --- /dev/null +++ b/base/src/main/java/bjc/utils/esodata/todos.txt @@ -0,0 +1,6 @@ +@TODO 10/11/17 Ben Culkin :TapeRefactor + Refactor double-sidedness into its own interface. + +@TODO 10/11/17 Ben Culkin :CursorHands + Add cursored list/tree data structures with the ability to pick/put the + current node. diff --git a/base/src/main/java/bjc/utils/exceptions/FileNotChosenException.java b/base/src/main/java/bjc/utils/exceptions/FileNotChosenException.java index 6f5a68a..501da5d 100644 --- a/base/src/main/java/bjc/utils/exceptions/FileNotChosenException.java +++ b/base/src/main/java/bjc/utils/exceptions/FileNotChosenException.java @@ -6,24 +6,21 @@ import java.io.IOException; * Represents the user failing to choose a file. * * @author ben - * */ public class FileNotChosenException extends IOException { - // Version ID for serialization + /* Version ID for serialization. */ private static final long serialVersionUID = -8753348705210831096L; - /** - * Create a new exception - */ + /** Create a new exception. */ public FileNotChosenException() { super(); } /** - * Create a new exception with the given cause + * Create a new exception with the given cause. * * @param cause - * The cause of why the exception was thrown + * The cause of why the exception was thrown. */ public FileNotChosenException(final String cause) { super(cause); diff --git a/base/src/main/java/bjc/utils/exceptions/PragmaFormatException.java b/base/src/main/java/bjc/utils/exceptions/PragmaFormatException.java index 1ad339d..362ab27 100644 --- a/base/src/main/java/bjc/utils/exceptions/PragmaFormatException.java +++ b/base/src/main/java/bjc/utils/exceptions/PragmaFormatException.java @@ -3,27 +3,24 @@ package bjc.utils.exceptions; import java.util.InputMismatchException; /** - * The exception to throw whenever a pragma is used with invalid syntax + * The exception to throw whenever a pragma is used with invalid syntax. * * @author ben - * */ public class PragmaFormatException extends InputMismatchException { - // Version ID for serialization + /* Version ID for serialization. */ private static final long serialVersionUID = 1288536477368021069L; - /** - * Create a new exception - */ + /** Create a new exception */ public PragmaFormatException() { super(); } /** - * Create a new exception with the given message + * Create a new exception with the given message. * * @param message - * The message to explain why the exception was thrown + * The message to explain why the exception was thrown. */ public PragmaFormatException(final String message) { super(message); diff --git a/base/src/main/java/bjc/utils/exceptions/UnknownPragmaException.java b/base/src/main/java/bjc/utils/exceptions/UnknownPragmaException.java index 6fc9113..dded214 100644 --- a/base/src/main/java/bjc/utils/exceptions/UnknownPragmaException.java +++ b/base/src/main/java/bjc/utils/exceptions/UnknownPragmaException.java @@ -3,20 +3,19 @@ package bjc.utils.exceptions; import java.util.InputMismatchException; /** - * Represents a error from encountering a unknown pragma + * Represents a error from encountering a unknown pragma. * * @author ben - * */ public class UnknownPragmaException extends InputMismatchException { - // Version ID for serialization + /* Version ID for serialization. */ private static final long serialVersionUID = -4277573484926638662L; /** - * Create a new exception with the given cause + * Create a new exception with the given cause. * * @param cause - * The cause for throwing this exception + * The cause for throwing this exception. */ public UnknownPragmaException(final String cause) { super(cause); diff --git a/base/src/main/java/bjc/utils/funcdata/ExtendedMap.java b/base/src/main/java/bjc/utils/funcdata/ExtendedMap.java index 909c5e9..0c6389e 100644 --- a/base/src/main/java/bjc/utils/funcdata/ExtendedMap.java +++ b/base/src/main/java/bjc/utils/funcdata/ExtendedMap.java @@ -6,11 +6,33 @@ import java.util.function.Function; import bjc.utils.funcutils.ListUtils; +/** + * An extended version of a map, that stores values into a map, but can look + * into a different one for others. + * + * @author Ben Culkin + * + * @param + * The type of the keys of the map. + * + * @param + * The type of the values of the map. + */ class ExtendedMap implements IMap { + /* The map we delegate lookups to. */ private final IMap delegate; - + /* The map we store things in. */ private final IMap store; + /** + * Create a new extended map. + * + * @param delegate + * The map to lookup things in. + * + * @param store + * The map to store things in. + */ public ExtendedMap(final IMap delegate, final IMap store) { this.delegate = delegate; this.store = store; diff --git a/base/src/main/java/bjc/utils/funcdata/FunctionalList.java b/base/src/main/java/bjc/utils/funcdata/FunctionalList.java index 55ea7ff..4cae085 100644 --- a/base/src/main/java/bjc/utils/funcdata/FunctionalList.java +++ b/base/src/main/java/bjc/utils/funcdata/FunctionalList.java @@ -27,17 +27,13 @@ import bjc.utils.data.Pair; * @author ben * * @param - * The type in this list + * The type in this list */ public class FunctionalList implements Cloneable, IList { - /* - * The list used as a backing store - */ + /* The list used as a backing store */ private final List wrapped; - /** - * Create a new empty functional list. - */ + /** Create a new empty functional list. */ public FunctionalList() { wrapped = new ArrayList<>(); } @@ -48,7 +44,7 @@ public class FunctionalList implements Cloneable, IList { * Takes O(n) time, where n is the number of items specified * * @param items - * The items to put into this functional list. + * The items to put into this functional list. */ @SafeVarargs public FunctionalList(final E... items) { @@ -63,7 +59,7 @@ public class FunctionalList implements Cloneable, IList { * Create a new functional list with the specified size. * * @param size - * The size of the backing list . + * The size of the backing list . */ private FunctionalList(final int size) { wrapped = new ArrayList<>(size); @@ -75,7 +71,7 @@ public class FunctionalList implements Cloneable, IList { * Takes O(1) time, since it doesn't copy the list. * * @param backing - * The list to use as a backing list. + * The list to use as a backing list. */ public FunctionalList(final List backing) { if (backing == null) throw new NullPointerException("Backing list must be non-null"); @@ -94,11 +90,11 @@ public class FunctionalList implements Cloneable, IList { for (final E item : wrapped) { if (!predicate.test(item)) - // We've found a non-matching item + /* We've found a non-matching item. */ return false; } - // All of the items matched + /* All of the items matched. */ return true; } @@ -108,20 +104,21 @@ public class FunctionalList implements Cloneable, IList { for (final E item : wrapped) { if (predicate.test(item)) - // We've found a matching item + /* We've found a matching item. */ return true; } - // We didn't find a matching item + /* We didn't find a matching item. */ return false; } /** - * Clone this list into a new one, and clone the backing list as well + * Clone this list into a new one, and clone the backing list as well. * - * Takes O(n) time, where n is the number of elements in the list + * Takes O(n) time, where n is the number of elements in the list. * - * @return A list + * @return + * A copy of the list. */ @Override public IList clone() { @@ -136,18 +133,20 @@ public class FunctionalList implements Cloneable, IList { @Override public IList combineWith(final IList rightList, final BiFunction itemCombiner) { - if (rightList == null) + if (rightList == null) { throw new NullPointerException("Target combine list must not be null"); - else if (itemCombiner == null) throw new NullPointerException("Combiner must not be null"); + } else if (itemCombiner == null) { + throw new NullPointerException("Combiner must not be null"); + } final IList returned = new FunctionalList<>(); - // Get the iterator for the other list + /* Get the iterator for the other list. */ final Iterator rightIterator = rightList.toIterable().iterator(); for (final Iterator leftIterator = wrapped.iterator(); leftIterator.hasNext() && rightIterator.hasNext();) { - // Add the transformed items to the result list + /* Add the transformed items to the result list. */ final E leftVal = leftIterator.next(); final T rightVal = rightIterator.next(); @@ -159,7 +158,7 @@ public class FunctionalList implements Cloneable, IList { @Override public boolean contains(final E item) { - // Check if any items in the list match the provided item + /* Check if any items in the list match the provided item. */ return this.anyMatch(item::equals); } @@ -182,7 +181,7 @@ public class FunctionalList implements Cloneable, IList { if (expandedElement == null) throw new NullPointerException("Expander returned null list"); - // Add each element to the returned list + /* Add each element to the returned list. */ expandedElement.forEach(returned::add); }); @@ -200,15 +199,14 @@ public class FunctionalList implements Cloneable, IList { public void forEachIndexed(final BiConsumer indexedAction) { if (indexedAction == null) throw new NullPointerException("Action must not be null"); - // This is held b/c ref'd variables must be final/effectively - // final + /* This is held b/c ref'd variables must be final/effectively final. */ final IHolder currentIndex = new Identity<>(0); wrapped.forEach((element) -> { - // Call the action with the index and the value + /* Call the action with the index and the value. */ indexedAction.accept(currentIndex.unwrap(index -> index), element); - // Increment the value + /* Increment the value. */ currentIndex.transform((index) -> index + 1); }); } @@ -221,7 +219,8 @@ public class FunctionalList implements Cloneable, IList { /** * Get the internal backing list. * - * @return The backing list this list is based off of. + * @return + * The backing list this list is based off of. */ public List getInternal() { return wrapped; @@ -235,8 +234,7 @@ public class FunctionalList implements Cloneable, IList { wrapped.forEach((element) -> { if (predicate.test(element)) { - // The item matches, so add it to the returned - // list + /* The item matches, so add it to the returned list. */ returned.add(element); } }); @@ -254,9 +252,7 @@ public class FunctionalList implements Cloneable, IList { return wrapped.isEmpty(); } - /* - * Check if a partition has room for another item - */ + /* Check if a partition has room for another item. */ private Boolean isPartitionFull(final int numberPerPartition, final IHolder> currentPartition) { return currentPartition.unwrap((partition) -> partition.getSize() >= numberPerPartition); } @@ -291,18 +287,18 @@ public class FunctionalList implements Cloneable, IList { final IList> returned = new FunctionalList<>(); - // The current partition being filled + /* The current partition being filled. */ final IHolder> currentPartition = new Identity<>(new FunctionalList<>()); this.forEach(element -> { if (isPartitionFull(numberPerPartition, currentPartition)) { - // Add the partition to the list + /* Add the partition to the list. */ returned.add(currentPartition.unwrap(partition -> partition)); - // Start a new partition + /* Start a new partition. */ currentPartition.transform(partition -> new FunctionalList<>()); } else { - // Add the element to the current partition + /* Add the element to the current partition. */ currentPartition.unwrap(partition -> partition.add(element)); } }); @@ -327,19 +323,21 @@ public class FunctionalList implements Cloneable, IList { @Override public F reduceAux(final T initialValue, final BiFunction stateAccumulator, final Function resultTransformer) { - if (stateAccumulator == null) + if (stateAccumulator == null) { throw new NullPointerException("Accumulator must not be null"); - else if (resultTransformer == null) throw new NullPointerException("Transformer must not be null"); + } else if (resultTransformer == null) { + throw new NullPointerException("Transformer must not be null"); + } - // The current collapsed list + /* The current collapsed list. */ final IHolder currentState = new Identity<>(initialValue); wrapped.forEach(element -> { - // Accumulate a new value into the state + /* Accumulate a new value into the state. */ currentState.transform(state -> stateAccumulator.apply(element, state)); }); - // Convert the state to its final value + /* Convert the state to its final value. */ return currentState.unwrap(resultTransformer); } @@ -362,19 +360,20 @@ public class FunctionalList implements Cloneable, IList { @Override public E search(final E searchKey, final Comparator comparator) { - // Search our internal list + /* Search our internal list. */ final int foundIndex = Collections.binarySearch(wrapped, searchKey, comparator); - if (foundIndex >= 0) // We found a matching element + if (foundIndex >= 0) { + /* We found a matching element. */ return wrapped.get(foundIndex); + } - // We didn't find an element + /* We didn't find an element. */ return null; } @Override public void sort(final Comparator comparator) { - // sb.deleteCharAt(sb.length() - 2); Collections.sort(wrapped, comparator); } diff --git a/base/src/main/java/bjc/utils/funcdata/FunctionalMap.java b/base/src/main/java/bjc/utils/funcdata/FunctionalMap.java index c4f0ff1..1218833 100644 --- a/base/src/main/java/bjc/utils/funcdata/FunctionalMap.java +++ b/base/src/main/java/bjc/utils/funcdata/FunctionalMap.java @@ -14,25 +14,25 @@ import bjc.utils.data.IPair; * @author ben * * @param - * The type of the map's keys + * The type of the map's keys. + * * @param - * The type of the map's values + * The type of the map's values. */ public class FunctionalMap implements IMap { + /* Our backing store. */ private Map wrappedMap; - /** - * Create a new blank functional map - */ + /** Create a new blank functional map */ public FunctionalMap() { wrappedMap = new HashMap<>(); } /** - * Create a new functional map with the specified entries + * Create a new functional map with the specified entries. * * @param entries - * The entries to put into the map + * The entries to put into the map. */ @SafeVarargs public FunctionalMap(final IPair... entries) { @@ -46,10 +46,10 @@ public class FunctionalMap implements IMap wrap) { if (wrap == null) throw new NullPointerException("Map to wrap must not be null"); diff --git a/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java b/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java index 8acd477..f9dc4a2 100644 --- a/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java +++ b/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java @@ -14,29 +14,23 @@ import bjc.utils.funcdata.IList; * @author ben * * @param - * The data type stored in the node. + * The data type stored in the node. */ public class BinarySearchTree { - /* - * The comparator for use in ordering items - */ + /* The comparator for use in ordering items */ private final Comparator comparator; - /* - * The current count of elements in the tree - */ + /* The current count of elements in the tree */ private int elementCount; - /* - * The root element of the tree - */ + /* The root element of the tree */ private ITreePart root; /** * Create a new tree using the specified way to compare elements. * * @param cmp - * The thing to use for comparing elements + * The thing to use for comparing elements */ public BinarySearchTree(final Comparator cmp) { if (cmp == null) throw new NullPointerException("Comparator must not be null"); @@ -49,7 +43,7 @@ public class BinarySearchTree { * Add a node to the binary search tree. * * @param element - * The data to add to the binary search tree. + * The data to add to the binary search tree. */ public void addNode(final T element) { elementCount++; @@ -62,18 +56,22 @@ public class BinarySearchTree { } /** - * Check if an adjusted pivot falls with the bounds of a list + * Check if an adjusted pivot falls with the bounds of a list. * * @param elements - * The list to get bounds from + * The list to get bounds from. + * * @param pivot - * The pivot + * The pivot. + * * @param pivotAdjustment - * The distance from the pivot - * @return Whether the adjusted pivot is with the list + * The distance from the pivot. + * + * @return + * Whether the adjusted pivot is with the list. */ private boolean adjustedPivotInBounds(final IList elements, final int pivot, final int pivotAdjustment) { - return pivot - pivotAdjustment >= 0 && pivot + pivotAdjustment < elements.getSize(); + return ((pivot - pivotAdjustment) >= 0) && ((pivot + pivotAdjustment) < elements.getSize()); } /** @@ -84,34 +82,35 @@ public class BinarySearchTree { public void balance() { final IList elements = new FunctionalList<>(); - // Add each element to the list in sorted order + /* Add each element to the list in sorted order. */ root.forEach(TreeLinearizationMethod.INORDER, element -> elements.add(element)); - // Clear the tree + /* Clear the tree. */ root = null; - // Set up the pivot and adjustment for readding elements + /* Set up the pivot and adjustment for readding elements. */ final int pivot = elements.getSize() / 2; int pivotAdjustment = 0; - // Add elements until there aren't any left + /* Add elements until there aren't any left. */ while (adjustedPivotInBounds(elements, pivot, pivotAdjustment)) { if (root == null) { - // Create a new root element + /* Create a new root element. */ root = new BinarySearchTreeNode<>(elements.getByIndex(pivot), null, null); } else { - // Add the left and right elements in a balanced - // manner + /* + * Add the left and right elements in a balanced + * manner. + */ root.add(elements.getByIndex(pivot + pivotAdjustment), comparator); - root.add(elements.getByIndex(pivot - pivotAdjustment), comparator); } - // Increase the distance from the pivot + /* Increase the distance from the pivot. */ pivotAdjustment++; } - // Add any trailing unbalanced elements + /* Add any trailing unbalanced elements. */ if (pivot - pivotAdjustment >= 0) { root.add(elements.getByIndex(pivot - pivotAdjustment), comparator); } else if (pivot + pivotAdjustment < elements.getSize()) { @@ -126,7 +125,7 @@ public class BinarySearchTree { * invoked, and are not included in traversals/finds. * * @param element - * The node to delete + * The node to delete */ public void deleteNode(final T element) { elementCount--; @@ -137,17 +136,19 @@ public class BinarySearchTree { /** * Get the root of the tree. * - * @return The root of the tree. + * @return + * The root of the tree. */ public ITreePart getRoot() { return root; } /** - * Check if a node is in the tree + * Check if a node is in the tree. * * @param element - * The node to check the presence of for the tree. + * The node to check the presence of for the tree.. + * * @return Whether or not the node is in the tree. */ public boolean isInTree(final T element) { @@ -155,37 +156,41 @@ public class BinarySearchTree { } /** - * Traverse the tree in a specified way until the function fails + * Traverse the tree in a specified way until the function fails. * * @param linearizationMethod - * The way to linearize the tree for traversal + * The way to linearize the tree for traversal. + * * @param traversalPredicate - * The function to use until it fails + * The function to use until it fails. */ public void traverse(final TreeLinearizationMethod linearizationMethod, final Predicate traversalPredicate) { - if (linearizationMethod == null) + if (linearizationMethod == null) { throw new NullPointerException("Linearization method must not be null"); - else if (traversalPredicate == null) throw new NullPointerException("Predicate must not be nulls"); + } else if (traversalPredicate == null) { + throw new NullPointerException("Predicate must not be nulls"); + } root.forEach(linearizationMethod, traversalPredicate); } - /** - * Remove all soft-deleted nodes from the tree. - */ + /** Remove all soft-deleted nodes from the tree. */ public void trim() { final List nodes = new ArrayList<>(elementCount); - // Add all non-soft deleted nodes to the tree in insertion order + /* + * Add all non-soft deleted nodes to the tree in insertion + * order. + */ traverse(TreeLinearizationMethod.PREORDER, node -> { nodes.add(node); return true; }); - // Clear the tree + /* Clear the tree. */ root = null; - // Add the nodes to the tree in the order they were inserted + /* Add the nodes to the tree in the order they were inserted. */ nodes.forEach(node -> addNode(node)); } diff --git a/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java b/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java index 8c4f3f0..46f597e 100644 --- a/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java +++ b/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java @@ -11,24 +11,20 @@ import java.util.function.Predicate; * @author ben * * @param - * The data stored in the tree. + * The data stored in the tree. */ public class BinarySearchTreeLeaf implements ITreePart { - /** - * The data held in this tree leaf - */ + /** The data held in this tree leaf */ protected T data; - /** - * Whether this node is soft-deleted or not - */ + /** Whether this node is soft-deleted or not */ protected boolean isDeleted; /** * Create a new leaf holding the specified data. * * @param element - * The data for the leaf to hold. + * The data for the leaf to hold. */ public BinarySearchTreeLeaf(final T element) { data = element; @@ -70,7 +66,7 @@ public class BinarySearchTreeLeaf implements ITreePart { switch (treeWalker.walk(data)) { case SUCCESS: return true; - // We don't have any children to care about + /* We don't have any children to care about. */ case FAILURE: case LEFT: case RIGHT: diff --git a/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java b/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java index 9f45c17..3124474 100644 --- a/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java +++ b/base/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java @@ -16,28 +16,26 @@ import java.util.function.Predicate; * @author ben * * @param - * The data type stored in the tree. + * The data type stored in the tree. */ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { - /* - * The left child of this node - */ + /* The left child of this node */ private ITreePart left; - /* - * The right child of this node - */ + /* The right child of this node */ private ITreePart right; /** * Create a new node with the specified data and children. * * @param element - * The data to store in this node. + * The data to store in this node. + * * @param lft - * The left child of this node. + * The left child of this node. + * * @param rght - * The right child of this node. + * The right child of this node. */ public BinarySearchTreeNode(final T element, final ITreePart lft, final ITreePart rght) { super(element); @@ -154,7 +152,6 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { case RIGHT: return right.directedWalk(treeWalker); case FAILURE: - return false; default: return false; } @@ -163,9 +160,11 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { @Override public boolean forEach(final TreeLinearizationMethod linearizationMethod, final Predicate traversalPredicate) { - if (linearizationMethod == null) + if (linearizationMethod == null) { throw new NullPointerException("Linearization method must not be null"); - else if (traversalPredicate == null) throw new NullPointerException("Predicate must not be null"); + } else if (traversalPredicate == null) { + throw new NullPointerException("Predicate must not be null"); + } switch (linearizationMethod) { case PREORDER: @@ -175,11 +174,13 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { case POSTORDER: return postorderTraverse(linearizationMethod, traversalPredicate); default: - throw new IllegalArgumentException( - "Passed an incorrect TreeLinearizationMethod " + linearizationMethod + ". WAT"); + String msg = String.format("Passed an incorrect TreeLinearizationMethod %s. WAT", linearizationMethod); + + throw new IllegalArgumentException(msg); } } + /* Do an in-order traversal. */ private boolean inorderTraverse(final TreeLinearizationMethod linearizationMethod, final Predicate traversalPredicate) { if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; @@ -191,6 +192,7 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { return true; } + /* Do a post-order traversal. */ private boolean postorderTraverse(final TreeLinearizationMethod linearizationMethod, final Predicate traversalPredicate) { if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; @@ -203,6 +205,7 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { } + /* Do a pre-order traversal. */ private boolean preorderTraverse(final TreeLinearizationMethod linearizationMethod, final Predicate traversalPredicate) { if (!traverseElement(traversalPredicate)) return false; @@ -214,6 +217,7 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { return true; } + /* Traverse an element. */ private boolean traverseElement(final Predicate traversalPredicate) { boolean nodeSuccesfullyTraversed; @@ -226,6 +230,7 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { return nodeSuccesfullyTraversed; } + /* Traverse the left branch of a tree. */ private boolean traverseLeftBranch(final TreeLinearizationMethod linearizationMethod, final Predicate traversalPredicate) { boolean leftSuccesfullyTraversed; @@ -239,6 +244,7 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { return leftSuccesfullyTraversed; } + /* Traverse the right branch of a tree. */ private boolean traverseRightBranch(final TreeLinearizationMethod linearizationMethod, final Predicate traversalPredicate) { boolean rightSuccesfullyTraversed; diff --git a/base/src/main/java/bjc/utils/funcdata/bst/DirectedWalkFunction.java b/base/src/main/java/bjc/utils/funcdata/bst/DirectedWalkFunction.java index e11524a..fdf86d7 100644 --- a/base/src/main/java/bjc/utils/funcdata/bst/DirectedWalkFunction.java +++ b/base/src/main/java/bjc/utils/funcdata/bst/DirectedWalkFunction.java @@ -6,7 +6,7 @@ package bjc.utils.funcdata.bst; * @author ben * * @param - * The type of element stored in the walked tree + * The type of element stored in the walked tree */ @FunctionalInterface public interface DirectedWalkFunction { @@ -14,12 +14,9 @@ public interface DirectedWalkFunction { * Represents the results used to direct a walk in a binary tree. * * @author ben - * */ public enum DirectedWalkResult { - /** - * Specifies that the function has failed. - */ + /** Specifies that the function has failed. */ FAILURE, /** * Specifies that the function wants to move left in the tree @@ -31,10 +28,7 @@ public interface DirectedWalkFunction { * next. */ RIGHT, - /** - * Specifies that the function has succesfully completed - * - */ + /** Specifies that the function has succesfully completed */ SUCCESS } @@ -42,8 +36,10 @@ public interface DirectedWalkFunction { * Perform a directed walk on a node of a tree. * * @param element - * The data stored in the node currently being visited - * @return The way the function wants the walk to go next. + * The data stored in the node currently being visited. + * + * @return + * The way the function wants the walk to go next. */ public DirectedWalkResult walk(T element); } diff --git a/base/src/main/java/bjc/utils/funcdata/bst/ITreePart.java b/base/src/main/java/bjc/utils/funcdata/bst/ITreePart.java index 3aa8880..a2ce71f 100644 --- a/base/src/main/java/bjc/utils/funcdata/bst/ITreePart.java +++ b/base/src/main/java/bjc/utils/funcdata/bst/ITreePart.java @@ -11,53 +11,61 @@ import java.util.function.Predicate; * @author ben * * @param - * The data contained in this part of the tree. + * The data contained in this part of the tree. */ public interface ITreePart { /** * Add a element below this tree part somewhere. * * @param element - * The element to add below this tree part + * The element to add below this tree part + * * @param comparator - * The thing to use for comparing values to find where to - * insert the tree part. + * The thing to use for comparing values to find where to + * insert the tree part. */ public void add(T element, Comparator comparator); /** - * Collapses this tree part into a single value. Does not change the - * underlying tree. + * Collapses this tree part into a single value. + * + * Does not change the underlying tree. * * @param - * The type of the final collapsed value + * The type of the final collapsed value * * @param nodeCollapser - * The function to use to transform data into mapped - * form. + * The function to use to transform data into mapped form. + * * @param branchCollapser - * The function to use to collapse data in mapped form - * into a single value. - * @return A single value from collapsing the tree. + * The function to use to collapse data in mapped form into a + * single value. + * + * @return + * A single value from collapsing the tree. */ public E collapse(Function nodeCollapser, BiFunction branchCollapser); /** - * Check if this tre part or below it contains the specified data item + * Check if this tre part or below it contains the specified data item. * * @param element - * The data item to look for. + * The data item to look for. + * * @param comparator - * The comparator to use to search for the data item - * @return Whether or not the given item is contained in this tree part - * or its children. + * The comparator to use to search for the data item. + * + * @return + * Whether or not the given item is contained in this tree part or + * its children. */ public boolean contains(T element, Comparator comparator); /** * Get the data associated with this tree part. * - * @return The data associated with this tree part. + * @return + * The data associated with this tree part. */ public T data(); @@ -65,9 +73,10 @@ public interface ITreePart { * Remove the given node from this tree part and any of its children. * * @param element - * The data item to remove. + * The data item to remove. + * * @param comparator - * The comparator to use to search for the data item. + * The comparator to use to search for the data item. */ public void delete(T element, Comparator comparator); @@ -75,22 +84,27 @@ public interface ITreePart { * Execute a directed walk through the tree. * * @param walker - * The function to use to direct the walk through the - * tree. - * @return Whether the directed walk finished successfully. + * The function to use to direct the walk through the + * tree. + * + * @return + * Whether the directed walk finished successfully. */ public boolean directedWalk(DirectedWalkFunction walker); /** * Execute a provided function for each element of tree it succesfully - * completes for + * completes for. * * @param linearizationMethod - * The way to linearize the tree for executing + * The way to linearize the tree for executing. + * * @param predicate - * The predicate to apply to each element, where it - * returning false terminates traversal early - * @return Whether the traversal finished succesfully + * The predicate to apply to each element, where it returning false + * terminates traversal early. + * + * @return + * Whether the traversal finished succesfully. */ public boolean forEach(TreeLinearizationMethod linearizationMethod, Predicate predicate); } diff --git a/base/src/main/java/bjc/utils/funcdata/bst/TreeLinearizationMethod.java b/base/src/main/java/bjc/utils/funcdata/bst/TreeLinearizationMethod.java index 0c83867..80afaf2 100644 --- a/base/src/main/java/bjc/utils/funcdata/bst/TreeLinearizationMethod.java +++ b/base/src/main/java/bjc/utils/funcdata/bst/TreeLinearizationMethod.java @@ -4,7 +4,6 @@ package bjc.utils.funcdata.bst; * Represents the ways to linearize a tree for traversal. * * @author ben - * */ public enum TreeLinearizationMethod { /** @@ -22,4 +21,4 @@ public enum TreeLinearizationMethod { * then the right part. */ PREORDER -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java b/base/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java index 13c1709..a94a7b5 100644 --- a/base/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java +++ b/base/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java @@ -3,14 +3,15 @@ package bjc.utils.funcdata.theory; import java.util.function.Function; /** - * A functor over a pair of heterogeneous types + * A functor over a pair of heterogeneous types. * * @author ben + * * @param - * The type stored on the 'left' of the pair - * @param - * The type stored on the 'right' of the pair + * The type stored on the 'left' of the pair. * + * @param + * The type stored on the 'right' of the pair. */ public interface Bifunctor { /** @@ -18,10 +19,17 @@ public interface Bifunctor { * * @author EVE * - * @param + * @param + * The old left type. + * * @param + * The old right type. + * * @param + * The new left type. + * * @param + * The new right type. */ public interface BifunctorMap extends Function, Bifunctor> { @@ -34,8 +42,13 @@ public interface Bifunctor { * @author EVE * * @param + * The old left type. + * * @param + * The old right type. + * * @param + * The new left type. */ public interface LeftBifunctorMap extends BifunctorMap { @@ -48,8 +61,13 @@ public interface Bifunctor { * @author EVE * * @param + * The old left type. + * * @param + * The old right type. + * * @param + * The new right type. */ public interface RightBifunctorMap extends BifunctorMap { @@ -58,21 +76,28 @@ public interface Bifunctor { /** * Lift a pair of functions to a single function that maps over both - * parts of a pair + * parts of a pair. * * @param - * The old left type of the pair + * The old left type of the pair. + * * @param - * The old right type of the pair + * The old right type of the pair. + * * @param - * The new left type of the pair + * The new left type of the pair. + * * @param - * The new right type of the pair + * The new right type of the pair. + * * @param leftFunc - * The function that maps over the left of the pair + * The function that maps over the left of the pair. + * * @param rightFunc - * The function that maps over the right of the pair - * @return A function that maps over both parts of the pair + * The function that maps over the right of the pair. + * + * @return + * A function that maps over both parts of the pair. */ public default BifunctorMap bimap( final Function leftFunc, final Function rightFunc) { @@ -90,50 +115,61 @@ public interface Bifunctor { } /** - * Lift a function to operate over the left part of this pair + * Lift a function to operate over the left part of this pair. * * @param - * The old left type of the pair + * The old left type of the pair. + * * @param - * The old right type of the pair + * The old right type of the pair. + * * @param - * The new left type of the pair + * The new left type of the pair. + * * @param func - * The function to lift to work over the left side of the - * pair - * @return The function lifted to work over the left side of bifunctors + * The function to lift to work over the left side of the pair. + * + * @return + * The function lifted to work over the left side of bifunctors. */ public LeftBifunctorMap fmapLeft( Function func); /** - * Lift a function to operate over the right part of this pair + * Lift a function to operate over the right part of this pair. * * @param - * The old left type of the pair + * The old left type of the pair. + * * @param - * The old right type of the pair + * The old right type of the pair. + * * @param - * The new right type of the pair + * The new right type of the pair. + * * @param func - * The function to lift to work over the right side of - * the pair - * @return The function lifted to work over the right side of bifunctors + * The function to lift to work over the right side of + * the pair. + * + * @return + * The function lifted to work over the right side of bifunctors. */ public RightBifunctorMap fmapRight( Function func); /** - * Get the value contained on the left of this bifunctor + * Get the value contained on the left of this bifunctor. * - * @return The value on the left side of this bifunctor + * @return + * The value on the left side of this bifunctor. */ public LeftType getLeft(); /** - * Get the value contained on the right of this bifunctor + * Get the value contained on the right of this bifunctor. * - * @return The value on the right of this bifunctor + * @return + * The value on the right of this bifunctor. */ public RightType getRight(); } diff --git a/base/src/main/java/bjc/utils/funcdata/theory/Functor.java b/base/src/main/java/bjc/utils/funcdata/theory/Functor.java index 1c53284..9efa883 100644 --- a/base/src/main/java/bjc/utils/funcdata/theory/Functor.java +++ b/base/src/main/java/bjc/utils/funcdata/theory/Functor.java @@ -4,36 +4,42 @@ import java.util.function.Function; /** * Represents a container or context some sort usually, but the precise - * definition is that it represents exactly what it is defined as + * definition is that it represents exactly what it is defined as. * * @author ben + * * @param - * The value inside the functor + * The value inside the functor. */ public interface Functor { /** - * Converts a normal function to operate over values in a functor. + * Converts a normal function to operate over values in a functor.. * * N.B: Even though the type signature implies that you can apply the * resulting function to any type of functor, it is only safe to call it - * on instances of the type of functor you called fmap on. + * on instances of the type of functor you called fmap on.. * * @param - * The argument of the function + * The argument of the function. + * * @param - * The return type of the function + * The return type of the function. + * * @param func - * The function to convert - * @return The passed in function converted to work over a particular - * type of functors + * The function to convert. + * + * @return + * The passed in function converted to work over a particular + * type of functors. */ public Function, Functor> fmap( Function func); /** - * Retrieve the thing inside this functor + * Retrieve the thing inside this functor. * - * @return The thing inside this functor + * @return + * The thing inside this functor. */ public ContainedType getValue(); } -- cgit v1.2.3