transcendental-lisp/eval/LAMBDA.java

109 lines
3.2 KiB
Java
Raw Normal View History

2016-12-07 14:16:45 -05:00
/*
* Name: Mike Cifelli
* Course: CIS 443 - Programming Languages
* Assignment: Lisp Interpreter 2
*/
package eval;
import parser.*;
/**
* <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 UDFunction 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);
UDFunction function = new UDFunction(":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;
}
}