diff options
| author | Oskari Timperi <oskari.timperi@iki.fi> | 2014-05-18 10:58:54 +0300 |
|---|---|---|
| committer | Oskari Timperi <oskari.timperi@iki.fi> | 2014-05-18 10:58:54 +0300 |
| commit | 36617b658e5f4ee1828c55673f1baf21b15af0bf (patch) | |
| tree | 7db0dab8e2aa47cf93a0125a6f35937cabd872f8 | |
| parent | 273589b4dbf45dc573b68baa3e5dc9c954982cd5 (diff) | |
| download | lispish-36617b658e5f4ee1828c55673f1baf21b15af0bf.tar.gz lispish-36617b658e5f4ee1828c55673f1baf21b15af0bf.zip | |
add ATOM_CLOSURE and related functions/macros
| -rw-r--r-- | atom.c | 25 | ||||
| -rw-r--r-- | atom.h | 16 |
2 files changed, 40 insertions, 1 deletions
@@ -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) @@ -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); |
