package function.builtin.special; import static function.builtin.cons.LIST.makeList; import function.*; import sexpression.*; public class LAMBDA extends LispSpecialFunction { public static boolean isLambdaExpression(SExpression sexpr) { if (sexpr.isCons()) { SExpression first = ((Cons) sexpr).getFirst(); return "LAMBDA".equals(first.toString()); } return false; } public static UserDefinedFunction createFunction(Cons lambdaExpression) { SExpression rest = lambdaExpression.getRest(); ArgumentValidator lambdaValidator = new ArgumentValidator("LAMBDA|create|"); lambdaValidator.setEveryArgumentExpectedType(Cons.class); lambdaValidator.validate(makeList(rest)); LambdaExpression lambda = new LAMBDA().call((Cons) rest); return lambda.getFunction(); } private ArgumentValidator argumentValidator; private ArgumentValidator lambdaListValidator; public LAMBDA() { this.argumentValidator = new ArgumentValidator("LAMBDA"); this.argumentValidator.setFirstArgumentExpectedType(Cons.class); this.argumentValidator.setMinimumNumberOfArguments(1); this.lambdaListValidator = new ArgumentValidator("LAMBDA|lambda-list|"); this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class); } public LambdaExpression call(Cons argumentList) { argumentValidator.validate(argumentList); SExpression first = argumentList.getFirst(); Cons lambdaList = (Cons) first; Cons body = (Cons) argumentList.getRest(); lambdaListValidator.validate(lambdaList); UserDefinedFunction function = new UserDefinedFunction(":LAMBDA", lambdaList, body); return new LambdaExpression(makeOriginalLambdaExpression(argumentList), function); } private Cons makeOriginalLambdaExpression(Cons argumentList) { return new Cons(new Symbol("LAMBDA"), argumentList); } }