diff --git a/src/main/java/org/nwapw/abacus/Abacus.java b/src/main/java/org/nwapw/abacus/Abacus.java index 1ee8f8a..6e7f27e 100644 --- a/src/main/java/org/nwapw/abacus/Abacus.java +++ b/src/main/java/org/nwapw/abacus/Abacus.java @@ -1,12 +1,12 @@ package org.nwapw.abacus; import org.nwapw.abacus.config.ConfigurationObject; -import org.nwapw.abacus.number.NaiveNumber; import org.nwapw.abacus.number.NumberInterface; import org.nwapw.abacus.parsing.LexerTokenizer; import org.nwapw.abacus.parsing.ShuntingYardParser; import org.nwapw.abacus.parsing.TreeBuilder; import org.nwapw.abacus.plugin.ClassFinder; +import org.nwapw.abacus.plugin.NumberImplementation; import org.nwapw.abacus.plugin.PluginManager; import org.nwapw.abacus.plugin.StandardPlugin; import org.nwapw.abacus.tree.NumberReducer; @@ -16,7 +16,6 @@ import org.nwapw.abacus.window.Window; import javax.swing.*; import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; /** * The main calculator class. This is responsible @@ -25,10 +24,7 @@ import java.lang.reflect.InvocationTargetException; */ public class Abacus { - /** - * The default implementation to use for the number representation. - */ - public static final Class DEFAULT_NUMBER = NaiveNumber.class; + public static final NumberImplementation DEFAULT_IMPLEMENTATION = StandardPlugin.IMPLEMENTATION_NAIVE; /** * The file used for saving and loading configuration. */ @@ -154,15 +150,10 @@ public class Abacus { * @return the resulting number. */ public NumberInterface numberFromString(String numberString) { - Class toInstantiate = - pluginManager.numberFor(configuration.getNumberImplementation()); - if (toInstantiate == null) toInstantiate = DEFAULT_NUMBER; + NumberImplementation toInstantiate = + pluginManager.numberImplementationFor(configuration.getNumberImplementation()); + if (toInstantiate == null) toInstantiate = DEFAULT_IMPLEMENTATION; - try { - return toInstantiate.getConstructor(String.class).newInstance(numberString); - } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - e.printStackTrace(); - } - return null; + return toInstantiate.instanceForString(numberString); } } diff --git a/src/main/java/org/nwapw/abacus/plugin/NumberImplementation.java b/src/main/java/org/nwapw/abacus/plugin/NumberImplementation.java index c57fbc6..99019cf 100644 --- a/src/main/java/org/nwapw/abacus/plugin/NumberImplementation.java +++ b/src/main/java/org/nwapw/abacus/plugin/NumberImplementation.java @@ -2,6 +2,7 @@ package org.nwapw.abacus.plugin; import org.nwapw.abacus.number.NumberInterface; +import java.util.HashMap; import java.util.Map; import java.util.function.Function; @@ -11,6 +12,12 @@ public abstract class NumberImplementation { private Map> promotionPaths; private int priority; + public NumberImplementation(Class implementation, int priority){ + this.implementation = implementation; + this.priority = priority; + promotionPaths = new HashMap<>(); + } + public abstract NumberInterface instanceForString(String string); public abstract NumberInterface instanceForPi(); diff --git a/src/main/java/org/nwapw/abacus/plugin/Plugin.java b/src/main/java/org/nwapw/abacus/plugin/Plugin.java index 2757841..e82df64 100644 --- a/src/main/java/org/nwapw/abacus/plugin/Plugin.java +++ b/src/main/java/org/nwapw/abacus/plugin/Plugin.java @@ -24,6 +24,10 @@ public abstract class Plugin { * A hash map of operators mapped to their string names. */ private Map operators; + /** + * The map of the number implementations this plugin provides. + */ + private Map numberImplementations; /** * The plugin manager in which to search for functions * not inside this package, @@ -46,6 +50,7 @@ public abstract class Plugin { this.manager = manager; functions = new HashMap<>(); operators = new HashMap<>(); + numberImplementations = new HashMap<>(); enabled = false; } @@ -67,6 +72,10 @@ public abstract class Plugin { return operators.keySet(); } + public final Set providedNumberImplementations(){ + return numberImplementations.keySet(); + } + /** * Gets a function under the given function name. * @@ -87,6 +96,10 @@ public abstract class Plugin { return operators.get(operatorName); } + public final NumberImplementation getNumberImplementation(String name){ + return numberImplementations.get(name); + } + /** * Enables the function, loading the necessary instances * of functions. @@ -132,6 +145,10 @@ public abstract class Plugin { operators.put(name, operator); } + protected final void registerNumberImplementation(String name, NumberImplementation implementation){ + numberImplementations.put(name, implementation); + } + /** * Searches the PluginManager for the given function name. * This can be used by the plugins internally in order to call functions @@ -156,6 +173,10 @@ public abstract class Plugin { return manager.operatorFor(name); } + protected final NumberImplementation numberImplementationFor(String name){ + return manager.numberImplementationFor(name); + } + /** * Abstract method to be overridden by plugin implementation, in which the plugins * are supposed to register the functions they provide and do any other diff --git a/src/main/java/org/nwapw/abacus/plugin/PluginManager.java b/src/main/java/org/nwapw/abacus/plugin/PluginManager.java index 1f61a56..7d837cb 100644 --- a/src/main/java/org/nwapw/abacus/plugin/PluginManager.java +++ b/src/main/java/org/nwapw/abacus/plugin/PluginManager.java @@ -30,6 +30,7 @@ public class PluginManager { * that is, found in a plugin and returned. */ private Map cachedOperators; + private Map cachedNumberImplementations; /** * List of all functions loaded by the plugins. */ @@ -38,6 +39,7 @@ public class PluginManager { * List of all operators loaded by the plugins. */ private Set allOperators; + private Set allNumberImplementations; /** * The list of plugin listeners attached to this instance. */ @@ -51,8 +53,10 @@ public class PluginManager { plugins = new HashSet<>(); cachedFunctions = new HashMap<>(); cachedOperators = new HashMap<>(); + cachedNumberImplementations = new HashMap<>(); allFunctions = new HashSet<>(); allOperators = new HashSet<>(); + allNumberImplementations = new HashSet<>(); listeners = new HashSet<>(); } @@ -109,6 +113,10 @@ public class PluginManager { return searchCached(plugins, cachedOperators, Plugin::providedOperators, Plugin::getOperator, name); } + public NumberImplementation numberImplementationFor(String name){ + return searchCached(plugins, cachedNumberImplementations, Plugin::providedNumberImplementations, + Plugin::getNumberImplementation, name); + } /** * Adds an instance of Plugin that already has been instantiated. * @@ -143,6 +151,7 @@ public class PluginManager { for (Plugin plugin : plugins) { allFunctions.addAll(plugin.providedFunctions()); allOperators.addAll(plugin.providedOperators()); + allNumberImplementations.addAll(plugin.providedNumberImplementations()); } listeners.forEach(e -> e.onLoad(this)); } @@ -154,6 +163,7 @@ public class PluginManager { for (Plugin plugin : plugins) plugin.disable(); allFunctions.clear(); allOperators.clear(); + allNumberImplementations.clear(); listeners.forEach(e -> e.onUnload(this)); } @@ -183,6 +193,10 @@ public class PluginManager { return allOperators; } + public Set getAllNumberImplementations(){ + return allNumberImplementations; + } + /** * Adds a plugin change listener to this plugin manager. * diff --git a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java index be6b3e8..e7729e0 100755 --- a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java @@ -6,6 +6,7 @@ import org.nwapw.abacus.function.OperatorAssociativity; import org.nwapw.abacus.function.OperatorType; import org.nwapw.abacus.number.NaiveNumber; import org.nwapw.abacus.number.NumberInterface; +import org.nwapw.abacus.number.PreciseNumber; import java.util.ArrayList; import java.util.HashMap; @@ -306,6 +307,30 @@ public class StandardPlugin extends Plugin { } }; + public static final NumberImplementation IMPLEMENTATION_NAIVE = new NumberImplementation(NaiveNumber.class, 0) { + @Override + public NumberInterface instanceForString(String string) { + return new NaiveNumber(string); + } + + @Override + public NumberInterface instanceForPi() { + return new NaiveNumber(Math.PI); + } + }; + + public static final NumberImplementation IMPLEMENTATION_PRECISE = new NumberImplementation(PreciseNumber.class, 0) { + @Override + public NumberInterface instanceForString(String string) { + return new PreciseNumber(string); + } + + @Override + public NumberInterface instanceForPi() { + return null; + } + }; + public StandardPlugin(PluginManager manager) { super(manager); } @@ -338,6 +363,9 @@ public class StandardPlugin extends Plugin { @Override public void onEnable() { + registerNumberImplementation("naive", IMPLEMENTATION_NAIVE); + registerNumberImplementation("precise", IMPLEMENTATION_PRECISE); + registerOperator("+", OP_ADD); registerOperator("-", OP_SUBTRACT); registerOperator("*", OP_MULTIPLY);