76 lines
2.1 KiB
Java
76 lines
2.1 KiB
Java
package function.builtin.cons;
|
|
|
|
import static sexpression.Nil.NIL;
|
|
import static table.FunctionTable.lookupFunction;
|
|
|
|
import function.ArgumentValidator;
|
|
import function.FunctionNames;
|
|
import function.LispFunction;
|
|
import sexpression.Cons;
|
|
|
|
@FunctionNames({ "APPEND" })
|
|
public class APPEND extends LispFunction {
|
|
|
|
public static Cons append(Cons firstList, Cons secondList) {
|
|
return lookupAppend().appendLists(firstList, secondList);
|
|
}
|
|
|
|
private static APPEND lookupAppend() {
|
|
return (APPEND) lookupFunction("APPEND");
|
|
}
|
|
|
|
private ArgumentValidator argumentValidator;
|
|
private ArgumentValidator firstListValidator;
|
|
|
|
public APPEND(String name) {
|
|
this.argumentValidator = new ArgumentValidator(name);
|
|
this.argumentValidator.setExactNumberOfArguments(2);
|
|
this.argumentValidator.setEveryArgumentExpectedType(Cons.class);
|
|
this.firstListValidator = new ArgumentValidator(name + "|first-list|");
|
|
}
|
|
|
|
@Override
|
|
public Cons call(Cons argumentList) {
|
|
argumentValidator.validate(argumentList);
|
|
|
|
Cons rest = (Cons) argumentList.getRest();
|
|
Cons firstList = (Cons) argumentList.getFirst();
|
|
Cons secondList = (Cons) rest.getFirst();
|
|
|
|
return appendLists(firstList, secondList);
|
|
}
|
|
|
|
private Cons appendLists(Cons firstList, Cons secondList) {
|
|
firstListValidator.validate(firstList);
|
|
|
|
if (firstList.isNull())
|
|
return secondList;
|
|
|
|
Cons appendedLists = copy(firstList);
|
|
getLastItem(appendedLists).setRest(secondList);
|
|
|
|
return appendedLists;
|
|
}
|
|
|
|
private Cons copy(Cons list) {
|
|
Cons newList = new Cons(list.getFirst(), NIL);
|
|
Cons builder = newList;
|
|
|
|
for (Cons iterator = (Cons) list.getRest(); iterator.isCons(); iterator = (Cons) iterator.getRest()) {
|
|
builder.setRest(new Cons(iterator.getFirst(), NIL));
|
|
builder = (Cons) builder.getRest();
|
|
}
|
|
|
|
return newList;
|
|
}
|
|
|
|
private Cons getLastItem(Cons list) {
|
|
Cons tail = list;
|
|
|
|
while (tail.getRest().isCons())
|
|
tail = (Cons) tail.getRest();
|
|
|
|
return tail;
|
|
}
|
|
}
|