transcendental-lisp/eval/LENGTH.java

70 lines
1.9 KiB
Java
Raw Normal View History

2016-12-07 14:16:45 -05:00
/*
* Name: Mike Cifelli
* Course: CIS 443 - Programming Languages
* Assignment: Lisp Interpreter 1
*/
package eval;
import parser.*;
/**
* <code>LENGTH</code> 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 <code>list</code>
*/
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);
}
}