96 lines
3.1 KiB
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;
|
|
}
|
|
|
|
}
|