transcendental-lisp/src/function/builtin/predicate/NUMERIC_EQUAL.java

56 lines
1.7 KiB
Java

package function.builtin.predicate;
import static recursion.TailCalls.done;
import static recursion.TailCalls.tailCall;
import static sexpression.Nil.NIL;
import static sexpression.Symbol.T;
import function.ArgumentValidator;
import function.FunctionNames;
import function.LispFunction;
import recursion.TailCall;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
@FunctionNames({ "=" })
public class NUMERIC_EQUAL extends LispFunction {
private ArgumentValidator argumentValidator;
public NUMERIC_EQUAL(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setMinimumNumberOfArguments(1);
this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return callTailRecursive(argumentList).invoke();
}
private TailCall<SExpression> callTailRecursive(Cons argumentList) {
Cons remainingArguments = (Cons) argumentList.getRest();
if (remainingArguments.isNull())
return done(T);
SExpression firstArgument = argumentList.getFirst();
LispNumber number1 = (LispNumber) firstArgument;
SExpression secondArgument = remainingArguments.getFirst();
LispNumber number2 = (LispNumber) secondArgument;
if (!isEqual(number1, number2))
return done(NIL);
return tailCall(() -> callTailRecursive(remainingArguments));
}
private boolean isEqual(LispNumber number1, LispNumber number2) {
return number1.getValue().equals(number2.getValue());
}
}