transcendental-lisp/src/main/kotlin/function/builtin/math/Modulo.kt

37 lines
1.0 KiB
Kotlin

package function.builtin.math
import error.LispException
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import sexpression.Cons
import sexpression.LispNumber
import sexpression.SExpression
@FunctionNames("MOD", "MODULO", "%")
class Modulo(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setExactNumberOfArguments(2)
setEveryArgumentExpectedType(LispNumber::class.java)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
val dividend = argumentList.first as LispNumber
val divisor = (argumentList.rest as Cons).first as LispNumber
try {
return LispNumber(dividend.value.mod(divisor.value))
} catch (e: ArithmeticException) {
throw ModulusNotPositiveException()
}
}
class ModulusNotPositiveException : LispException() {
override val message = "modulus not positive"
}
}