diff options
author | Keith Packard <keithp@keithp.com> | 2016-11-17 16:08:15 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2017-02-20 11:16:51 -0800 |
commit | eaa528e4e62ba1d9765888760d387303487b2e01 (patch) | |
tree | 02fc89072aafcad60d48c9933d325aedcc45a387 /src/lisp/ao_lisp_eval.c | |
parent | ffaf73407bcdf6bc4120c90212de4a2f52cf7991 (diff) |
altos/lisp: Make lambda, cond and while all have implicit progns
This lets all of these execute more than one sexpr, returning the
value of the last.
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 | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/lisp/ao_lisp_eval.c b/src/lisp/ao_lisp_eval.c index 6f56a120..5fa9e0ad 100644 --- a/src/lisp/ao_lisp_eval.c +++ b/src/lisp/ao_lisp_eval.c @@ -310,7 +310,6 @@ ao_lisp_eval_formal(void) * value and re-evaluate it */ prev = ao_lisp_poly_stack(ao_lisp_stack->prev); - ao_lisp_stack->state = eval_sexpr; ao_lisp_stack->sexprs = prev->sexprs; DBGI(".. start macro\n"); @@ -401,10 +400,11 @@ ao_lisp_eval_exec(void) DBGI(".. frame "); DBG_POLY(ao_lisp_frame_poly(ao_lisp_frame_current)); DBG("\n"); break; case AO_LISP_LAMBDA: - ao_lisp_stack->state = eval_sexpr; DBGI(".. frame "); DBG_POLY(ao_lisp_frame_poly(ao_lisp_frame_current)); DBG("\n"); - ao_lisp_v = ao_lisp_lambda_eval(); - DBGI(".. sexpr "); DBG_POLY(ao_lisp_v); DBG("\n"); + ao_lisp_stack->state = eval_progn; + v = ao_lisp_lambda_eval(); + ao_lisp_stack->sexprs = v; + DBGI(".. sexprs "); DBG_POLY(ao_lisp_stack->sexprs); DBG("\n"); DBGI(".. frame "); DBG_POLY(ao_lisp_frame_poly(ao_lisp_frame_current)); DBG("\n"); break; } @@ -442,7 +442,6 @@ ao_lisp_eval_cond(void) ao_lisp_stack->state = eval_cond_test; if (!ao_lisp_stack_push()) return 0; - ao_lisp_stack->state = eval_sexpr; } return 1; } @@ -464,11 +463,11 @@ ao_lisp_eval_cond_test(void) DBGI(".. saved frame "); DBG_POLY(ao_lisp_stack->frame); DBG("\n"); if (ao_lisp_v) { struct ao_lisp_cons *car = ao_lisp_poly_cons(ao_lisp_poly_cons(ao_lisp_stack->sexprs)->car); - struct ao_lisp_cons *c = ao_lisp_poly_cons(car->cdr); + ao_poly c = car->cdr; if (c) { - ao_lisp_stack->state = eval_sexpr; - ao_lisp_v = c->car; + ao_lisp_stack->state = eval_progn; + ao_lisp_stack->sexprs = c; } else ao_lisp_stack->state = eval_val; } else { @@ -502,6 +501,10 @@ ao_lisp_eval_progn(void) } else { ao_lisp_v = ao_lisp_poly_cons(ao_lisp_stack->sexprs)->car; ao_lisp_stack->sexprs = ao_lisp_poly_cons(ao_lisp_stack->sexprs)->cdr; + + /* If there are more sexprs to do, then come back here, otherwise + * return the value of the last one by just landing in eval_sexpr + */ if (ao_lisp_stack->sexprs) { ao_lisp_stack->state = eval_progn; if (!ao_lisp_stack_push()) @@ -530,7 +533,6 @@ ao_lisp_eval_while(void) ao_lisp_stack->state = eval_while_test; if (!ao_lisp_stack_push()) return 0; - ao_lisp_stack->state = eval_sexpr; } return 1; } @@ -547,11 +549,11 @@ ao_lisp_eval_while_test(void) if (ao_lisp_v) { ao_lisp_v = ao_lisp_poly_cons(ao_lisp_stack->sexprs)->cdr; - if (ao_lisp_v) - ao_lisp_v = ao_lisp_poly_cons(ao_lisp_v)->car; ao_lisp_stack->state = eval_while; if (!ao_lisp_stack_push()) return 0; + ao_lisp_stack->state = eval_progn; + ao_lisp_stack->sexprs = ao_lisp_v; } else ao_lisp_stack->state = eval_val; @@ -567,6 +569,8 @@ 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_v == AO_LISP_NIL) + ao_lisp_abort(); 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; |