diff options
author | Keith Packard <keithp@keithp.com> | 2016-10-31 16:43:44 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2016-11-17 22:18:39 -0800 |
commit | eabd97e4b1a9d34416455b0fceb14a9a480c63a4 (patch) | |
tree | 57053a1ea332cfc8057f5b4a17ee977f77ae020b /src/lisp/ao_lisp_atom.c | |
parent | d46698a01ed4903d36635b34867bfc4bb8fbafc6 (diff) |
Add first lisp bits
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/lisp/ao_lisp_atom.c')
-rw-r--r-- | src/lisp/ao_lisp_atom.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/lisp/ao_lisp_atom.c b/src/lisp/ao_lisp_atom.c new file mode 100644 index 00000000..65282142 --- /dev/null +++ b/src/lisp/ao_lisp_atom.c @@ -0,0 +1,107 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao_lisp.h" + +static int name_size(char *name) +{ + return sizeof(struct ao_lisp_atom) + strlen(name) + 1; +} + +static int atom_size(void *addr) +{ + struct ao_lisp_atom *atom = addr; + if (!atom) + return 0; + return name_size(atom->name); +} + +static void atom_mark(void *addr) +{ + struct ao_lisp_atom *atom = addr; + + if (atom->next == AO_LISP_ATOM_CONST) + return; + + for (;;) { + ao_lisp_poly_mark(atom->val); + atom = atom->next; + if (!atom) + break; + if (ao_lisp_mark_memory(atom, atom_size(atom))) + break; + } +} + +static void atom_move(void *addr) +{ + struct ao_lisp_atom *atom = addr; + + if (atom->next == AO_LISP_ATOM_CONST) + return; + + for (;;) { + struct ao_lisp_atom *next; + + atom->val = ao_lisp_poly_move(atom->val); + next = ao_lisp_move_memory(atom->next, atom_size(atom->next)); + if (!next) + break; + atom->next = next; + atom = next; + } +} + +const struct ao_lisp_mem_type ao_lisp_atom_type = { + .mark = atom_mark, + .size = atom_size, + .move = atom_move, +}; + +struct ao_lisp_atom *atoms; + +struct ao_lisp_atom * +ao_lisp_atom_intern(char *name) +{ + struct ao_lisp_atom *atom; + int b; + + for (atom = atoms; atom; atom = atom->next) { + if (!strcmp(atom->name, name)) + return atom; + } + for (b = 0; ao_lisp_builtins[b]; b++) + if (!strcmp(ao_lisp_builtins[b]->name, name)) + return (struct ao_lisp_atom *) ao_lisp_builtins[b]; + if (!atoms) + ao_lisp_root_add(&ao_lisp_atom_type, (void **) &atoms); + atom = ao_lisp_alloc(name_size(name)); + if (atom) { + atom->type = AO_LISP_ATOM; + atom->next = atoms; + atoms = atom; + strcpy(atom->name, name); + atom->val = AO_LISP_NIL; + } + return atom; +} + +void +ao_lisp_atom_print(struct ao_lisp_atom *a) +{ + fputs(a->name, stdout); +} |