transcendental-lisp/src/eval/LAMBDA.java

96 lines
3.1 KiB
Java

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