Exceptions!!!
This commit is contained in:
+39
-6
@@ -1,6 +1,10 @@
|
||||
#include "list.h"
|
||||
|
||||
#include "function.h"
|
||||
#include "stack.h"
|
||||
|
||||
DEFINE_SYMBOL(circular_list_error, "circular-list-error");
|
||||
DEFINE_CONDITION_CLASS(circular_list_error, error);
|
||||
|
||||
intptr_t list_length(LispVal *list) {
|
||||
assert(LISTP(list));
|
||||
@@ -32,21 +36,24 @@ DEFUN(cons, "cons", (LispVal * car, LispVal *cdr), "(car cdr)",
|
||||
}
|
||||
|
||||
DEFUN(length, "length", (LispVal * list), "(list)", "") {
|
||||
// TODO type check
|
||||
// TODO list may be circular
|
||||
return MAKE_FIXNUM(list_length(list));
|
||||
CHECK_LISTP(list);
|
||||
intptr_t len = list_length(list);
|
||||
if (len == -1) {
|
||||
lisp_signal(Qcircular_list_error, Qnil);
|
||||
}
|
||||
return MAKE_FIXNUM(len);
|
||||
}
|
||||
|
||||
DEFUN(length_eq, "length=", (LispVal * list, LispVal *length), "(list length)",
|
||||
"Return non-nil if LIST's length is LENGTH.") {
|
||||
// TODO type check
|
||||
CHECK_LISTP(list);
|
||||
return list_length_eq(list, XFIXNUM(length)) ? Qt : Qnil;
|
||||
}
|
||||
|
||||
DEFUN(nreverse, "nreverse", (LispVal * list), "(list)", "") {
|
||||
// TODO type checking
|
||||
LispVal *rev = Qnil;
|
||||
while (!NILP(list)) {
|
||||
CHECK_LISTP(list);
|
||||
LispVal *next = XCDR(list);
|
||||
RPLACD(list, rev);
|
||||
rev = list;
|
||||
@@ -63,6 +70,22 @@ DEFUN(list, "list", (LispVal * args), "(&rest args)", "") {
|
||||
return args;
|
||||
}
|
||||
|
||||
LispVal *nth(size_t n, LispVal *list) {
|
||||
size_t i = 0;
|
||||
DOTAILS(rest, list) {
|
||||
if (i == n) {
|
||||
return XCAR(rest);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN(nth, "list", (LispVal * n, LispVal *list), "(n list)", "") {
|
||||
CHECK_TYPE(n, TYPE_FIXNUM);
|
||||
return nth(XFIXNUM(n), list);
|
||||
}
|
||||
|
||||
DEFUN(member, "member", (LispVal * elt, LispVal *list, LispVal *pred),
|
||||
"(elt list &optional pred)", "") {
|
||||
if (NILP(pred) || pred == Qeq) {
|
||||
@@ -74,7 +97,7 @@ DEFUN(member, "member", (LispVal * elt, LispVal *list, LispVal *pred),
|
||||
}
|
||||
} else {
|
||||
DOTAILS(rest, list) {
|
||||
if (CALL(pred, elt, XCAR(rest))) {
|
||||
if (!NILP(CALL(pred, elt, XCAR(rest)))) {
|
||||
return rest;
|
||||
}
|
||||
}
|
||||
@@ -82,6 +105,16 @@ DEFUN(member, "member", (LispVal * elt, LispVal *list, LispVal *pred),
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN(member_if, "member-if", (LispVal * pred, LispVal *list), "(pred list)",
|
||||
"") {
|
||||
DOTAILS(rest, list) {
|
||||
if (!NILP(CALL(pred, XCAR(rest)))) {
|
||||
return rest;
|
||||
}
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN(plist_put, "plist-put", (LispVal * plist, LispVal *prop, LispVal *value),
|
||||
"(plist prop value)", "") {
|
||||
CHECK_LISTP(plist);
|
||||
|
||||
Reference in New Issue
Block a user