transcendental-lisp/src/function/builtin/special/LAMBDA.java

63 lines
2.0 KiB
Java

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);
}
}