/* * Name: Mike Cifelli * Course: CIS 443 - Programming Languages * Assignment: Lisp Interpreter 2 */ package eval; import parser.*; /** * LET 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 * false */ public boolean evaluateArguments() { return false; } }