Macro expansion!
This commit is contained in:
+57
-2
@@ -35,6 +35,16 @@ DEFUN(cons, "cons", (LispVal * car, LispVal *cdr), "(car cdr)",
|
||||
return CONS(car, cdr);
|
||||
}
|
||||
|
||||
DEFUN(car, "car", (LispVal * list), "(list)", "") {
|
||||
CHECK_LISTP(list);
|
||||
return NILP(list) ? Qnil : XCAR(list);
|
||||
}
|
||||
|
||||
DEFUN(cdr, "cdr", (LispVal * list), "(list)", "") {
|
||||
CHECK_LISTP(list);
|
||||
return NILP(list) ? Qnil : XCDR(list);
|
||||
}
|
||||
|
||||
DEFUN(length, "length", (LispVal * list), "(list)", "") {
|
||||
CHECK_LISTP(list);
|
||||
intptr_t len = list_length(list);
|
||||
@@ -96,11 +106,30 @@ DEFUN(list, "list", (LispVal * args), "(&rest args)", "") {
|
||||
return args;
|
||||
}
|
||||
|
||||
DEFUN(copy_list, "copy-list", (LispVal * list), "(list)", "") {
|
||||
LispVal *start = Qnil;
|
||||
LispVal *end = NULL;
|
||||
DOTAILS(rest, list) {
|
||||
if (!CONSP(rest)) {
|
||||
RPLACD(end, rest);
|
||||
break;
|
||||
}
|
||||
if (NILP(start)) {
|
||||
start = CONS(XCAR(rest), Qnil);
|
||||
end = start;
|
||||
} else {
|
||||
RPLACD(end, CONS(XCAR(rest), Qnil));
|
||||
end = XCDR(end);
|
||||
}
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
LispVal *nth(size_t n, LispVal *list) {
|
||||
size_t i = 0;
|
||||
DOTAILS(rest, list) {
|
||||
DOLIST_SAFE(elt, list) {
|
||||
if (i == n) {
|
||||
return XCAR(rest);
|
||||
return elt;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
@@ -117,12 +146,14 @@ DEFUN(member, "member", (LispVal * elt, LispVal *list, LispVal *pred),
|
||||
if (NILP(pred) || pred == Qeq) {
|
||||
// fast case
|
||||
DOTAILS(rest, list) {
|
||||
CHECK_LISTP(rest);
|
||||
if (elt == XCAR(rest)) {
|
||||
return rest;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DOTAILS(rest, list) {
|
||||
CHECK_LISTP(rest);
|
||||
if (!NILP(CALL(pred, elt, XCAR(rest)))) {
|
||||
return rest;
|
||||
}
|
||||
@@ -134,6 +165,7 @@ DEFUN(member, "member", (LispVal * elt, LispVal *list, LispVal *pred),
|
||||
DEFUN(member_if, "member-if", (LispVal * pred, LispVal *list), "(pred list)",
|
||||
"") {
|
||||
DOTAILS(rest, list) {
|
||||
CHECK_LISTP(rest);
|
||||
if (!NILP(CALL(pred, XCAR(rest)))) {
|
||||
return rest;
|
||||
}
|
||||
@@ -145,7 +177,9 @@ DEFUN(plist_put, "plist-put", (LispVal * plist, LispVal *prop, LispVal *value),
|
||||
"(plist prop value)", "") {
|
||||
CHECK_LISTP(plist);
|
||||
DOTAILS(rest, plist) {
|
||||
CHECK_LISTP(rest);
|
||||
if (EQ(XCAR(rest), prop)) {
|
||||
CHECK_TYPE(XCDR(rest), TYPE_CONS);
|
||||
RPLACA(XCDR(rest), value);
|
||||
return plist;
|
||||
}
|
||||
@@ -163,3 +197,24 @@ DEFUN(plist_get, "plist-get", (LispVal * plist, LispVal *prop, LispVal *def),
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
DEFUN(assoc, "assoc", (LispVal * key, LispVal *alist, LispVal *pred),
|
||||
"(key alist &optional pred)", "") {
|
||||
if (NILP(pred)) {
|
||||
DOLIST_SAFE(ent, alist) {
|
||||
CHECK_TYPE(ent, TYPE_CONS);
|
||||
if (EQ(key, XCAR(ent))) {
|
||||
return ent;
|
||||
}
|
||||
}
|
||||
return Qnil;
|
||||
} else {
|
||||
DOLIST_SAFE(ent, alist) {
|
||||
CHECK_TYPE(ent, TYPE_CONS);
|
||||
if (!NILP(CALL(pred, key, XCAR(ent)))) {
|
||||
return ent;
|
||||
}
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user