mirror of
https://github.com/DanilaFe/abacus
synced 2024-06-28 05:36:23 -07:00
115 lines
3.7 KiB
Kotlin
115 lines
3.7 KiB
Kotlin
package org.nwapw.abacus
|
|
|
|
import org.nwapw.abacus.config.Configuration
|
|
import org.nwapw.abacus.context.MutableEvaluationContext
|
|
import org.nwapw.abacus.context.EvaluationContext
|
|
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.PluginManager
|
|
import org.nwapw.abacus.plugin.StandardPlugin
|
|
import org.nwapw.abacus.tree.EvaluationResult
|
|
import org.nwapw.abacus.tree.NumberReducer
|
|
import org.nwapw.abacus.tree.TreeNode
|
|
|
|
/**
|
|
* 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 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 hidden, mutable implementation of the context.
|
|
*/
|
|
private val mutableContext = MutableEvaluationContext(numberImplementation = StandardPlugin.IMPLEMENTATION_NAIVE)
|
|
/**
|
|
* The base context from which calculations are started.
|
|
*/
|
|
val context: EvaluationContext
|
|
get() = mutableContext
|
|
|
|
init {
|
|
pluginManager.addListener(tokenizer)
|
|
pluginManager.addListener(parser)
|
|
pluginManager.addListener(promotionManager)
|
|
}
|
|
|
|
/**
|
|
* Reloads the Abacus core.
|
|
*/
|
|
fun reload(){
|
|
pluginManager.reload()
|
|
with(mutableContext) {
|
|
numberImplementation = pluginManager.numberImplementationFor(configuration.numberImplementation)
|
|
?: StandardPlugin.IMPLEMENTATION_NAIVE
|
|
clearVariables()
|
|
clearDefinitions()
|
|
}
|
|
}
|
|
/**
|
|
* Merges the current context with the provided one, updating
|
|
* variables and the like.
|
|
* @param context the context to apply.
|
|
*/
|
|
fun applyToContext(context: EvaluationContext){
|
|
mutableContext.apply(context)
|
|
}
|
|
/**
|
|
* 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.
|
|
*
|
|
* @param tree the tree to reduce, must not be null.
|
|
* @return the evaluation result.
|
|
*/
|
|
fun evaluateTree(tree: TreeNode): EvaluationResult {
|
|
return evaluateTreeWithContext(tree, context.mutableSubInstance())
|
|
}
|
|
/**
|
|
* Evaluates the given tree using a different context than
|
|
* the default one.
|
|
*
|
|
* @param tree the tree to reduce, must not be null.
|
|
* @param context the context to use for the evaluation.
|
|
* @return the evaluation result.
|
|
*/
|
|
fun evaluateTreeWithContext(tree: TreeNode, context: MutableEvaluationContext): EvaluationResult {
|
|
val newReducer = NumberReducer(this, context)
|
|
val evaluationValue = tree.reduce(newReducer)
|
|
return EvaluationResult(evaluationValue, newReducer.context)
|
|
}
|
|
|
|
} |