- stack = 0;
- actuals = 0;
- formals = 0;
- formals_tail = 0;
- cond = 0;
- for (;;) {
-
- restart:
- if (cond) {
- if (cond->car == AO_LISP_NIL) {
- cond = AO_LISP_NIL;
- v = AO_LISP_NIL;
- } else {
- if (ao_lisp_poly_type(cond->car) != AO_LISP_CONS) {
- ao_lisp_error(AO_LISP_INVALID, "malformed cond");
- goto bail;
- }
- v = ao_lisp_poly_cons(cond->car)->car;
- }
- }
-
- /* Build stack frames for each list */
- while (ao_lisp_poly_type(v) == AO_LISP_CONS) {
- if (v == AO_LISP_NIL)
- break;
-
- /* Push existing bits on the stack */
- if (cons++)
- if (!ao_lisp_stack_push())
- goto bail;
-
- actuals = ao_lisp_poly_cons(v);
- formals = NULL;
- formals_tail = NULL;
- cond = NULL;
-
- v = actuals->car;
-
-// DBG("start: stack"); DBG_CONS(stack); DBG("\n");
-// DBG("start: actuals"); DBG_CONS(actuals); DBG("\n");
-// DBG("start: formals"); DBG_CONS(formals); DBG("\n");
- }
-
- /* Evaluate primitive types */
-
- DBG ("actual: "); DBG_POLY(v); DBG("\n");
-
- switch (ao_lisp_poly_type(v)) {
- case AO_LISP_INT:
- case AO_LISP_STRING:
- break;
- case AO_LISP_ATOM:
- v = ao_lisp_atom_get(v);
- break;
- }
-
- while (cons) {
- DBG("add formal: "); DBG_POLY(v); DBG("\n");
-
- /* We've processed the first element of the list, go check
- * what kind of function we've got
- */
- if (formals == NULL) {
- if (ao_lisp_poly_type(v) == AO_LISP_BUILTIN) {
- struct ao_lisp_builtin *b = ao_lisp_poly_builtin(v);
- switch (b->args) {
- case AO_LISP_NLAMBDA:
- formals = actuals;
- goto eval;
-
- case AO_LISP_MACRO:
- v = ao_lisp_func(b)(ao_lisp_poly_cons(actuals->cdr));
- DBG("macro "); DBG_POLY(ao_lisp_cons_poly(actuals));
- DBG(" -> "); DBG_POLY(v);
- DBG("\n");
- if (ao_lisp_poly_type(v) != AO_LISP_CONS) {
- ao_lisp_error(AO_LISP_INVALID, "macro didn't return list");
- goto bail;
- }
- /* Reset frame to the new list */
- actuals = ao_lisp_poly_cons(v);
- v = actuals->car;
- goto restart;
- }
- } else {
- switch (func_type(v)) {
- case _ao_lisp_atom_lambda:
- case _ao_lisp_atom_lexpr:
- break;
- case _ao_lisp_atom_nlambda:
- formals = actuals;
- goto eval;
- case _ao_lisp_atom_macro:
- break;
- default:
- ao_lisp_error(AO_LISP_INVALID, "operator is not a function");
- goto bail;
- }
- }
- }