Started refactoring UserDefinedFunction
This commit is contained in:
parent
27fdc7b328
commit
5351168763
|
@ -12,7 +12,7 @@ public class UserDefinedFunction extends LispFunction {
|
||||||
private String name;
|
private String name;
|
||||||
private Cons body;
|
private Cons body;
|
||||||
private Cons lambdaExpression;
|
private Cons lambdaExpression;
|
||||||
private SymbolTable environment;
|
private SymbolTable scope;
|
||||||
private ArrayList<String> formalParameters;
|
private ArrayList<String> formalParameters;
|
||||||
private ArgumentValidator argumentValidator;
|
private ArgumentValidator argumentValidator;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ public class UserDefinedFunction extends LispFunction {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.lambdaExpression = new Cons(new Symbol(name), new Cons(lambdaList, body));
|
this.lambdaExpression = new Cons(new Symbol(name), new Cons(lambdaList, body));
|
||||||
this.environment = SETF.getSymbolTable();
|
this.scope = SETF.getSymbolTable();
|
||||||
|
|
||||||
for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getCdr())
|
for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getCdr())
|
||||||
this.formalParameters.add(lambdaList.getCar().toString());
|
this.formalParameters.add(lambdaList.getCar().toString());
|
||||||
|
@ -29,46 +29,52 @@ public class UserDefinedFunction extends LispFunction {
|
||||||
this.argumentValidator.setExactNumberOfArguments(this.formalParameters.size());
|
this.argumentValidator.setExactNumberOfArguments(this.formalParameters.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public SExpression call(Cons argList) {
|
public SExpression call(Cons argumentList) {
|
||||||
argumentValidator.validate(argList);
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
// push a new symbol table onto this function's environment (for its
|
|
||||||
// parameters)
|
|
||||||
environment = new SymbolTable(environment);
|
|
||||||
|
|
||||||
// bind the values of the arguments to the formal parameter names
|
// bind the values of the arguments to the formal parameter names
|
||||||
for (String param : formalParameters) {
|
bindParameterValues(argumentList);
|
||||||
SExpression currentArg = argList.getCar();
|
|
||||||
environment.put(param, currentArg);
|
|
||||||
argList = (Cons) argList.getCdr();
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the environment of the S-expression that called this function
|
// store the environment of the S-expression that called this function
|
||||||
// (the current environment)
|
// (the current environment)
|
||||||
SymbolTable currentEnvironment = SETF.getSymbolTable();
|
SymbolTable callingScope = SETF.getSymbolTable();
|
||||||
|
|
||||||
// replace the current environment with the environment of this
|
// replace the current environment with the environment of this
|
||||||
// function
|
// function
|
||||||
SETF.setSymbolTable(environment);
|
SETF.setSymbolTable(scope);
|
||||||
|
|
||||||
Cons currentSExpression = body;
|
Cons currentSExpression = body;
|
||||||
SExpression retval = null;
|
SExpression lastValue = null;
|
||||||
|
|
||||||
// evaluate all the S-expressions making up this function's body
|
// evaluate all the S-expressions making up this function's body
|
||||||
while (currentSExpression.consp()) {
|
while (currentSExpression.consp()) {
|
||||||
retval = EVAL.eval(currentSExpression.getCar());
|
lastValue = EVAL.eval(currentSExpression.getCar());
|
||||||
currentSExpression = (Cons) currentSExpression.getCdr();
|
currentSExpression = (Cons) currentSExpression.getCdr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace the environment of the S-expression that called this
|
// replace the environment of the S-expression that called this
|
||||||
// function
|
// function
|
||||||
SETF.setSymbolTable(currentEnvironment);
|
SETF.setSymbolTable(callingScope);
|
||||||
|
|
||||||
// remove the bindings of the arguments to the formal parameter names
|
// remove the bindings of the arguments to the formal parameter names
|
||||||
// in the environment of this function
|
// in the environment of this function
|
||||||
environment = new SymbolTable(environment.getParent());
|
releaseParameterValues();
|
||||||
|
|
||||||
return retval;
|
return lastValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindParameterValues(Cons argumentList) {
|
||||||
|
scope = new SymbolTable(scope);
|
||||||
|
|
||||||
|
for (String parameter : formalParameters) {
|
||||||
|
SExpression currentArg = argumentList.getCar();
|
||||||
|
scope.put(parameter, currentArg);
|
||||||
|
argumentList = (Cons) argumentList.getCdr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void releaseParameterValues() {
|
||||||
|
scope = new SymbolTable(scope.getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cons getLambdaExpression() {
|
public Cons getLambdaExpression() {
|
||||||
|
|
Loading…
Reference in New Issue