package function.builtin; import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; import sexpression.SExpression; import table.FunctionTable; import static function.builtin.Eval.applyFunction; import static function.builtin.Eval.lookupFunctionOrLambda; @FunctionNames({ "APPLY" }) public class APPLY extends LispFunction { public static SExpression apply(Cons argumentList) { return FunctionTable.INSTANCE.lookupFunction("APPLY").call(argumentList); } private ArgumentValidator argumentValidator; public APPLY(String name) { this.argumentValidator = new ArgumentValidator(name); this.argumentValidator.setExactNumberOfArguments(2); this.argumentValidator.setTrailingArgumentExpectedType(Cons.class); } @Override public SExpression call(Cons argumentList) { argumentValidator.validate(argumentList); Cons rest = (Cons) argumentList.getRest(); Cons functionArguments = (Cons) rest.getFirst(); SExpression functionName = argumentList.getFirst(); LispFunction function = lookupFunctionOrLambda(functionName); return applyFunction(function, functionArguments); } }