package function.builtin.special import function.ArgumentValidator import function.FunctionNames import function.LispSpecialFunction import function.builtin.Eval.Companion.eval import sexpression.Cons import sexpression.SExpression @FunctionNames("OR") class Or(name: String) : LispSpecialFunction() { private val argumentValidator = ArgumentValidator(name) override fun call(argumentList: Cons): SExpression { argumentValidator.validate(argumentList) return callTailRecursive(argumentList) } private tailrec fun callTailRecursive(argumentList: Cons): SExpression { val currentValue = eval(argumentList.first) val remainingValues = argumentList.rest as Cons return if (remainingValues.isNull || !currentValue.isNull) currentValue else callTailRecursive(remainingValues) } }