diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lisp/Makefile | 1 | ||||
| -rw-r--r-- | src/lisp/ao_lisp.h | 39 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_builtin.c | 5 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_eval.c | 18 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_make_const.c | 2 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_save.c | 57 | 
6 files changed, 119 insertions, 3 deletions
| diff --git a/src/lisp/Makefile b/src/lisp/Makefile index aa542021..dac11f66 100644 --- a/src/lisp/Makefile +++ b/src/lisp/Makefile @@ -20,6 +20,7 @@ SRCS=\  	ao_lisp_lambda.c \  	ao_lisp_eval.c \  	ao_lisp_rep.c \ +	ao_lisp_save.c \  	ao_lisp_error.c   OBJS=$(SRCS:.c=.o) diff --git a/src/lisp/ao_lisp.h b/src/lisp/ao_lisp.h index 7a165cd8..44838a34 100644 --- a/src/lisp/ao_lisp.h +++ b/src/lisp/ao_lisp.h @@ -20,6 +20,26 @@  //#include <stdio.h>  #include <ao_lisp_os.h> +typedef uint16_t	ao_poly; +typedef int16_t		ao_signed_poly; + +#ifdef AO_LISP_SAVE + +struct ao_lisp_os_save { +	ao_poly	ao_lisp_atoms; +	ao_poly	ao_lisp_globals; +}; + +#define AO_LISP_POOL	(AO_LISP_POOL_TOTAL - sizeof (struct ao_lisp_os_save)) + +int +ao_lisp_os_save(void); + +int +ao_lisp_os_restore(void); + +#endif +  #ifdef AO_LISP_MAKE_CONST  #define AO_LISP_POOL_CONST	16384  extern uint8_t ao_lisp_const[AO_LISP_POOL_CONST]; @@ -85,9 +105,6 @@ extern uint16_t		ao_lisp_top;  extern uint8_t		ao_lisp_exception; -typedef uint16_t	ao_poly; -typedef int16_t		ao_signed_poly; -  static inline int  ao_lisp_is_const(ao_poly poly) {  	return poly & AO_LISP_CONST; @@ -228,6 +245,8 @@ enum ao_lisp_builtin_id {  	builtin_flush,  	builtin_delay,  	builtin_led, +	builtin_save, +	builtin_restore,  	_builtin_last  }; @@ -468,6 +487,12 @@ ao_lisp_poly_move(ao_poly *p, uint8_t note_cons);  /* eval */ +void +ao_lisp_eval_clear_globals(void); + +int +ao_lisp_eval_restart(void); +  ao_poly  ao_lisp_eval(ao_poly p); @@ -542,6 +567,14 @@ ao_lisp_macro(struct ao_lisp_cons *cons);  ao_poly  ao_lisp_lambda_eval(void); +/* save */ + +ao_poly +ao_lisp_save(struct ao_lisp_cons *cons); + +ao_poly +ao_lisp_restore(struct ao_lisp_cons *cons); +  /* error */  void diff --git a/src/lisp/ao_lisp_builtin.c b/src/lisp/ao_lisp_builtin.c index 30631980..ebc69f77 100644 --- a/src/lisp/ao_lisp_builtin.c +++ b/src/lisp/ao_lisp_builtin.c @@ -82,6 +82,9 @@ static const ao_poly builtin_names[] = {  	[builtin_flush] = _ao_lisp_atom_flush,  	[builtin_delay] = _ao_lisp_atom_delay,  	[builtin_led] = _ao_lisp_atom_led, +	[builtin_save] = _ao_lisp_atom_save, +	[builtin_restore] = _ao_lisp_atom_restore, +  };  static char * @@ -591,5 +594,7 @@ const ao_lisp_func_t ao_lisp_builtins[] = {  	[builtin_flush] = ao_lisp_flush,  	[builtin_led] = ao_lisp_led,  	[builtin_delay] = ao_lisp_delay, +	[builtin_save] = ao_lisp_save, +	[builtin_restore] = ao_lisp_restore,  }; diff --git a/src/lisp/ao_lisp_eval.c b/src/lisp/ao_lisp_eval.c index 1c929869..f945bc16 100644 --- a/src/lisp/ao_lisp_eval.c +++ b/src/lisp/ao_lisp_eval.c @@ -546,6 +546,24 @@ static int (*const evals[])(void) = {  	[eval_while_test] = ao_lisp_eval_while_test,  }; +/* + * Called at restore time to reset all execution state + */ + +void +ao_lisp_eval_clear_globals(void) +{ +	ao_lisp_stack = NULL; +	ao_lisp_frame_current = NULL; +	ao_lisp_v = AO_LISP_NIL; +} + +int +ao_lisp_eval_restart(void) +{ +	return ao_lisp_stack_push(); +} +  ao_poly  ao_lisp_eval(ao_poly _v)  { diff --git a/src/lisp/ao_lisp_make_const.c b/src/lisp/ao_lisp_make_const.c index 0b3e25a6..0a8c9d07 100644 --- a/src/lisp/ao_lisp_make_const.c +++ b/src/lisp/ao_lisp_make_const.c @@ -67,6 +67,8 @@ struct builtin_func funcs[] = {  	"flush",	AO_LISP_FUNC_LAMBDA,	builtin_flush,  	"delay",	AO_LISP_FUNC_LAMBDA,	builtin_delay,  	"led",		AO_LISP_FUNC_LEXPR,	builtin_led, +	"save",		AO_LISP_FUNC_LAMBDA,	builtin_save, +	"restore",	AO_LISP_FUNC_LAMBDA,	builtin_restore,  };  #define N_FUNC (sizeof funcs / sizeof funcs[0]) diff --git a/src/lisp/ao_lisp_save.c b/src/lisp/ao_lisp_save.c new file mode 100644 index 00000000..2b19fdcb --- /dev/null +++ b/src/lisp/ao_lisp_save.c @@ -0,0 +1,57 @@ +/* + * 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, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include <ao_lisp.h> + +ao_poly +ao_lisp_save(struct ao_lisp_cons *cons) +{ +#ifdef AO_LISP_SAVE +	struct ao_lisp_os_save *os = (struct ao_lisp_os_save *) &ao_lisp_pool[AO_LISP_POOL]; + +	ao_lisp_collect(); +	os->ao_lisp_atoms = ao_lisp_atom_poly(ao_lisp_atoms); +	os->ao_lisp_globals = ao_lisp_frame_poly(ao_lisp_frame_global); +	if (ao_lisp_os_save()) +		return _ao_lisp_atom_t; +#endif +	return AO_LISP_NIL; +} + +ao_poly +ao_lisp_restore(struct ao_lisp_cons *cons) +{ +#ifdef AO_LISP_SAVE +	struct ao_lisp_os_save *os = (struct ao_lisp_os_save *) &ao_lisp_pool[AO_LISP_POOL]; + +	if (ao_lisp_os_restore()) { + +		ao_lisp_atoms = ao_lisp_poly_atom(os->ao_lisp_atoms); +		ao_lisp_frame_global = ao_lisp_poly_frame(os->ao_lisp_globals); + +		/* Clear the eval global variabls */ +		ao_lisp_eval_clear_globals(); + +		/* Reset the allocator */ +		ao_lisp_top = AO_LISP_POOL; +		ao_lisp_collect(); + +		/* Re-create the evaluator stack */ +		if (!ao_lisp_eval_restart()) +			return AO_LISP_NIL; +		return _ao_lisp_atom_t; +	} +#endif +	return AO_LISP_NIL; +} | 
