summaryrefslogtreecommitdiff
path: root/src/lisp/ao_lisp_eval.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-11-15 09:55:22 -0800
committerKeith Packard <keithp@keithp.com>2016-11-17 22:18:39 -0800
commitacfc29f2400cc3c06745edb5ec0c82b82998d3cc (patch)
tree87d7a10500c9576afb563e315b0855134ce66b47 /src/lisp/ao_lisp_eval.c
parent3d837e52b29da16088fb5ca7921d8bcb99941759 (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.c23
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,
};
/*