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

68 lines
2.3 KiB
Java

package function.builtin.predicate;
import function.*;
import function.builtin.cons.LIST;
import sexpression.*;
public class EQUAL extends LispFunction {
private ArgumentValidator argumentValidator;
public EQUAL() {
this.argumentValidator = new ArgumentValidator("EQUAL");
this.argumentValidator.setExactNumberOfArguments(2);
}
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return callRecursive(argumentList);
}
private SExpression callRecursive(Cons argumentList) {
Cons cdr = (Cons) argumentList.getCdr();
SExpression firstArgument = argumentList.getCar();
SExpression secondArgument = cdr.getCar();
if (!isListPair(firstArgument, secondArgument))
return equal(firstArgument, secondArgument);
Cons listOne = (Cons) firstArgument;
Cons listTwo = (Cons) secondArgument;
SExpression listOneCar = listOne.getCar();
SExpression listTwoCar = listTwo.getCar();
SExpression listOneCdr = listOne.getCdr();
SExpression listTwoCdr = listTwo.getCdr();
SExpression carEqual = callRecursive(makeArgumentList(listOneCar, listTwoCar));
SExpression cdrEqual = callRecursive(makeArgumentList(listOneCdr, listTwoCdr));
return logicalConjunction(carEqual, cdrEqual);
}
private boolean isListPair(SExpression firstArgument, SExpression secondArgument) {
return firstArgument.consp() && secondArgument.consp();
}
private SExpression equal(SExpression firstArgument, SExpression secondArgument) {
return isEqual(firstArgument, secondArgument) ? Symbol.T : Nil.getInstance();
}
private boolean isEqual(SExpression firstArgument, SExpression secondArgument) {
return firstArgument.toString().equals(secondArgument.toString());
}
private Cons makeArgumentList(SExpression listOneCar, SExpression listTwoCar) {
return new Cons(listOneCar, LIST.makeList(listTwoCar));
}
private SExpression logicalConjunction(SExpression carEqual, SExpression cdrEqual) {
return bothAreTrue(carEqual, cdrEqual) ? Symbol.T : Nil.getInstance();
}
private boolean bothAreTrue(SExpression carEqual, SExpression cdrEqual) {
return (carEqual == Symbol.T) && (cdrEqual == Symbol.T);
}
}