X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flisp%2Fao_lisp_lambda.c;h=cc333d6fc3a0dcc8252f8241fd4d21158da142f1;hb=b3b4731fcb89cb404433f37a7704a503567c43bd;hp=6020a8b8b1a8482e970d891c49306171d7e593b5;hpb=ddb4b8d90478ae324aa207a7541352c1ac9451ee;p=fw%2Faltos diff --git a/src/lisp/ao_lisp_lambda.c b/src/lisp/ao_lisp_lambda.c index 6020a8b8..cc333d6f 100644 --- a/src/lisp/ao_lisp_lambda.c +++ b/src/lisp/ao_lisp_lambda.c @@ -15,7 +15,6 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define DBG_EVAL 0 #include "ao_lisp.h" int @@ -78,8 +77,6 @@ ao_lisp_lambda_alloc(struct ao_lisp_cons *code, int args) if (!lambda) return AO_LISP_NIL; - if (!ao_lisp_check_argc(_ao_lisp_atom_lambda, code, 2, 2)) - return AO_LISP_NIL; if (!ao_lisp_check_argt(_ao_lisp_atom_lambda, code, 0, AO_LISP_CONS, 1)) return AO_LISP_NIL; f = 0; @@ -94,32 +91,32 @@ ao_lisp_lambda_alloc(struct ao_lisp_cons *code, int args) lambda->type = AO_LISP_LAMBDA; lambda->args = args; lambda->code = ao_lisp_cons_poly(code); - lambda->frame = ao_lisp_frame_poly(ao_lisp_frame_current); + lambda->frame = ao_lisp_frame_mark(ao_lisp_frame_current); DBGI("build frame: "); DBG_POLY(lambda->frame); DBG("\n"); DBG_STACK(); return ao_lisp_lambda_poly(lambda); } ao_poly -ao_lisp_lambda(struct ao_lisp_cons *cons) +ao_lisp_do_lambda(struct ao_lisp_cons *cons) { return ao_lisp_lambda_alloc(cons, AO_LISP_FUNC_LAMBDA); } ao_poly -ao_lisp_lexpr(struct ao_lisp_cons *cons) +ao_lisp_do_lexpr(struct ao_lisp_cons *cons) { return ao_lisp_lambda_alloc(cons, AO_LISP_FUNC_LEXPR); } ao_poly -ao_lisp_nlambda(struct ao_lisp_cons *cons) +ao_lisp_do_nlambda(struct ao_lisp_cons *cons) { return ao_lisp_lambda_alloc(cons, AO_LISP_FUNC_NLAMBDA); } ao_poly -ao_lisp_macro(struct ao_lisp_cons *cons) +ao_lisp_do_macro(struct ao_lisp_cons *cons) { return ao_lisp_lambda_alloc(cons, AO_LISP_FUNC_MACRO); } @@ -134,6 +131,8 @@ ao_lisp_lambda_eval(void) struct ao_lisp_frame *next_frame; int args_wanted; int args_provided; + int f; + struct ao_lisp_cons *vals; DBGI("lambda "); DBG_POLY(ao_lisp_lambda_poly(lambda)); DBG("\n"); @@ -141,12 +140,14 @@ ao_lisp_lambda_eval(void) /* Create a frame to hold the variables */ - if (lambda->args == AO_LISP_FUNC_LAMBDA) - args_provided = ao_lisp_cons_length(cons) - 1; - else - args_provided = 1; - if (args_wanted != args_provided) - return ao_lisp_error(AO_LISP_INVALID, "need %d args, not %d", args_wanted, args_provided); + args_provided = ao_lisp_cons_length(cons) - 1; + if (lambda->args == AO_LISP_FUNC_LAMBDA) { + if (args_wanted != args_provided) + return ao_lisp_error(AO_LISP_INVALID, "need %d args, got %d", args_wanted, args_provided); + } else { + if (args_provided < args_wanted - 1) + return ao_lisp_error(AO_LISP_INVALID, "need at least %d args, got %d", args_wanted, args_provided); + } next_frame = ao_lisp_frame_new(args_wanted); @@ -155,33 +156,41 @@ ao_lisp_lambda_eval(void) cons = ao_lisp_poly_cons(ao_lisp_stack->values); code = ao_lisp_poly_cons(lambda->code); args = ao_lisp_poly_cons(ao_lisp_arg(code, 0)); + vals = ao_lisp_poly_cons(cons->cdr); - switch (lambda->args) { - case AO_LISP_FUNC_LAMBDA: { - int f; - struct ao_lisp_cons *vals = ao_lisp_poly_cons(cons->cdr); + next_frame->prev = lambda->frame; + ao_lisp_frame_current = next_frame; + ao_lisp_stack->frame = ao_lisp_frame_poly(ao_lisp_frame_current); + 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"); - next_frame->vals[f].atom = args->car; - next_frame->vals[f].val = vals->car; + 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)) + ao_lisp_cons_free(cons); + cons = NULL; break; - } case AO_LISP_FUNC_LEXPR: case AO_LISP_FUNC_NLAMBDA: case AO_LISP_FUNC_MACRO: - DBGI("bind "); DBG_POLY(args->car); DBG(" = "); DBG_POLY(cons->cdr); DBG("\n"); - next_frame->vals[0].atom = args->car; - next_frame->vals[0].val = cons->cdr; + for (f = 0; f < args_wanted - 1; 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); + } + DBGI("bind "); DBG_POLY(args->car); DBG(" = "); DBG_POLY(ao_lisp_cons_poly(vals)); DBG("\n"); + ao_lisp_frame_bind(next_frame, f, args->car, ao_lisp_cons_poly(vals)); + break; + default: break; } - next_frame->next = lambda->frame; DBGI("eval frame: "); DBG_POLY(ao_lisp_frame_poly(next_frame)); DBG("\n"); - ao_lisp_frame_current = next_frame; - ao_lisp_stack->frame = ao_lisp_frame_poly(ao_lisp_frame_current); DBG_STACK(); - return ao_lisp_arg(code, 1); + DBGI("eval code: "); DBG_POLY(code->cdr); DBG("\n"); + return code->cdr; }