/*
* Name: Mike Cifelli
* Course: CIS 443 - Programming Languages
* Assignment: Lisp Interpreter 1
*/
package eval;
import parser.*;
/**
* LENGTH
represents the LENGTH function in Lisp.
*/
public class LENGTH extends LispFunction {
/**
* Returns the length of the given list.
*
* @param list
* the list to determine the length of
* @return
* the length of list
*/
public static int getLength(Cons list) {
LENGTH lengthFunction = new LENGTH();
LispNumber length = lengthFunction.call(LIST.makeList(list));
return length.getValue();
}
public LispNumber call(Cons argList) {
// make sure we have received at least one argument
if (argList.nullp()) {
Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
throw new RuntimeException("too few arguments given to LENGTH: " +
originalSExpr);
}
SExpression argCar = argList.getCar();
SExpression argCdr = argList.getCdr();
// make sure we have received only one argument
if (! argCdr.nullp()) {
Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
throw new RuntimeException("too many arguments given to LENGTH: " +
originalSExpr);
}
// make sure that the argument is a list
if (argCar.listp()) {
Cons arg = (Cons) argCar;
if (arg.nullp()) {
return new LispNumber(0);
}
Cons cdr = LIST.makeList(arg.getCdr());
LispNumber cdrLength = call(cdr);
return new LispNumber(1 + cdrLength.getValue());
}
throw new RuntimeException("LENGTH: a proper list must not end with " +
argCar);
}
}