package function.builtin; import function.LispFunction; import sexpression.*; public class COND extends LispFunction { public SExpression call(Cons argList) { if (argList.nullp()) { // return NIL if there are were no arguments passed to COND return Nil.getUniqueInstance(); } SExpression argCar = argList.getCar(); // first clause Cons argCdr = (Cons) argList.getCdr(); // list of remaining clauses // make sure the first clause is a list and is not NIL if (argCar.consp()) { Cons clause = (Cons) argCar; SExpression test = EVAL.eval(clause.getCar()); if (test != Nil.getUniqueInstance()) { // the car of this clause is true, so we evaluate its cdr SExpression cdr = clause.getCdr(); SExpression retval = test; // evaluate all the S-expressions in the cdr of the clause while (cdr.consp()) { retval = EVAL.eval(((Cons) cdr).getCar()); cdr = ((Cons) cdr).getCdr(); } // return the value of the last S-expression evaluated return retval; } // the car of this clause is false, so we test any remaining // clauses // check if the list of remaining clauses is a list and is not NIL if (argCdr.consp()) { return call(argCdr); } // there are no remaining clauses, so we return NIL return Nil.getUniqueInstance(); } throw new RuntimeException("COND: clause " + argCar + " should be a list"); } public boolean evaluateArguments() { return false; } }