mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-31 19:15:20 +00:00
Switch all applicables to use the Context.
This commit is contained in:
@@ -84,6 +84,6 @@ class Abacus(val configuration: Configuration) {
|
||||
* @return the resulting number, or null of the reduction failed.
|
||||
*/
|
||||
fun evaluateTree(tree: TreeNode): NumberInterface? =
|
||||
tree.reduce(NumberReducer(this, context.mutableSubInstance()))
|
||||
tree.reduce(NumberReducer(this, context))
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.nwapw.abacus.function
|
||||
|
||||
import org.nwapw.abacus.function.applicable.ReducerApplicable
|
||||
import org.nwapw.abacus.function.applicable.Applicable
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
import org.nwapw.abacus.tree.TreeNode
|
||||
|
||||
@@ -10,4 +10,4 @@ import org.nwapw.abacus.tree.TreeNode
|
||||
* A function that operates on parse tree nodes instead of on already simplified numbers.
|
||||
* Despite this, it returns a number, not a tree.
|
||||
*/
|
||||
abstract class TreeValueFunction : ReducerApplicable<TreeNode, NumberInterface, NumberInterface>
|
||||
abstract class TreeValueFunction : Applicable<TreeNode, NumberInterface>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.nwapw.abacus.function
|
||||
|
||||
import org.nwapw.abacus.function.applicable.ReducerApplicable
|
||||
import org.nwapw.abacus.function.applicable.Applicable
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
import org.nwapw.abacus.tree.TreeNode
|
||||
|
||||
@@ -15,4 +15,4 @@ import org.nwapw.abacus.tree.TreeNode
|
||||
abstract class TreeValueOperator(associativity: OperatorAssociativity, type: OperatorType,
|
||||
precedence: Int) :
|
||||
Operator(associativity, type, precedence),
|
||||
ReducerApplicable<TreeNode, NumberInterface, NumberInterface>
|
||||
Applicable<TreeNode, NumberInterface>
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.nwapw.abacus.function.applicable
|
||||
|
||||
import org.nwapw.abacus.context.MutableReductionContext
|
||||
import org.nwapw.abacus.function.DomainException
|
||||
import org.nwapw.abacus.plugin.NumberImplementation
|
||||
|
||||
/**
|
||||
* A class that can be applied to arguments.
|
||||
@@ -18,7 +18,7 @@ interface Applicable<in T : Any, out O : Any> {
|
||||
* @param params the parameter array to verify for compatibility.
|
||||
* @return whether the array can be used with applyInternal.
|
||||
*/
|
||||
fun matchesParams(implementation: NumberImplementation, params: Array<out T>): Boolean
|
||||
fun matchesParams(context: MutableReductionContext, params: Array<out T>): Boolean
|
||||
|
||||
/**
|
||||
* Applies the applicable object to the given parameters,
|
||||
@@ -26,7 +26,7 @@ interface Applicable<in T : Any, out O : Any> {
|
||||
* @param params the parameters to apply to.
|
||||
* @return the result of the application.
|
||||
*/
|
||||
fun applyInternal(implementation: NumberImplementation, params: Array<out T>): O
|
||||
fun applyInternal(context: MutableReductionContext, params: Array<out T>): O
|
||||
|
||||
/**
|
||||
* If the parameters can be used with this applicable, returns
|
||||
@@ -35,9 +35,9 @@ interface Applicable<in T : Any, out O : Any> {
|
||||
* @param params the parameters to apply to.
|
||||
* @return the result of the operation, or null if parameters do not match.
|
||||
*/
|
||||
fun apply(implementation: NumberImplementation, vararg params: T): O {
|
||||
if (!matchesParams(implementation, params)) throw DomainException()
|
||||
return applyInternal(implementation, params)
|
||||
fun apply(context: MutableReductionContext, vararg params: T): O {
|
||||
if (!matchesParams(context, params)) throw DomainException()
|
||||
return applyInternal(context, params)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package org.nwapw.abacus.function.applicable
|
||||
|
||||
import org.nwapw.abacus.function.DomainException
|
||||
import org.nwapw.abacus.plugin.NumberImplementation
|
||||
import org.nwapw.abacus.tree.Reducer
|
||||
|
||||
/**
|
||||
* Applicable that requires a reducer.
|
||||
*
|
||||
* ReducerApplicable slightly more specific Applicable that requires a reducer
|
||||
* to be passed to it along with the parameters.
|
||||
* @param <T> the type of the input arguments.
|
||||
* @param <O> the return type of the application.
|
||||
* @param <R> the required type of the reducer.
|
||||
*/
|
||||
interface ReducerApplicable<in T : Any, out O : Any, in R : Any> {
|
||||
|
||||
/**
|
||||
* Checks if this applicable can be applied to the
|
||||
* given parameters.
|
||||
* @param params the parameters to check.
|
||||
*/
|
||||
fun matchesParams(implementation: NumberImplementation, params: Array<out T>): Boolean
|
||||
|
||||
/**
|
||||
* Applies this applicable to the given arguments, and reducer.
|
||||
* @param reducer the reducer to use in the application.
|
||||
* @param params the arguments to apply to.
|
||||
* @return the result of the application.
|
||||
*/
|
||||
fun applyWithReducerInternal(implementation: NumberImplementation, reducer: Reducer<R>, params: Array<out T>): O
|
||||
|
||||
/**
|
||||
* Applies this applicable to the given arguments, and reducer,
|
||||
* if the arguments and reducer are compatible with this applicable.
|
||||
* @param reducer the reducer to use in the application.
|
||||
* @param params the arguments to apply to.
|
||||
* @return the result of the application, or null if the arguments are incompatible.
|
||||
*/
|
||||
fun applyWithReducer(implementation: NumberImplementation, reducer: Reducer<R>, vararg params: T): O {
|
||||
if (!matchesParams(implementation, params)) throw DomainException()
|
||||
return applyWithReducerInternal(implementation, reducer, params)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,10 +2,17 @@ package org.nwapw.abacus.tree
|
||||
|
||||
import org.nwapw.abacus.Abacus
|
||||
import org.nwapw.abacus.context.MutableReductionContext
|
||||
import org.nwapw.abacus.context.ReductionContext
|
||||
import org.nwapw.abacus.function.NumberFunction
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
|
||||
class NumberReducer(val abacus: Abacus, val context: MutableReductionContext) : Reducer<NumberInterface> {
|
||||
class NumberReducer(val abacus: Abacus, context: ReductionContext) : Reducer<NumberInterface> {
|
||||
|
||||
val context = context.mutableSubInstance()
|
||||
|
||||
init {
|
||||
this.context.reducer = this
|
||||
}
|
||||
|
||||
override fun reduceNode(treeNode: TreeNode, vararg children: Any): NumberInterface? {
|
||||
val promotionManager = abacus.promotionManager
|
||||
@@ -22,33 +29,34 @@ class NumberReducer(val abacus: Abacus, val context: MutableReductionContext) :
|
||||
}
|
||||
is NumberUnaryNode -> {
|
||||
val child = children[0] as NumberInterface
|
||||
context.numberImplementation = abacus.pluginManager.interfaceImplementationFor(child.javaClass)
|
||||
abacus.pluginManager.operatorFor(treeNode.operation)
|
||||
.apply(abacus.pluginManager.interfaceImplementationFor(child.javaClass), child)
|
||||
.apply(context, child)
|
||||
}
|
||||
is NumberBinaryNode -> {
|
||||
val left = children[0] as NumberInterface
|
||||
val right = children[1] as NumberInterface
|
||||
val promotionResult = promotionManager.promote(left, right) ?: return null
|
||||
abacus.pluginManager.operatorFor(treeNode.operation).apply(promotionResult.promotedTo, *promotionResult.items)
|
||||
context.numberImplementation = promotionResult.promotedTo
|
||||
abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items)
|
||||
}
|
||||
is FunctionNode -> {
|
||||
val promotionResult = promotionManager
|
||||
.promote(*children.map { it as NumberInterface }.toTypedArray()) ?: return null
|
||||
abacus.pluginManager.functionFor(treeNode.callTo).apply(promotionResult.promotedTo, *promotionResult.items)
|
||||
context.numberImplementation = promotionResult.promotedTo
|
||||
abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items)
|
||||
}
|
||||
is TreeValueUnaryNode -> {
|
||||
abacus.pluginManager.treeValueOperatorFor(treeNode.operation)
|
||||
.applyWithReducer(context.inheritedNumberImplementation!!, this, children[0] as TreeNode)
|
||||
.apply(context, treeNode.applyTo ?: return null)
|
||||
}
|
||||
is TreeValueBinaryNode -> {
|
||||
abacus.pluginManager.treeValueOperatorFor(treeNode.operation)
|
||||
.applyWithReducer(context.inheritedNumberImplementation!!, this,
|
||||
children[0] as TreeNode, children[1] as TreeNode)
|
||||
.apply(context, treeNode.left ?: return null, treeNode.right ?: return null)
|
||||
}
|
||||
is TreeValueFunctionNode -> {
|
||||
abacus.pluginManager.treeValueFunctionFor(treeNode.callTo)
|
||||
.applyWithReducer(context.inheritedNumberImplementation!!, this,
|
||||
*children.map { it as TreeNode }.toTypedArray())
|
||||
.apply(context, *treeNode.children.toTypedArray())
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user