117 lines
4.0 KiB
Java
117 lines
4.0 KiB
Java
/*
|
|
* Name: Mike Cifelli
|
|
* Course: CIS 443 - Programming Languages
|
|
* Assignment: Lisp Interpreter 2
|
|
*/
|
|
|
|
package eval;
|
|
|
|
import parser.*;
|
|
|
|
/**
|
|
* <code>LET</code> represents the LET form in Lisp.
|
|
*/
|
|
public class LET extends LispFunction {
|
|
|
|
public SExpression call(Cons argList) {
|
|
// make sure we have received at least one argument
|
|
if (argList.nullp()) {
|
|
throw new RuntimeException("too few arguments given to LET");
|
|
}
|
|
|
|
// create a new symbol table on top of the current environment to add
|
|
// all the local variables to
|
|
SymbolTable environment = new SymbolTable(SETF.getEnvironment());
|
|
|
|
SExpression car = argList.getCar();
|
|
Cons cdr = (Cons) argList.getCdr();
|
|
|
|
addVariablesToTable(environment, car);
|
|
SETF.setEnvironment(environment);
|
|
|
|
SExpression retval = Nil.getUniqueInstance();
|
|
|
|
// evaluate all S-expression in the body
|
|
while (cdr.consp()) {
|
|
retval = EVAL.eval(cdr.getCar());
|
|
cdr = (Cons) cdr.getCdr();
|
|
}
|
|
|
|
// restore the environment to its original value
|
|
SETF.setEnvironment(environment.getParent());
|
|
|
|
return retval;
|
|
}
|
|
|
|
// Add a list of variables and their values to the specified symbol table.
|
|
//
|
|
// Parameters: environment - the symbol table to add the variables and
|
|
// their values to (must not be null)
|
|
// vars - a list of variable/value pairs (must be either a
|
|
// proper list of pairs or NIL)
|
|
// Throws: RuntimeException - Indicates that 'vars' is not a proper list or
|
|
// that it contains an member that is not a
|
|
// variable/value pair.
|
|
// Precondition: 'environment' and 'vars' must not be null.
|
|
// Postcondition: All of the variables in 'vars' have been placed into
|
|
// 'environment' with their values.
|
|
private void addVariablesToTable(SymbolTable environment,
|
|
SExpression vars) {
|
|
// makes sure the list of variable/value pairs is a list
|
|
if (! vars.listp()) {
|
|
throw new RuntimeException("LET: " + vars +
|
|
" is not a properly formatted" +
|
|
" variable/value pair list");
|
|
}
|
|
|
|
// add all variables in 'vars' to 'environment'
|
|
while (vars.consp()) {
|
|
Cons varList = (Cons) vars;
|
|
SExpression varListCar = varList.getCar();
|
|
|
|
// make sure this variable/value pair is a list
|
|
if (! varListCar.consp()) {
|
|
throw new RuntimeException("LET: " + varListCar +
|
|
" is not a properly formatted" +
|
|
" variable/value pair");
|
|
}
|
|
|
|
Cons varSpec = (Cons) varListCar;
|
|
SExpression symbol = varSpec.getCar();
|
|
SExpression varSpecCdr = varSpec.getCdr();
|
|
|
|
// make sure this variable pair has a value associated with it
|
|
if (! varSpecCdr.consp()) {
|
|
throw new RuntimeException("LET: illegal variable " +
|
|
"specification " + varSpec);
|
|
}
|
|
|
|
Cons varValue = (Cons) varSpecCdr;
|
|
SExpression value = varValue.getCar();
|
|
|
|
// make sure there are no more members of this variable/value pair
|
|
// and that 'symbol' is actually a symbol
|
|
if ((! varValue.getCdr().nullp()) || (! symbol.symbolp())) {
|
|
throw new RuntimeException("LET: illegal variable " +
|
|
"specification " + varSpec);
|
|
}
|
|
|
|
environment.put(symbol.toString(), value);
|
|
|
|
vars = varList.getCdr();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determine if the arguments passed to this Lisp function should be
|
|
* evaluated.
|
|
*
|
|
* @return
|
|
* <code>false</code>
|
|
*/
|
|
public boolean evaluateArguments() {
|
|
return false;
|
|
}
|
|
|
|
}
|