aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOskari Timperi <oskari.timperi@iki.fi>2014-05-18 10:58:54 +0300
committerOskari Timperi <oskari.timperi@iki.fi>2014-05-18 10:58:54 +0300
commit36617b658e5f4ee1828c55673f1baf21b15af0bf (patch)
tree7db0dab8e2aa47cf93a0125a6f35937cabd872f8
parent273589b4dbf45dc573b68baa3e5dc9c954982cd5 (diff)
downloadlispish-36617b658e5f4ee1828c55673f1baf21b15af0bf.tar.gz
lispish-36617b658e5f4ee1828c55673f1baf21b15af0bf.zip
add ATOM_CLOSURE and related functions/macros
-rw-r--r--atom.c25
-rw-r--r--atom.h16
2 files changed, 40 insertions, 1 deletions
diff --git a/atom.c b/atom.c
index 9e33255..43626d8 100644
--- a/atom.c
+++ b/atom.c
@@ -1,4 +1,5 @@
#include "atom.h"
+#include "env.h"
#include <stdlib.h>
#include <stdio.h>
@@ -59,6 +60,16 @@ struct atom *atom_new_list_empty()
return atom_new_list(list);
}
+struct atom *atom_new_closure(struct atom *params, struct atom *body,
+ struct env *env)
+{
+ struct atom *atom = atom_new(ATOM_CLOSURE);
+ atom->closure.params = params;
+ atom->closure.body = body;
+ atom->closure.env = env;
+ return atom;
+}
+
struct atom *atom_clone(struct atom *atom)
{
switch (atom->type)
@@ -98,6 +109,15 @@ struct atom *atom_clone(struct atom *atom)
return atom_new_list(list_clone);
}
+
+ case ATOM_CLOSURE:
+ // TODO: should we clone the env or what? If it is just plainly
+ // cloned, it leads to a infinite loop when we have a closure
+ // bound to a name in the env.
+ return atom_new_closure(atom_clone(atom->closure.params),
+ atom_clone(atom->closure.body),
+ atom->closure.env);
+ break;
}
return NULL;
@@ -134,7 +154,12 @@ void print_atom(struct atom *atom, int level)
printf(" ");
}
printf(")");
+ break;
}
+
+ case ATOM_CLOSURE:
+ printf("<closure@%p>", atom);
+ break;
}
if (level == 0)
diff --git a/atom.h b/atom.h
index f620af4..7240670 100644
--- a/atom.h
+++ b/atom.h
@@ -16,6 +16,8 @@
#define IS_NIL(ATOM) (ATOM_TYPE(ATOM) == ATOM_NIL)
+#define IS_CLOSURE(ATOM) (ATOM_TYPE(ATOM) == ATOM_CLOSURE)
+
#define CAR(LIST) (LIST_FIRST(LIST))
#define CDR(LIST) ((LIST) != NULL ? LIST_NEXT((LIST), entries) : NULL)
#define CDDR(LIST) CDR(CDR(LIST))
@@ -28,10 +30,19 @@ enum
ATOM_SYMBOL,
ATOM_LIST,
ATOM_TRUE,
- ATOM_FALSE
+ ATOM_FALSE,
+ ATOM_CLOSURE
};
struct atom;
+struct env;
+
+struct closure
+{
+ struct env *env;
+ struct atom *params;
+ struct atom *body;
+};
LIST_HEAD(list, atom);
@@ -48,6 +59,7 @@ struct atom
int len;
} str;
struct list *list;
+ struct closure closure;
};
LIST_ENTRY(atom) entries;
@@ -59,6 +71,8 @@ struct atom *atom_new_str(const char *str, int len);
struct atom *atom_new_sym(const char *sym, int len);
struct atom *atom_new_list(struct list *list);
struct atom *atom_new_list_empty();
+struct atom *atom_new_closure(struct atom *params, struct atom *body,
+ struct env *env);
struct atom *atom_clone();
void print_atom(struct atom *atom, int level);