summaryrefslogtreecommitdiff
path: root/src/lisp/ao_lisp_atom.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-11-03 21:49:50 -0700
committerKeith Packard <keithp@keithp.com>2017-02-20 11:16:49 -0800
commit77db0e8162cd01c2b42737b3d71b38cea942484f (patch)
tree6345771cd69cdc646fd38f02e84056e0a8ff21d9 /src/lisp/ao_lisp_atom.c
parent11cb03b1d336ee90c422be27588f57be573a9546 (diff)
altos: Add lambda support to lisp
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.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/src/lisp/ao_lisp_atom.c b/src/lisp/ao_lisp_atom.c
index e5d28c3b..ea04741e 100644
--- a/src/lisp/ao_lisp_atom.c
+++ b/src/lisp/ao_lisp_atom.c
@@ -109,31 +109,65 @@ ao_lisp_atom_intern(char *name)
return atom;
}
-static struct ao_lisp_frame *globals;
+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, 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 *ref;
+ ao_lisp_atom_init();
+ while (frame) {
+ 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;
+}
ao_poly
ao_lisp_atom_get(ao_poly atom)
{
- struct ao_lisp_frame *frame = globals;
+ ao_poly *ref = ao_lisp_atom_ref(ao_lisp_frame_current, atom);
+
+ if (!ref && ao_lisp_frame_global)
+ ref = ao_lisp_frame_ref(ao_lisp_frame_global, atom);
#ifdef ao_builtin_frame
- if (!frame)
- frame = ao_lisp_poly_frame(ao_builtin_frame);
+ if (!ref)
+ ref = ao_lisp_frame_ref(ao_lisp_poly_frame(ao_builtin_frame), atom);
#endif
- return ao_lisp_frame_get(frame, atom);
+ if (ref)
+ return *ref;
+ return AO_LISP_NIL;
}
ao_poly
ao_lisp_atom_set(ao_poly atom, ao_poly val)
{
- if (!ao_lisp_frame_set(globals, atom, val)) {
- globals = ao_lisp_frame_add(globals, atom, val);
- if (!globals->next) {
- ao_lisp_root_add(&ao_lisp_frame_type, &globals);
-#ifdef ao_builtin_frame
- globals->next = ao_builtin_frame;
-#endif
- }
- }
+ ao_poly *ref = ao_lisp_atom_ref(ao_lisp_frame_current, 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);
return val;
}