- switch (lambda->args) {
- case AO_LISP_FUNC_LAMBDA:
- for (f = 0; f < args_wanted; f++) {
- DBGI("bind "); DBG_POLY(args->car); DBG(" = "); DBG_POLY(vals->car); DBG("\n");
- ao_lisp_frame_bind(next_frame, f, args->car, vals->car);
- args = ao_lisp_poly_cons(args->cdr);
- vals = ao_lisp_poly_cons(vals->cdr);
- }
- if (!ao_lisp_stack_marked(ao_lisp_stack))
+ for (f = 0; f < args_wanted; f++) {
+ struct ao_lisp_cons *arg = ao_lisp_poly_cons(formals);
+ DBGI("bind "); DBG_POLY(arg->car); DBG(" = "); DBG_POLY(vals->car); DBG("\n");
+ ao_lisp_frame_bind(next_frame, f, arg->car, vals->car);
+ formals = arg->cdr;
+ vals = ao_lisp_poly_cons(vals->cdr);
+ }
+ if (varargs) {
+ DBGI("bind "); DBG_POLY(varargs); DBG(" = "); DBG_POLY(ao_lisp_cons_poly(vals)); DBG("\n");
+ /*
+ * Bind the rest of the arguments to the final parameter
+ */
+ ao_lisp_frame_bind(next_frame, f, varargs, ao_lisp_cons_poly(vals));
+ } else {
+ /*
+ * Mark the cons cells from the actuals as freed for immediate re-use, unless
+ * the actuals point into the source function (nlambdas and macros), or if the
+ * stack containing them was copied as a part of a continuation
+ */
+ if (lambda->args == AO_LISP_FUNC_LAMBDA && !ao_lisp_stack_marked(ao_lisp_stack)) {
+ ao_lisp_stack->values = AO_LISP_NIL;