diff options
| author | Oskari Timperi <oskari.timperi@iki.fi> | 2014-05-15 22:50:37 +0300 |
|---|---|---|
| committer | Oskari Timperi <oskari.timperi@iki.fi> | 2014-05-15 22:50:37 +0300 |
| commit | a2ed9c63f26f5cd767ac6c1d4073cdaa08a168b4 (patch) | |
| tree | 61402635148a26c8ab8a2fd51c0811dc258429a1 | |
| parent | e23d0ee6eec1433849e4af1f3906a0946a19aef4 (diff) | |
| download | lispish-a2ed9c63f26f5cd767ac6c1d4073cdaa08a168b4.tar.gz lispish-a2ed9c63f26f5cd767ac6c1d4073cdaa08a168b4.zip | |
add atom_clone()
| -rw-r--r-- | atom.c | 40 | ||||
| -rw-r--r-- | atom.h | 1 |
2 files changed, 41 insertions, 0 deletions
@@ -44,6 +44,46 @@ struct atom *atom_new_list(struct list *list) return atom; } +struct atom *atom_clone(struct atom *atom) +{ + switch (atom->type) + { + case ATOM_NIL: + case ATOM_TRUE: + case ATOM_FALSE: + return atom; + + case ATOM_INT: + return atom_new_int(atom->l); + + case ATOM_STR: + return atom_new_str(atom->str.str, atom->str.len); + + case ATOM_SYMBOL: + return atom_new_sym(atom->str.str, atom->str.len); + + case ATOM_LIST: + { + struct list *list = atom->list; + struct list *clone = NULL, *last = NULL; + + while (list) + { + struct atom *a = LIST_GET_ATOM(list); + struct atom *b = atom_clone(a); + last = list_append(last, b); + list = list->next; + if (!clone) + clone = last; + } + + return atom_new_list(clone); + } + } + + return NULL; +} + #ifdef BUILD_TEST #include "test_util.h" @@ -54,6 +54,7 @@ struct atom *atom_new_int(long l); 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_clone(); extern struct atom true_atom; extern struct atom false_atom; |
