2 * Copyright © 2016 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 #define DBG(...) printf(__VA_ARGS__)
26 static int name_size(char *name)
28 return sizeof(struct ao_lisp_atom) + strlen(name) + 1;
31 static int atom_size(void *addr)
33 struct ao_lisp_atom *atom = addr;
36 return name_size(atom->name);
39 static void atom_mark(void *addr)
41 struct ao_lisp_atom *atom = addr;
43 DBG ("\tatom start %s\n", atom->name);
45 atom = ao_lisp_poly_atom(atom->next);
48 DBG("\t\tatom mark %s %d\n", atom->name, (uint8_t *) atom - ao_lisp_const);
49 if (ao_lisp_mark_memory(atom, atom_size(atom)))
52 DBG ("\tatom done\n");
55 static void atom_move(void *addr)
57 struct ao_lisp_atom *atom = addr;
59 DBG("\tatom move start %s %d next %s %d\n",
60 atom->name, ((uint8_t *) atom - ao_lisp_const),
61 atom->next ? ao_lisp_poly_atom(atom->next)->name : "(none)",
62 atom->next ? ((uint8_t *) ao_lisp_poly_atom(atom->next) - ao_lisp_const) : 0);
64 struct ao_lisp_atom *next;
66 next = ao_lisp_poly_atom(atom->next);
67 next = ao_lisp_move_memory(next, atom_size(next));
70 DBG("\t\tatom move %s %d->%d\n", next->name, ((uint8_t *) ao_lisp_poly_atom(atom->next) - ao_lisp_const), ((uint8_t *) next - ao_lisp_const));
71 atom->next = ao_lisp_atom_poly(next);
74 DBG("\tatom move end\n");
77 const struct ao_lisp_type ao_lisp_atom_type = {
83 struct ao_lisp_atom *ao_lisp_atoms;
86 ao_lisp_atom_intern(char *name)
88 struct ao_lisp_atom *atom;
90 for (atom = ao_lisp_atoms; atom; atom = ao_lisp_poly_atom(atom->next)) {
91 if (!strcmp(atom->name, name))
94 #ifdef ao_builtin_atoms
95 for (atom = ao_lisp_poly_atom(ao_builtin_atoms); atom; atom = ao_lisp_poly_atom(atom->next)) {
96 if (!strcmp(atom->name, name))
100 atom = ao_lisp_alloc(name_size(name));
102 atom->type = AO_LISP_ATOM;
103 atom->next = ao_lisp_atom_poly(ao_lisp_atoms);
105 ao_lisp_root_add(&ao_lisp_atom_type, &ao_lisp_atoms);
106 ao_lisp_atoms = atom;
107 strcpy(atom->name, name);
112 static struct ao_lisp_frame *globals;
115 ao_lisp_atom_get(ao_poly atom)
117 struct ao_lisp_frame *frame = globals;
118 #ifdef ao_builtin_frame
120 frame = ao_lisp_poly_frame(ao_builtin_frame);
122 return ao_lisp_frame_get(frame, atom);
126 ao_lisp_atom_set(ao_poly atom, ao_poly val)
128 if (!ao_lisp_frame_set(globals, atom, val)) {
129 globals = ao_lisp_frame_add(globals, atom, val);
130 if (!globals->next) {
131 ao_lisp_root_add(&ao_lisp_frame_type, &globals);
132 #ifdef ao_builtin_frame
133 globals->next = ao_builtin_frame;
141 ao_lisp_atom_print(ao_poly a)
143 struct ao_lisp_atom *atom = ao_lisp_poly_atom(a);
144 printf("%s", atom->name);