package eval; import sexpression.*; /** * <code>LAMBDA</code> represents the LAMBDA form in Lisp. */ public class LAMBDA extends LispFunction { /** * Determine if the given S-expression is a lambda expression. * * @param sexpr * the S-expression to test (must not be null) * @return <code>true</code> if <code>sexpr</code> is a valid lambda expression; * <code>false</code> otherwise */ public static boolean isLambdaExpression(SExpression sexpr) { if (sexpr.consp()) { SExpression first = ((Cons) sexpr).getCar(); return "LAMBDA".equals(first.toString()); } return false; } /** * Create an internal representation of a user-defined function from the specified lambda * expression. * * @param lexpr * the lambda expression to create the function from (must not be null) * @return an internal representation of a user-defined function created from <code>lexpr</code> * @throws RuntimeException * Indicates that <code>lexpr</code> is not a valid lambda expression. */ public static UserDefinedFunction createFunction(Cons lexpr) { LAMBDA lambda = new LAMBDA(); SExpression cdr = lexpr.getCdr(); // make sure lexpr is a proper list if (!cdr.consp()) { throw new RuntimeException("invalid lambda expression"); } else if (EVAL.isDotted((Cons) cdr)) { throw new RuntimeException("dotted lambda expression " + lexpr); } Cons rest = (Cons) cdr; return lambda.call(rest).getFunction(); } // The minimum number of arguments that LAMBDA takes. private static final int MIN_ARGS = 2; public LambdaExpression call(Cons argList) { // retrieve the number of arguments passed to LAMBDA int argListLength = LENGTH.getLength(argList); // make sure we have received the proper number of arguments if (argListLength < MIN_ARGS) { Cons originalSExpr = new Cons(new Symbol("LAMBDA"), argList); String errMsg = "too few arguments given to LAMBDA: " + originalSExpr; throw new RuntimeException(errMsg); } SExpression car = argList.getCar(); // make sure the list of arguments is a proper list if (!car.listp()) { throw new RuntimeException("LAMBDA: " + car + " is not a list"); } else if (EVAL.isDotted((Cons) car)) { throw new RuntimeException("LAMBDA: " + car + " must be a proper list"); } Cons lambdaList = (Cons) car; Cons body = (Cons) argList.getCdr(); Cons lexpr = new Cons(new Symbol("LAMBDA"), argList); UserDefinedFunction function = new UserDefinedFunction(":LAMBDA", lambdaList, body); return new LambdaExpression(lexpr, function); } /** * Determine if the arguments passed to this Lisp function should be evaluated. * * @return <code>false</code> */ public boolean evaluateArguments() { return false; } }