package function.builtin; import function.*; import sexpression.*; public class APPLY extends LispFunction { private static final int NUMBER_OF_ARGUMENTS = 2; private ArgumentValidator argumentValidator; public static SExpression apply(Cons argList) { return new APPLY().call(argList); } public APPLY() { this.argumentValidator = new ArgumentValidator("APPLY"); this.argumentValidator.setExactNumberOfArguments(NUMBER_OF_ARGUMENTS); } public SExpression call(Cons argList) { argumentValidator.validate(argList); Cons cdr = (Cons) argList.getCdr(); SExpression functionName = argList.getCar(); SExpression argumentList = cdr.getCar(); if (argumentList.listp()) { LispFunction function = EVAL.lookupFunction(functionName.toString()); if (function == null) { if (functionName.functionp()) { function = ((LambdaExpression) functionName).getFunction(); } else if (LAMBDA.isLambdaExpression(functionName)) { Cons lexpr = (Cons) functionName; function = LAMBDA.createFunction(lexpr); } else { throw new RuntimeException("undefined function " + functionName); } } return function.call((Cons) argumentList); } throw new RuntimeException("APPLY: " + argumentList + " is not a list"); } }