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.
18 #include "ao_scheme.h"
20 static int name_size(char *name)
22 return sizeof(struct ao_scheme_atom) + strlen(name) + 1;
25 static int atom_size(void *addr)
27 struct ao_scheme_atom *atom = addr;
30 return name_size(atom->name);
33 static void atom_mark(void *addr)
35 struct ao_scheme_atom *atom = addr;
38 atom = ao_scheme_poly_atom(atom->next);
41 if (ao_scheme_mark_memory(&ao_scheme_atom_type, atom))
46 static void atom_move(void *addr)
48 struct ao_scheme_atom *atom = addr;
52 struct ao_scheme_atom *next = ao_scheme_poly_atom(atom->next);
56 ret = ao_scheme_move_memory(&ao_scheme_atom_type, (void **) &next);
57 if (next != ao_scheme_poly_atom(atom->next))
58 atom->next = ao_scheme_atom_poly(next);
65 const struct ao_scheme_type ao_scheme_atom_type = {
72 struct ao_scheme_atom *ao_scheme_atoms;
74 static struct ao_scheme_atom *
75 ao_scheme_atom_find(char *name)
77 struct ao_scheme_atom *atom;
79 for (atom = ao_scheme_atoms; atom; atom = ao_scheme_poly_atom(atom->next)) {
80 if (!strcmp(atom->name, name))
83 #ifdef ao_builtin_atoms
84 for (atom = ao_scheme_poly_atom(ao_builtin_atoms); atom; atom = ao_scheme_poly_atom(atom->next)) {
85 if (!strcmp(atom->name, name))
93 ao_scheme_atom_init(struct ao_scheme_atom *atom, char *name)
96 atom->type = AO_SCHEME_ATOM;
97 strcpy(atom->name, name);
98 atom->next = ao_scheme_atom_poly(ao_scheme_atoms);
99 ao_scheme_atoms = atom;
103 struct ao_scheme_atom *
104 ao_scheme_string_to_atom(struct ao_scheme_string *string)
106 struct ao_scheme_atom *atom = ao_scheme_atom_find(string->val);
110 ao_scheme_string_stash(string);
111 atom = ao_scheme_alloc(name_size(string->val));
112 string = ao_scheme_string_fetch();
113 ao_scheme_atom_init(atom, string->val);
117 struct ao_scheme_atom *
118 ao_scheme_atom_intern(char *name)
120 struct ao_scheme_atom *atom = ao_scheme_atom_find(name);
124 atom = ao_scheme_alloc(name_size(name));
125 ao_scheme_atom_init(atom, name);
130 ao_scheme_atom_ref(ao_poly atom, struct ao_scheme_frame **frame_ref)
133 struct ao_scheme_frame *frame;
135 for (frame = ao_scheme_frame_current; frame; frame = ao_scheme_poly_frame(frame->prev)) {
136 ref = ao_scheme_frame_ref(frame, atom);
143 ref = ao_scheme_frame_ref(ao_scheme_frame_global, atom);
146 *frame_ref = ao_scheme_frame_global;
151 ao_scheme_atom_get(ao_poly atom)
153 ao_poly *ref = ao_scheme_atom_ref(atom, NULL);
155 #ifdef ao_builtin_frame
157 ref = ao_scheme_frame_ref(ao_scheme_poly_frame(ao_builtin_frame), atom);
161 return ao_scheme_error(AO_SCHEME_UNDEFINED, "undefined atom %s", ao_scheme_poly_atom(atom)->name);
165 ao_scheme_atom_set(ao_poly atom, ao_poly val)
167 ao_poly *ref = ao_scheme_atom_ref(atom, NULL);
170 return ao_scheme_error(AO_SCHEME_UNDEFINED, "undefined atom %s", ao_scheme_poly_atom(atom)->name);
176 ao_scheme_atom_def(ao_poly atom, ao_poly val)
178 struct ao_scheme_frame *frame;
179 ao_poly *ref = ao_scheme_atom_ref(atom, &frame);
182 if (frame == ao_scheme_frame_current)
183 return ao_scheme_error(AO_SCHEME_REDEFINED, "attempt to redefine atom %s", ao_scheme_poly_atom(atom)->name);
187 return ao_scheme_frame_add(ao_scheme_frame_current ? ao_scheme_frame_current : ao_scheme_frame_global, atom, val);
191 ao_scheme_atom_write(ao_poly a, bool write)
193 struct ao_scheme_atom *atom = ao_scheme_poly_atom(a);
195 printf("%s", atom->name);