Move Abacus core into Kotlin.

This commit is contained in:
Danila Fedorin 2017-09-01 23:52:05 -07:00
parent 9ddfeb02cf
commit daffdb6b42
2 changed files with 85 additions and 150 deletions

View File

@ -1,150 +0,0 @@
package org.nwapw.abacus;
import org.nwapw.abacus.config.Configuration;
import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.number.PromotionManager;
import org.nwapw.abacus.parsing.LexerTokenizer;
import org.nwapw.abacus.parsing.ShuntingYardParser;
import org.nwapw.abacus.parsing.TreeBuilder;
import org.nwapw.abacus.plugin.NumberImplementation;
import org.nwapw.abacus.plugin.PluginManager;
import org.nwapw.abacus.plugin.StandardPlugin;
import org.nwapw.abacus.tree.NumberReducer;
import org.nwapw.abacus.tree.TreeNode;
/**
* The main calculator class. This is responsible
* for piecing together all of the components, allowing
* their interaction with each other.
*/
public class Abacus {
/**
* The default number implementation to be used if no other one is available / selected.
*/
public static final NumberImplementation DEFAULT_IMPLEMENTATION = StandardPlugin.IMPLEMENTATION_NAIVE;
/**
* The plugin manager responsible for
* loading and unloading plugins,
* and getting functions from them.
*/
private PluginManager pluginManager;
/**
* The reducer used to evaluate the tree.
*/
private NumberReducer numberReducer;
/**
* The configuration loaded from a file.
*/
private Configuration configuration;
/**
* The tree builder used to construct a tree
* from a string.
*/
private TreeBuilder treeBuilder;
/**
* Promotion manager responsible for the promotion system.
*/
private PromotionManager promotionManager;
/**
* Creates a new instance of the Abacus calculator.
*
* @param configuration the configuration object for this Abacus instance.
*/
public Abacus(Configuration configuration) {
pluginManager = new PluginManager(this);
numberReducer = new NumberReducer(this);
this.configuration = new Configuration(configuration);
LexerTokenizer lexerTokenizer = new LexerTokenizer();
ShuntingYardParser shuntingYardParser = new ShuntingYardParser();
treeBuilder = new TreeBuilder<>(lexerTokenizer, shuntingYardParser);
promotionManager = new PromotionManager(this);
pluginManager.addListener(shuntingYardParser);
pluginManager.addListener(lexerTokenizer);
pluginManager.addListener(promotionManager);
}
/**
* Gets the promotion manager.
*
* @return the promotion manager.
*/
public PromotionManager getPromotionManager() {
return promotionManager;
}
/**
* Gets the current tree builder.
*
* @return the main tree builder in this abacus instance.
*/
public TreeBuilder getTreeBuilder() {
return treeBuilder;
}
/**
* Gets the current plugin manager,
*
* @return the plugin manager in this abacus instance.
*/
public PluginManager getPluginManager() {
return pluginManager;
}
/**
* Get the reducer that is responsible for transforming
* an expression into a number.
*
* @return the number reducer in this abacus instance.
*/
public NumberReducer getNumberReducer() {
return numberReducer;
}
/**
* Gets the configuration object associated with this instance.
*
* @return the configuration object.
*/
public Configuration getConfiguration() {
return configuration;
}
/**
* Parses a string into a tree structure using the main
* tree builder.
*
* @param input the input string to parse
* @return the resulting tree, null if the tree builder or the produced tree are null.
*/
public TreeNode parseString(String input) {
return treeBuilder.fromString(input);
}
/**
* Evaluates the given tree using the main
* number reducer.
*
* @param tree the tree to reduce, must not be null.
* @return the resulting number, or null of the reduction failed.
*/
public NumberInterface evaluateTree(TreeNode tree) {
return tree.reduce(numberReducer);
}
/**
* Gets the number implementation.
*
* @return the number implementation to use for creating numbers.
*/
public NumberImplementation getNumberImplementation() {
NumberImplementation selectedImplementation =
pluginManager.numberImplementationFor(configuration.getNumberImplementation());
if (selectedImplementation != null) return selectedImplementation;
return DEFAULT_IMPLEMENTATION;
}
}

View File

@ -0,0 +1,85 @@
package org.nwapw.abacus
import org.nwapw.abacus.config.Configuration
import org.nwapw.abacus.number.NumberInterface
import org.nwapw.abacus.number.PromotionManager
import org.nwapw.abacus.parsing.LexerTokenizer
import org.nwapw.abacus.parsing.ShuntingYardParser
import org.nwapw.abacus.parsing.TreeBuilder
import org.nwapw.abacus.plugin.NumberImplementation
import org.nwapw.abacus.plugin.PluginManager
import org.nwapw.abacus.plugin.StandardPlugin
import org.nwapw.abacus.tree.NumberReducer
import org.nwapw.abacus.tree.TreeNode
import org.nwapw.abacus.variables.VariableDatabase
/**
* Core class to handle all mathematics.
*
* The main calculator class. This is responsible
* for piecing together all of the components, allowing
* their interaction with each other.
*
* @property configuration the configuration to use.
*/
class Abacus(val configuration: Configuration) {
/**
* The tokenizer used to convert strings into tokens.
*/
private val tokenizer = LexerTokenizer()
/**
* Parser the parser used to convert tokens into trees.
*/
private val parser = ShuntingYardParser()
/**
* The plugin manager used to handle loading and unloading plugins.
*/
val pluginManager = PluginManager(this)
/**
* The reducer used to turn trees into a single number.
*/
val numberReducer = NumberReducer(this)
/**
* The tree builder that handles the conversion of strings into trees.
*/
val treeBuilder = TreeBuilder(tokenizer, parser)
/**
* The promotion manager used to convert between number implementations.
*/
val promotionManager = PromotionManager(this)
/**
* The number implementation used by default.
*/
val numberImplementation: NumberImplementation
get() {
val selectedImplementation =
pluginManager.numberImplementationFor(configuration.numberImplementation)
if (selectedImplementation != null) return selectedImplementation
return StandardPlugin.IMPLEMENTATION_NAIVE
}
init {
pluginManager.addListener(tokenizer)
pluginManager.addListener(parser)
pluginManager.addListener(promotionManager)
}
/**
* Parses a string into a tree structure using the main
* tree builder.
*
* @param input the input string to parse
* @return the resulting tree, null if the tree builder or the produced tree are null.
*/
fun parseString(input: String): TreeNode? = treeBuilder.fromString(input)
/**
* Evaluates the given tree using the main
* number reducer.
*
* @param tree the tree to reduce, must not be null.
* @return the resulting number, or null of the reduction failed.
*/
fun evaluateTree(tree: TreeNode): NumberInterface? = tree.reduce(numberReducer)
}