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.
20 static int name_size(char *name)
22 return sizeof(struct ao_lisp_atom) + strlen(name) + 1;
25 static int atom_size(void *addr)
27 struct ao_lisp_atom *atom = addr;
30 return name_size(atom->name);
33 static void atom_mark(void *addr)
35 struct ao_lisp_atom *atom = addr;
38 atom = ao_lisp_poly_atom(atom->next);
41 if (ao_lisp_mark_memory(atom, atom_size(atom)))
46 static void atom_move(void *addr)
48 struct ao_lisp_atom *atom = addr;
52 struct ao_lisp_atom *next = ao_lisp_poly_atom(atom->next);
56 ret = ao_lisp_move_memory((void **) &next, atom_size(next));
57 if (next != ao_lisp_poly_atom(atom->next))
58 atom->next = ao_lisp_atom_poly(next);
65 const struct ao_lisp_type ao_lisp_atom_type = {
71 struct ao_lisp_atom *ao_lisp_atoms;
74 ao_lisp_atom_intern(char *name)
76 struct ao_lisp_atom *atom;
78 for (atom = ao_lisp_atoms; atom; atom = ao_lisp_poly_atom(atom->next)) {
79 if (!strcmp(atom->name, name))
82 #ifdef ao_builtin_atoms
83 for (atom = ao_lisp_poly_atom(ao_builtin_atoms); atom; atom = ao_lisp_poly_atom(atom->next)) {
84 if (!strcmp(atom->name, name))
88 atom = ao_lisp_alloc(name_size(name));
90 atom->type = AO_LISP_ATOM;
91 atom->next = ao_lisp_atom_poly(ao_lisp_atoms);
93 ao_lisp_root_add(&ao_lisp_atom_type, &ao_lisp_atoms);
95 strcpy(atom->name, name);
100 struct ao_lisp_frame *ao_lisp_frame_global;
101 struct ao_lisp_frame *ao_lisp_frame_current;
104 ao_lisp_atom_init(void)
106 if (!ao_lisp_frame_global) {
107 ao_lisp_frame_global = ao_lisp_frame_new(0);
108 ao_lisp_root_add(&ao_lisp_frame_type, &ao_lisp_frame_global);
109 ao_lisp_root_add(&ao_lisp_frame_type, &ao_lisp_frame_current);
114 ao_lisp_atom_ref(struct ao_lisp_frame *frame, ao_poly atom)
119 ref = ao_lisp_frame_ref(frame, atom);
122 frame = ao_lisp_poly_frame(frame->next);
124 if (ao_lisp_frame_global) {
125 ref = ao_lisp_frame_ref(ao_lisp_frame_global, atom);
133 ao_lisp_atom_get(ao_poly atom)
135 ao_poly *ref = ao_lisp_atom_ref(ao_lisp_frame_current, atom);
137 if (!ref && ao_lisp_frame_global)
138 ref = ao_lisp_frame_ref(ao_lisp_frame_global, atom);
139 #ifdef ao_builtin_frame
141 ref = ao_lisp_frame_ref(ao_lisp_poly_frame(ao_builtin_frame), atom);
145 return ao_lisp_error(AO_LISP_UNDEFINED, "undefined atom %s", ao_lisp_poly_atom(atom)->name);
149 ao_lisp_atom_set(ao_poly atom, ao_poly val)
151 ao_poly *ref = ao_lisp_atom_ref(ao_lisp_frame_current, atom);
153 if (!ref && ao_lisp_frame_global)
154 ref = ao_lisp_frame_ref(ao_lisp_frame_global, atom);
158 ao_lisp_frame_add(&ao_lisp_frame_global, atom, val);
163 ao_lisp_atom_print(ao_poly a)
165 struct ao_lisp_atom *atom = ao_lisp_poly_atom(a);
166 printf("%s", atom->name);