- break;
- case eval_exec:
- if (!ao_lisp_stack->formals) {
- ao_lisp_v = AO_LISP_NIL;
- ao_lisp_stack->state = eval_val;
- break;
- }
- ao_lisp_v = ao_lisp_poly_cons(ao_lisp_stack->formals)->car;
- case eval_exec_direct:
- DBGI("exec: macro %d ", ao_lisp_stack->macro); DBG_POLY(ao_lisp_v); DBG(" formals "); DBG_POLY(ao_lisp_stack->formals); DBG ("\n");
- if (ao_lisp_poly_type(ao_lisp_v) == AO_LISP_BUILTIN) {
- stack_validate_tails();
- struct ao_lisp_builtin *b = ao_lisp_poly_builtin(ao_lisp_v);
- stack_validate_tails();
- struct ao_lisp_cons *f = ao_lisp_poly_cons(ao_lisp_poly_cons(ao_lisp_stack->formals)->cdr);
-
- DBGI(".. builtin formals "); DBG_CONS(f); DBG("\n");
- stack_validate_tails();
- if (ao_lisp_stack->macro)
- ao_lisp_stack->state = eval_sexpr;
- else
- ao_lisp_stack->state = eval_val;
- ao_lisp_stack->macro = 0;
- ao_lisp_stack->actuals = ao_lisp_stack->formals = ao_lisp_stack->formals_tail = AO_LISP_NIL;
- ao_lisp_v = ao_lisp_func(b) (f);
- DBGI("builtin result:"); DBG_POLY(ao_lisp_v); DBG ("\n");
- if (ao_lisp_exception)
- goto bail;
- break;
- } else {
- ao_lisp_v = ao_lisp_lambda(ao_lisp_poly_cons(ao_lisp_stack->formals));
- ao_lisp_stack_reset(ao_lisp_stack);
- }
- break;
- case eval_cond:
- DBGI("cond: "); DBG_POLY(ao_lisp_stack->actuals); DBG("\n");
- if (!ao_lisp_stack->actuals) {
- ao_lisp_v = AO_LISP_NIL;
- ao_lisp_stack->state = eval_val;
- } else {
- ao_lisp_v = ao_lisp_poly_cons(ao_lisp_stack->actuals)->car;
- if (!ao_lisp_v || ao_lisp_poly_type(ao_lisp_v) != AO_LISP_CONS) {
- ao_lisp_error(AO_LISP_INVALID, "invalid cond clause");
- goto bail;
- }
- ao_lisp_v = ao_lisp_poly_cons(ao_lisp_v)->car;
- ao_lisp_stack->state = eval_cond_test;
- stack_validate_tails();
- ao_lisp_stack_push();
- stack_validate_tails();
- ao_lisp_stack->state = eval_sexpr;
- }
- break;
- case eval_cond_test:
- DBGI("cond_test: "); DBG_POLY(ao_lisp_v); DBG(" actuals "); DBG_POLY(ao_lisp_stack->actuals); DBG("\n");
- if (ao_lisp_v) {
- struct ao_lisp_cons *car = ao_lisp_poly_cons(ao_lisp_poly_cons(ao_lisp_stack->actuals)->car);
- struct ao_lisp_cons *c = ao_lisp_poly_cons(car->cdr);
- if (c) {
- ao_lisp_v = c->car;
- ao_lisp_stack->state = eval_sexpr;
- } else {
- ao_lisp_stack->state = eval_val;
- }
- } else {
- ao_lisp_stack->actuals = ao_lisp_poly_cons(ao_lisp_stack->actuals)->cdr;
- DBGI("actuals now "); DBG_POLY(ao_lisp_stack->actuals); DBG("\n");
- ao_lisp_stack->state = eval_cond;
- }
- break;
+/*
+ * 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)
+{
+ ao_lisp_v = _v;
+
+ if (!ao_lisp_stack_push())
+ return AO_LISP_NIL;
+
+ while (ao_lisp_stack) {
+ if (!(*evals[ao_lisp_stack->state])() || ao_lisp_exception) {
+ ao_lisp_stack_clear();
+ return AO_LISP_NIL;