X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flisp%2Fao_lisp_atom.c;h=a633c223a32208cededbd1eeab876749390bc665;hb=d314a5654fafa5eac86d8293f1197a2f2c2eac72;hp=41ba97f5d7f5b674948d9da00324cdb0d97f5f10;hpb=6e5c1308ce33a864095eae02e7db18b0e043ab6e;p=fw%2Faltos diff --git a/src/lisp/ao_lisp_atom.c b/src/lisp/ao_lisp_atom.c index 41ba97f5..a633c223 100644 --- a/src/lisp/ao_lisp_atom.c +++ b/src/lisp/ao_lisp_atom.c @@ -38,7 +38,7 @@ static void atom_mark(void *addr) atom = ao_lisp_poly_atom(atom->next); if (!atom) break; - if (ao_lisp_mark_memory(atom, atom_size(atom))) + if (ao_lisp_mark_memory(&ao_lisp_atom_type, atom)) break; } } @@ -46,11 +46,19 @@ static void atom_mark(void *addr) static void atom_move(void *addr) { struct ao_lisp_atom *atom = addr; + int ret; for (;;) { - if (ao_lisp_poly_move(&atom->next, 0)) + struct ao_lisp_atom *next = ao_lisp_poly_atom(atom->next); + + if (!next) break; - atom = ao_lisp_poly_atom(atom->next); + ret = ao_lisp_move_memory(&ao_lisp_atom_type, (void **) &next); + if (next != ao_lisp_poly_atom(atom->next)) + atom->next = ao_lisp_atom_poly(next); + if (ret) + break; + atom = next; } } @@ -58,6 +66,7 @@ const struct ao_lisp_type ao_lisp_atom_type = { .mark = atom_mark, .size = atom_size, .move = atom_move, + .name = "atom" }; struct ao_lisp_atom *ao_lisp_atoms; @@ -77,82 +86,73 @@ ao_lisp_atom_intern(char *name) return atom; } #endif + ao_lisp_string_stash(0, name); atom = ao_lisp_alloc(name_size(name)); + name = ao_lisp_string_fetch(0); if (atom) { atom->type = AO_LISP_ATOM; atom->next = ao_lisp_atom_poly(ao_lisp_atoms); - if (!ao_lisp_atoms) - ao_lisp_root_add(&ao_lisp_atom_type, &ao_lisp_atoms); ao_lisp_atoms = atom; strcpy(atom->name, name); } return atom; } -static struct ao_lisp_frame *ao_lisp_frame_global; -struct ao_lisp_frame *ao_lisp_frame_current; - -static void -ao_lisp_atom_init(void) -{ - if (!ao_lisp_frame_global) { - ao_lisp_frame_global = ao_lisp_frame_new(0); - ao_lisp_root_add(&ao_lisp_frame_type, &ao_lisp_frame_global); - ao_lisp_root_add(&ao_lisp_frame_type, &ao_lisp_frame_current); - } -} - -static ao_poly * -ao_lisp_atom_ref(struct ao_lisp_frame *frame, ao_poly atom) +ao_poly * +ao_lisp_atom_ref(ao_poly atom) { ao_poly *ref; - ao_lisp_atom_init(); - while (frame) { + struct ao_lisp_frame *frame; + + for (frame = ao_lisp_frame_current; frame; frame = ao_lisp_poly_frame(frame->prev)) { ref = ao_lisp_frame_ref(frame, atom); if (ref) return ref; - frame = ao_lisp_poly_frame(frame->next); - } - if (ao_lisp_frame_global) { - ref = ao_lisp_frame_ref(ao_lisp_frame_global, atom); - if (ref) - return ref; } - return NULL; + return ao_lisp_frame_ref(ao_lisp_frame_global, atom); } ao_poly ao_lisp_atom_get(ao_poly atom) { - ao_poly *ref = ao_lisp_atom_ref(ao_lisp_frame_current, atom); + ao_poly *ref = ao_lisp_atom_ref(atom); - if (!ref && ao_lisp_frame_global) - ref = ao_lisp_frame_ref(ao_lisp_frame_global, atom); #ifdef ao_builtin_frame if (!ref) ref = ao_lisp_frame_ref(ao_lisp_poly_frame(ao_builtin_frame), atom); #endif if (ref) return *ref; - return AO_LISP_NIL; + return ao_lisp_error(AO_LISP_UNDEFINED, "undefined atom %s", ao_lisp_poly_atom(atom)->name); } ao_poly ao_lisp_atom_set(ao_poly atom, ao_poly val) { - ao_poly *ref = ao_lisp_atom_ref(ao_lisp_frame_current, atom); + ao_poly *ref = ao_lisp_atom_ref(atom); - if (!ref && ao_lisp_frame_global) - ref = ao_lisp_frame_ref(ao_lisp_frame_global, atom); - if (ref) - *ref = val; - else - ao_lisp_frame_global = ao_lisp_frame_add(ao_lisp_frame_global, atom, val); + if (!ref) + return ao_lisp_error(AO_LISP_UNDEFINED, "undefined atom %s", ao_lisp_poly_atom(atom)->name); + *ref = val; return val; } +ao_poly +ao_lisp_atom_def(ao_poly atom, ao_poly val) +{ + ao_poly *ref = ao_lisp_atom_ref(atom); + + if (ref) { + if (ao_lisp_frame_current) + return ao_lisp_error(AO_LISP_REDEFINED, "attempt to redefine atom %s", ao_lisp_poly_atom(atom)->name); + *ref = val; + return val; + } + return ao_lisp_frame_add(ao_lisp_frame_current ? ao_lisp_frame_current : ao_lisp_frame_global, atom, val); +} + void -ao_lisp_atom_print(ao_poly a) +ao_lisp_atom_write(ao_poly a) { struct ao_lisp_atom *atom = ao_lisp_poly_atom(a); printf("%s", atom->name);