From 5351168763797213dbcace59bb17e8c9a9a3e0a2 Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Fri, 27 Jan 2017 16:19:09 -0500 Subject: [PATCH] Started refactoring UserDefinedFunction --- src/function/UserDefinedFunction.java | 46 +++++++++++++++------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/function/UserDefinedFunction.java b/src/function/UserDefinedFunction.java index b8f3afe..a0ce867 100644 --- a/src/function/UserDefinedFunction.java +++ b/src/function/UserDefinedFunction.java @@ -12,7 +12,7 @@ public class UserDefinedFunction extends LispFunction { private String name; private Cons body; private Cons lambdaExpression; - private SymbolTable environment; + private SymbolTable scope; private ArrayList formalParameters; private ArgumentValidator argumentValidator; @@ -20,7 +20,7 @@ public class UserDefinedFunction extends LispFunction { this.name = name; this.body = 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()) this.formalParameters.add(lambdaList.getCar().toString()); @@ -29,46 +29,52 @@ public class UserDefinedFunction extends LispFunction { this.argumentValidator.setExactNumberOfArguments(this.formalParameters.size()); } - public SExpression call(Cons argList) { - argumentValidator.validate(argList); - - // push a new symbol table onto this function's environment (for its - // parameters) - environment = new SymbolTable(environment); + public SExpression call(Cons argumentList) { + argumentValidator.validate(argumentList); // bind the values of the arguments to the formal parameter names - for (String param : formalParameters) { - SExpression currentArg = argList.getCar(); - environment.put(param, currentArg); - argList = (Cons) argList.getCdr(); - } + bindParameterValues(argumentList); // store the environment of the S-expression that called this function // (the current environment) - SymbolTable currentEnvironment = SETF.getSymbolTable(); + SymbolTable callingScope = SETF.getSymbolTable(); // replace the current environment with the environment of this // function - SETF.setSymbolTable(environment); + SETF.setSymbolTable(scope); Cons currentSExpression = body; - SExpression retval = null; + SExpression lastValue = null; // evaluate all the S-expressions making up this function's body while (currentSExpression.consp()) { - retval = EVAL.eval(currentSExpression.getCar()); + lastValue = EVAL.eval(currentSExpression.getCar()); currentSExpression = (Cons) currentSExpression.getCdr(); } // replace the environment of the S-expression that called this // function - SETF.setSymbolTable(currentEnvironment); + SETF.setSymbolTable(callingScope); // remove the bindings of the arguments to the formal parameter names // 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() {