+ if (ao_lisp_exception)
+ return AO_LISP_NIL;
+ switch (stack->state) {
+ case eval_sexpr:
+ DBGI("sexpr: "); DBG_POLY(v); DBG("\n");
+ switch (ao_lisp_poly_type(v)) {
+ case AO_LISP_CONS:
+ if (v == AO_LISP_NIL) {
+ stack->state = eval_exec;
+ break;
+ }
+ stack->actuals = v;
+ stack = ao_lisp_stack_push();
+ v = ao_lisp_poly_cons(v)->car;
+ break;
+ case AO_LISP_ATOM:
+ v = ao_lisp_atom_get(v);
+ /* fall through */
+ case AO_LISP_INT:
+ case AO_LISP_STRING:
+ stack->state = eval_val;
+ break;
+ }
+ break;
+ case eval_val:
+ DBGI("val: "); DBG_POLY(v); DBG("\n");
+ stack = ao_lisp_stack_pop();
+ if (!stack)
+ return v;
+
+ stack->state = eval_sexpr;
+ /* Check what kind of function we've got */
+ if (!stack->formals) {
+ switch (func_type(v)) {
+ case AO_LISP_LAMBDA:
+ case _ao_lisp_atom_lambda:
+ case AO_LISP_LEXPR:
+ case _ao_lisp_atom_lexpr:
+ DBGI(".. lambda or lexpr\n");
+ break;
+ case AO_LISP_NLAMBDA:
+ case _ao_lisp_atom_nlambda:
+ case AO_LISP_MACRO:
+ case _ao_lisp_atom_macro:
+ DBGI(".. nlambda or macro\n");
+ stack->formals = stack->actuals;
+ stack->state = eval_exec_direct;
+ break;
+ }
+ if (stack->state == eval_exec_direct)
+ break;
+ }
+
+ formal = ao_lisp_cons_poly(ao_lisp_cons_cons(v, NULL));
+ if (!formal) {
+ ao_lisp_stack_clear();
+ return AO_LISP_NIL;
+ }
+
+ if (stack->formals_tail)
+ ao_lisp_poly_cons(stack->formals_tail)->cdr = formal;
+ else
+ stack->formals = formal;
+ stack->formals_tail = formal;
+
+ DBGI("formals now "); DBG_POLY(stack->formals); DBG("\n");
+
+ v = ao_lisp_poly_cons(stack->actuals)->cdr;
+
+ break;
+ case eval_exec:
+ v = ao_lisp_poly_cons(stack->formals)->car;
+ case eval_exec_direct:
+ DBGI("exec: "); DBG_POLY(v); DBG(" formals "); DBG_POLY(stack->formals); DBG ("\n");
+ if (ao_lisp_poly_type(v) == AO_LISP_BUILTIN) {
+ struct ao_lisp_builtin *b = ao_lisp_poly_builtin(v);
+
+ v = ao_lisp_func(b) (ao_lisp_poly_cons(ao_lisp_poly_cons(stack->formals)->cdr));
+ DBGI("builtin result:"); DBG_POLY(v); DBG ("\n");
+ if (ao_lisp_exception) {
+ ao_lisp_stack_clear();
+ return AO_LISP_NIL;
+ }
+ stack->state = eval_val;
+ break;
+ } else {
+ v = ao_lisp_lambda(ao_lisp_poly_cons(stack->formals));
+ ao_lisp_stack_reset(stack);
+ }
+ break;
+ }
+ }
+}
+#if 0
+