1
0
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:
2017-09-06 21:43:07 -07:00
parent 58fea9c52b
commit 91986112a1
9 changed files with 191 additions and 191 deletions

View File

@@ -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))
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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
}