Add optional, variadic arguments
diff --git a/src/lisp/lisp.c b/src/lisp/lisp.c
index c606e29..e151670 100644
--- a/src/lisp/lisp.c
+++ b/src/lisp/lisp.c
@@ -14,7 +14,7 @@
unsigned char max_pool = 0, current_pool = 0;
-void err(const char *msg)
+__attribute__((noreturn)) void err(const char *msg)
{
fprintf(stderr, "ERROR: %s\n", msg);
exit(1);
@@ -239,7 +239,7 @@
{
struct closure *c = (void *)(v ^ CLOSURE_TAG);
printf("closure %p taking %d argument(s) and capturing %d value(s)\n",
- c->function, c->num_args, c->num_captured);
+ c->function, c->args->num_required, c->num_captured);
}
else
{
@@ -598,13 +598,13 @@
return c->name;
}
-value_t create_closure(void *code, int nargs, int ncaptures)
+value_t create_closure(void *code, struct args *args, int ncaptures)
{
struct closure_alloc *ca = malloc_aligned(sizeof(struct closure_alloc) +
ncaptures * sizeof(value_t));
ca->closure.function = code;
- ca->closure.num_args = nargs;
+ ca->closure.args = args;
ca->closure.num_captured = ncaptures;
add_this_alloc(&ca->alloc, CLOSURE_TAG);
@@ -621,3 +621,68 @@
c->data[index] = value;
}
+
+value_t cxdr(value_t v, int index)
+{
+ if (!listp(v) || index >= length(v))
+ return nil;
+
+ for (int i = 0; i < index; i++)
+ {
+ v = cdr(v);
+ }
+
+ return v;
+}
+
+value_t *cxdrref(value_t *v, int index)
+{
+ if (!listp(*v) || index >= length(*v))
+ return NULL;
+
+ value_t *p = v;
+
+ for (int i = 0; i < index; i++)
+ {
+ p = cdrref(*p);
+ }
+
+ return p;
+}
+
+value_t deep_copy(value_t val)
+{
+ if (integerp(val) || val == nil || val == t)
+ {
+ return val;
+ }
+ else if (symbolp(val))
+ {
+ return symval((char *)(val ^ SYMBOL_TAG));
+ }
+ else if (stringp(val))
+ {
+ return strval((char *)(val ^ STRING_TAG));
+ }
+ else if (consp(val))
+ {
+ return cons(deep_copy(car(val)), deep_copy(cdr(val)));
+ }
+ else if (closurep(val))
+ {
+ struct closure *c = (void *)(val ^ CLOSURE_TAG);
+ value_t new = create_closure(c->function, c->args, c->num_captured);
+ struct closure *new_c = (void *)(new ^ CLOSURE_TAG);
+
+ for (int i = 0; i < c->num_captured; i++)
+ {
+ new_c->data[i] = deep_copy(c->data[i]);
+ }
+
+ return new;
+ }
+ else
+ {
+ err("Don't know how to deep copy this, sorry... please report this bug :)");
+ }
+}