package function.builtin.predicate import function.ArgumentValidator import function.FunctionNames import function.LispFunction import sexpression.Cons import sexpression.LispNumber import sexpression.Nil import sexpression.SExpression import sexpression.Symbol.Companion.T @FunctionNames(">") class NumericGreater(name: String) : LispFunction() { private val argumentValidator = ArgumentValidator(name).apply { setMinimumNumberOfArguments(1) setEveryArgumentExpectedType(LispNumber::class.java) } override fun call(argumentList: Cons): SExpression { argumentValidator.validate(argumentList) return callTailRecursive(argumentList) } private tailrec fun callTailRecursive(argumentList: Cons): SExpression { val remainingArguments = argumentList.rest as Cons if (remainingArguments.isNull) return T val firstArgument = argumentList.first val secondArgument = remainingArguments.first val number1 = firstArgument as LispNumber val number2 = secondArgument as LispNumber return if (number1.value > number2.value) callTailRecursive(remainingArguments) else Nil } }