Fixed a bug with how Labdas evaluate their arguments.

Arguments should be evaluated in the calling scope, but due to the way labdas
were constructing a new symbol table, the arguments were being evaluated inside
the closure scope.
This commit is contained in:
Jonathan Bernard 2010-04-20 11:18:09 -05:00
parent 794467003a
commit 99a3601896
2 changed files with 20 additions and 2 deletions

View File

@ -1,9 +1,10 @@
#Tue, 20 Apr 2010 11:13:19 -0500
#Tue Feb 09 14:02:30 CST 2010
build.dir=build
src.dir=src
grammar.output.dir=${src.dir}/edu/utexas/cs345/jdblisp/parser
build.jar=${build.dir}/JCLisp-${application.version}.${build.number}.jar
build.number=15
build.number=17
dist.dir=dist
javacc.home=${lib.dir}/javacc
dist.jar=${dist.dir}/JCLisp-${application.version}.jar

View File

@ -1,5 +1,6 @@
package edu.utexas.cs345.jdblisp;
import java.util.ArrayList;
/**
* Lambda
*/
@ -45,8 +46,24 @@ public class Lambda extends FunctionEntry {
@Override
public SExp call(SymbolTable symbolTable, Seq arguments)
throws LispException {
// we are going to pass a ClosureSymbolTable into the
// FunctionEntry.call() method. But the first thing FE.call() is going
// to do is evaluate the arguments and bind them to the parameters
// expected by the function (lambda in this case). The
// ClosureSymbolTable looks in the closure context first, then in the
// calling context. This is correct inside the body of the closure but
// incorrect for the argument evaluation, which should happen in the
// calling context, so let's preemptivly evaluate the arguments.
Seq evaledArguments;
ArrayList<SExp> temp = new ArrayList<SExp>();
for (;arguments != null; arguments = arguments.cdr)
temp.add(arguments.car.eval(symbolTable));
evaledArguments = new Seq(temp.toArray(new SExp[]{}));
return super.call(new ClosureSymbolTable(symbolTable, closure),
arguments);
evaledArguments);
}
}