2017-09-23 17:13:56 -07:00
|
|
|
package org.nwapw.abacus.plugin.standard.operator
|
2017-09-23 16:19:45 -07:00
|
|
|
|
2017-11-23 02:21:06 -08:00
|
|
|
import org.nwapw.abacus.context.PluginEvaluationContext
|
2017-09-23 16:19:45 -07:00
|
|
|
import org.nwapw.abacus.function.OperatorAssociativity
|
|
|
|
import org.nwapw.abacus.function.OperatorType
|
2017-11-14 23:03:12 -08:00
|
|
|
import org.nwapw.abacus.function.interfaces.NumberOperator
|
2017-09-23 16:19:45 -07:00
|
|
|
import org.nwapw.abacus.number.NumberInterface
|
|
|
|
|
2017-09-23 17:11:05 -07:00
|
|
|
/**
|
|
|
|
* The factorial operator.
|
|
|
|
*
|
|
|
|
* This is a standard operator that simply evaluates the factorial of a number.
|
|
|
|
*/
|
2017-09-23 16:19:45 -07:00
|
|
|
class OperatorFactorial: NumberOperator(OperatorAssociativity.LEFT, OperatorType.UNARY_POSTFIX, 0) {
|
|
|
|
|
2017-11-23 02:21:06 -08:00
|
|
|
override fun matchesParams(context: PluginEvaluationContext, params: Array<out NumberInterface>) =
|
2017-09-23 16:19:45 -07:00
|
|
|
params.size == 1
|
2017-11-03 21:41:46 -07:00
|
|
|
&& params[0].isInteger()
|
2017-09-23 16:19:45 -07:00
|
|
|
&& params[0].signum() >= 0
|
|
|
|
|
2017-11-23 02:21:06 -08:00
|
|
|
override fun applyInternal(context: PluginEvaluationContext, params: Array<out NumberInterface>): NumberInterface {
|
2017-09-23 16:19:45 -07:00
|
|
|
val implementation = context.inheritedNumberImplementation
|
|
|
|
val one = implementation.instanceForString("1")
|
|
|
|
if (params[0].signum() == 0) {
|
|
|
|
return one
|
|
|
|
}
|
|
|
|
var factorial = params[0]
|
|
|
|
var multiplier = params[0] - one
|
|
|
|
//It is necessary to later prevent calls of factorial on anything but non-negative integers.
|
|
|
|
while (multiplier.signum() == 1) {
|
|
|
|
factorial *= multiplier
|
|
|
|
multiplier -= one
|
|
|
|
}
|
|
|
|
return factorial
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|