transcendental-lisp/src/function/builtin/special/DEFUN.java

64 lines
2.2 KiB
Java

package function.builtin.special;
import java.text.MessageFormat;
import environment.Environment;
import function.*;
import function.builtin.cons.LIST;
import sexpression.*;
import table.FunctionTable;
public class DEFUN extends LispFunction {
private ArgumentValidator argumentValidator;
private ArgumentValidator lambdaListIsListValidator;
private ArgumentValidator lambdaListValidator;
private Environment environment;
public DEFUN() {
this.argumentValidator = new ArgumentValidator("DEFUN");
this.argumentValidator.setMinimumNumberOfArguments(2);
this.argumentValidator.setFirstArgumentExpectedType(Symbol.class);
this.lambdaListIsListValidator = new ArgumentValidator("DEFUN|lambda-list|");
this.lambdaListIsListValidator.setEveryArgumentExpectedType(Cons.class);
this.lambdaListValidator = new ArgumentValidator("DEFUN|parameter|");
this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class);
this.environment = Environment.getInstance();
}
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons remainingArguments = (Cons) argumentList.getCdr();
SExpression functionName = argumentList.getCar();
SExpression secondArgument = remainingArguments.getCar();
lambdaListIsListValidator.validate(LIST.makeList(secondArgument));
Cons lambdaList = (Cons) secondArgument;
lambdaListValidator.validate(lambdaList);
Cons functionBody = (Cons) remainingArguments.getCdr();
UserDefinedFunction function = new UserDefinedFunction(functionName.toString(), lambdaList, functionBody);
if (FunctionTable.isAlreadyDefined(functionName.toString()))
printWarning(functionName);
FunctionTable.defineFunction(functionName.toString(), function);
return functionName;
}
private void printWarning(SExpression functionName) {
String message = MessageFormat.format("WARNING: redefining function {0}", functionName.toString());
environment.getOutput().println(message);
}
public boolean evaluateArguments() {
return false;
}
}