diff options
| author | Keith Packard <keithp@keithp.com> | 2016-11-03 21:49:50 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-02-20 11:16:49 -0800 | 
| commit | 77db0e8162cd01c2b42737b3d71b38cea942484f (patch) | |
| tree | 6345771cd69cdc646fd38f02e84056e0a8ff21d9 /src/lisp/ao_lisp_atom.c | |
| parent | 11cb03b1d336ee90c422be27588f57be573a9546 (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.c | 62 | 
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;  } | 
