transcendental-lisp/eval/DEFUN.java

83 lines
2.5 KiB
Java

/*
* Name: Mike Cifelli
* Course: CIS 443 - Programming Languages
* Assignment: Lisp Interpreter 2
*/
package eval;
import parser.*;
import java.util.HashMap;
/**
* <code>DEFUN</code> represents the DEFUN form in Lisp.
*/
public class DEFUN extends LispFunction {
// The minimum number of arguments that DEFUN takes.
private static final int MIN_ARGS = 3;
public SExpression call(Cons argList) {
// retrieve the number of arguments passed to DEFUN
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("DEFUN"), argList);
String errMsg = "too few arguments given to DEFUN: " +
originalSExpr;
throw new RuntimeException(errMsg);
}
SExpression name = argList.getCar(); // name of the function
// make sure the function name is a symbol
if (! name.symbolp()) {
throw new RuntimeException("DEFUN: " + name + " is not a symbol");
}
Cons cdr = (Cons) argList.getCdr();
SExpression cadr = cdr.getCar();
// make sure the list of arguments (lambda list) is a proper list
if (! cadr.listp()) {
throw new RuntimeException("DEFUN: " + cadr + " is not a list");
} else if (EVAL.isDotted((Cons) cadr)) {
throw new RuntimeException("DEFUN: " + cadr +
" is not a proper list");
}
Cons lambdaList = (Cons) cadr; // lambda list of the function
// list of S-expressions making up the body of the function
Cons body = (Cons) cdr.getCdr();
HashMap<String, LispFunction> functionTable = EVAL.getFunctionTable();
// give a warning if this function has already been defined
if (functionTable.containsKey(name.toString())) {
System.out.println("WARNING: redefining function " +
name.toString());
}
// place the function in the function table
functionTable.put(name.toString(),
new UDFunction(name.toString(), lambdaList, body));
return name;
}
/**
* Determine if the arguments passed to this Lisp function should be
* evaluated.
*
* @return
* <code>false</code>
*/
public boolean evaluateArguments() {
return false;
}
}