diff options
| author | Keith Packard <keithp@keithp.com> | 2016-11-15 09:55:22 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-02-20 11:16:51 -0800 | 
| commit | 974717eb9dad105c9897ee24f953d98d57eaec77 (patch) | |
| tree | ea77eec1b39f859353f17ad384950f6bd982c569 /src/lisp/ao_lisp_eval.c | |
| parent | b3b5bd2c14cfcde6c551a87ee6da08a53f1e4bc6 (diff) | |
altos/lisp: Evaluate macros once, then smash them into place
This assumes that macros are all pure functions, which should be true
for syntactic macros.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/lisp/ao_lisp_eval.c')
| -rw-r--r-- | src/lisp/ao_lisp_eval.c | 23 | 
1 files changed, 21 insertions, 2 deletions
| diff --git a/src/lisp/ao_lisp_eval.c b/src/lisp/ao_lisp_eval.c index 5cc1b75a..3af56796 100644 --- a/src/lisp/ao_lisp_eval.c +++ b/src/lisp/ao_lisp_eval.c @@ -298,7 +298,7 @@ ao_lisp_eval_formal(void)  			break;  		case AO_LISP_FUNC_MACRO:  			/* Evaluate the result once more */ -			ao_lisp_stack->state = eval_sexpr; +			ao_lisp_stack->state = eval_macro;  			if (!ao_lisp_stack_push())  				return 0; @@ -308,7 +308,6 @@ ao_lisp_eval_formal(void)  			prev = ao_lisp_poly_stack(ao_lisp_stack->prev);  			ao_lisp_stack->state = eval_sexpr;  			ao_lisp_stack->sexprs = prev->sexprs; -			prev->sexprs = AO_LISP_NIL;  			DBGI(".. start macro\n");  			DBGI(".. sexprs       "); DBG_POLY(ao_lisp_stack->sexprs); DBG("\n"); @@ -555,6 +554,25 @@ ao_lisp_eval_while_test(void)  	return 1;  } +/* + * Replace the original sexpr with the macro expansion, then + * execute that + */ +static int +ao_lisp_eval_macro(void) +{ +	DBGI("macro: "); DBG_POLY(ao_lisp_v); DBG(" sexprs "); DBG_POLY(ao_lisp_stack->sexprs); DBG("\n"); + +	if (ao_lisp_poly_type(ao_lisp_v) == AO_LISP_CONS) { +		*ao_lisp_poly_cons(ao_lisp_stack->sexprs) = *ao_lisp_poly_cons(ao_lisp_v); +		ao_lisp_v = ao_lisp_stack->sexprs; +		DBGI("sexprs rewritten to: "); DBG_POLY(ao_lisp_v); DBG("\n"); +	} +	ao_lisp_stack->sexprs = AO_LISP_NIL; +	ao_lisp_stack->state = eval_sexpr; +	return 1; +} +  static int (*const evals[])(void) = {  	[eval_sexpr] = ao_lisp_eval_sexpr,  	[eval_val] = ao_lisp_eval_val, @@ -565,6 +583,7 @@ static int (*const evals[])(void) = {  	[eval_progn] = ao_lisp_eval_progn,  	[eval_while] = ao_lisp_eval_while,  	[eval_while_test] = ao_lisp_eval_while_test, +	[eval_macro] = ao_lisp_eval_macro,  };  /* | 
