package function.builtin.special;

import static function.builtin.EVAL.eval;

import function.*;
import sexpression.*;

@FunctionNames({ "AND" })
public class AND extends LispSpecialFunction {

    private ArgumentValidator argumentValidator;

    public AND() {
        this.argumentValidator = new ArgumentValidator("AND");
    }

    public SExpression call(Cons argumentList) {
        argumentValidator.validate(argumentList);

        return callTailRecursive(argumentList, Symbol.T);
    }

    private SExpression callTailRecursive(Cons argumentList, SExpression lastValue) {
        SExpression currentValue = eval(argumentList.getFirst());
        Cons remainingValues = (Cons) argumentList.getRest();

        if (argumentList.isNull())
            return lastValue;

        if (currentValue.isNull())
            return currentValue;

        return callTailRecursive(remainingValues, currentValue);
    }

}
