mirror of
https://github.com/DanilaFe/abacus
synced 2026-09-22 03:12:33 +00:00
Move some more operators out of StandardPlugin.java to separate classes
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package org.nwapw.abacus.plugin.standard
|
||||
|
||||
import org.nwapw.abacus.context.MutableEvaluationContext
|
||||
import org.nwapw.abacus.function.NumberOperator
|
||||
import org.nwapw.abacus.function.OperatorAssociativity
|
||||
import org.nwapw.abacus.function.OperatorType
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
import org.nwapw.abacus.plugin.StandardPlugin.*
|
||||
|
||||
/**
|
||||
* The power operator.
|
||||
*
|
||||
* This is a standard operator that brings one number to the power of the other.
|
||||
*/
|
||||
class OperatorCaret: NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 2) {
|
||||
|
||||
override fun matchesParams(context: MutableEvaluationContext, params: Array<out NumberInterface>) =
|
||||
params.size == 2
|
||||
&& !(params[0].signum() == 0 && params[1].signum() == 0)
|
||||
&& !(params[0].signum() == -1 && params[1].fractionalPart().signum() != 0)
|
||||
|
||||
override fun applyInternal(context: MutableEvaluationContext, params: Array<out NumberInterface>): NumberInterface {
|
||||
val implementation = context.inheritedNumberImplementation
|
||||
if (params[0].signum() == 0)
|
||||
return implementation.instanceForString("0")
|
||||
else if (params[1].signum() == 0)
|
||||
return implementation.instanceForString("1")
|
||||
//Detect integer bases:
|
||||
if (params[0].fractionalPart().signum() == 0
|
||||
&& FUNCTION_ABS.apply(context, params[1]) < implementation.instanceForString(Integer.toString(Integer.MAX_VALUE))
|
||||
&& FUNCTION_ABS.apply(context, params[1]) >= implementation.instanceForString("1")) {
|
||||
val newParams = arrayOf(params[0], params[1].fractionalPart())
|
||||
return params[0].intPow(params[1].floor().intValue()) * applyInternal(context, newParams)
|
||||
}
|
||||
return FUNCTION_EXP.apply(context, FUNCTION_LN.apply(context, FUNCTION_ABS.apply(context, params[0])) * params[1])
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.nwapw.abacus.plugin.standard
|
||||
|
||||
import org.nwapw.abacus.context.MutableEvaluationContext
|
||||
import org.nwapw.abacus.function.OperatorAssociativity
|
||||
import org.nwapw.abacus.function.OperatorType
|
||||
import org.nwapw.abacus.function.TreeValueOperator
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
import org.nwapw.abacus.tree.TreeNode
|
||||
import org.nwapw.abacus.tree.VariableNode
|
||||
|
||||
/**
|
||||
* The definition operator.
|
||||
*
|
||||
* This is a standard operator that creates a definition - something that doesn't capture variable values
|
||||
* when it's created, but rather the variables themselves, and changes when the variables it uses change.
|
||||
*/
|
||||
class OperatorDefine: TreeValueOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) {
|
||||
|
||||
override fun matchesParams(context: MutableEvaluationContext, params: Array<out TreeNode>) =
|
||||
params.size == 2 && params[0] is VariableNode
|
||||
|
||||
override fun applyInternal(context: MutableEvaluationContext, params: Array<out TreeNode>): NumberInterface {
|
||||
val assignTo = (params[0] as VariableNode).variable
|
||||
context.setDefinition(assignTo, params[1])
|
||||
return params[1].reduce(context.inheritedReducer)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,11 +6,16 @@ import org.nwapw.abacus.function.OperatorAssociativity
|
||||
import org.nwapw.abacus.function.OperatorType
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
|
||||
/**
|
||||
* The factorial operator.
|
||||
*
|
||||
* This is a standard operator that simply evaluates the factorial of a number.
|
||||
*/
|
||||
class OperatorFactorial: NumberOperator(OperatorAssociativity.LEFT, OperatorType.UNARY_POSTFIX, 0) {
|
||||
|
||||
override fun matchesParams(context: MutableEvaluationContext, params: Array<out NumberInterface>) =
|
||||
params.size == 1
|
||||
&& params[0].fractionalPart().compareTo(context.inheritedNumberImplementation.instanceForString("0")) == 0
|
||||
&& params[0].fractionalPart().signum() == 0
|
||||
&& params[0].signum() >= 0
|
||||
|
||||
override fun applyInternal(context: MutableEvaluationContext, params: Array<out NumberInterface>): NumberInterface {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.nwapw.abacus.plugin.standard
|
||||
|
||||
import org.nwapw.abacus.context.MutableEvaluationContext
|
||||
import org.nwapw.abacus.function.NumberOperator
|
||||
import org.nwapw.abacus.function.OperatorAssociativity
|
||||
import org.nwapw.abacus.function.OperatorType
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
import org.nwapw.abacus.plugin.StandardPlugin.*
|
||||
|
||||
/**
|
||||
* The "N choose R" operator.
|
||||
*
|
||||
* This is a standard operator that returns the number of possible combinations, regardless of order,
|
||||
* of a certain size can be taken out of a pool of a bigger size.
|
||||
*/
|
||||
class OperatorNcr: NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) {
|
||||
|
||||
override fun matchesParams(context: MutableEvaluationContext, params: Array<out NumberInterface>) =
|
||||
params.size == 2 && params[0].fractionalPart().signum() == 0
|
||||
&& params[1].fractionalPart().signum() == 0
|
||||
|
||||
override fun applyInternal(context: MutableEvaluationContext, params: Array<out NumberInterface>) =
|
||||
OP_NPR.apply(context, *params) / OP_FACTORIAL.apply(context, params[1])
|
||||
|
||||
}
|
||||
@@ -6,6 +6,11 @@ import org.nwapw.abacus.function.OperatorAssociativity
|
||||
import org.nwapw.abacus.function.OperatorType
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
|
||||
/**
|
||||
* The negation operator.
|
||||
*
|
||||
* This is a standard operator that negates a number.
|
||||
*/
|
||||
class OperatorNegate: NumberOperator(OperatorAssociativity.LEFT, OperatorType.UNARY_PREFIX, 0) {
|
||||
|
||||
override fun matchesParams(context: MutableEvaluationContext, params: Array<out NumberInterface>) =
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.nwapw.abacus.plugin.standard
|
||||
|
||||
import org.nwapw.abacus.context.MutableEvaluationContext
|
||||
import org.nwapw.abacus.function.NumberOperator
|
||||
import org.nwapw.abacus.function.OperatorAssociativity
|
||||
import org.nwapw.abacus.function.OperatorType
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
|
||||
/**
|
||||
* The "N pick R" operator.
|
||||
*
|
||||
* his is a standard operator that returns the number of possible combinations
|
||||
* of a certain size can be taken out of a pool of a bigger size.
|
||||
*/
|
||||
class OperatorNpr: NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) {
|
||||
|
||||
override fun matchesParams(context: MutableEvaluationContext, params: Array<out NumberInterface>) =
|
||||
params.size == 2 && params[0].fractionalPart().signum() == 0
|
||||
&& params[1].fractionalPart().signum() == 0
|
||||
|
||||
override fun applyInternal(context: MutableEvaluationContext, params: Array<out NumberInterface>): NumberInterface {
|
||||
val implementation = context.inheritedNumberImplementation
|
||||
if (params[0] < params[1] ||
|
||||
params[0].signum() < 0 ||
|
||||
params[0].signum() == 0 && params[1].signum() != 0)
|
||||
return implementation.instanceForString("0")
|
||||
var total = implementation.instanceForString("1")
|
||||
var multiplyBy = params[0]
|
||||
var remainingMultiplications = params[1]
|
||||
val halfway = params[0] / implementation.instanceForString("2")
|
||||
if (remainingMultiplications > halfway) {
|
||||
remainingMultiplications = params[0] - remainingMultiplications
|
||||
}
|
||||
while (remainingMultiplications.signum() > 0) {
|
||||
total *= multiplyBy
|
||||
remainingMultiplications -= implementation.instanceForString("1")
|
||||
multiplyBy -= implementation.instanceForString("1")
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.nwapw.abacus.plugin.standard
|
||||
|
||||
import org.nwapw.abacus.context.MutableEvaluationContext
|
||||
import org.nwapw.abacus.function.OperatorAssociativity
|
||||
import org.nwapw.abacus.function.OperatorType
|
||||
import org.nwapw.abacus.function.TreeValueOperator
|
||||
import org.nwapw.abacus.number.NumberInterface
|
||||
import org.nwapw.abacus.tree.TreeNode
|
||||
import org.nwapw.abacus.tree.VariableNode
|
||||
|
||||
/**
|
||||
* The set operator.
|
||||
*
|
||||
* This is a standard operator that assigns a value to a variable name.
|
||||
*/
|
||||
class OperatorSet: TreeValueOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) {
|
||||
|
||||
override fun matchesParams(context: MutableEvaluationContext, params: Array<out TreeNode>) =
|
||||
params.size == 2 && params[0] is VariableNode
|
||||
|
||||
override fun applyInternal(context: MutableEvaluationContext, params: Array<out TreeNode>): NumberInterface {
|
||||
val assignTo = (params[0] as VariableNode).variable
|
||||
val value = params[1].reduce(context.inheritedReducer)
|
||||
context.setVariable(assignTo, value)
|
||||
return value
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user