diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 13bfb038..9ee26d65 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.52 2006-04-18 10:28:03 bacon Exp $ + * $Id: awk.h,v 1.53 2006-04-18 16:04:54 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -73,6 +73,7 @@ enum XP_AWK_EDUPNAME, /* duplicate name - function, variable, etc */ XP_AWK_EUNDEF, /* undefined identifier */ XP_AWK_ELVALUE, /* l-value required */ + XP_AWK_ETOOMANYARGS, /* too many arguments */ /* run time error */ XP_AWK_EDIVBYZERO, /* divide by zero */ diff --git a/ase/awk/err.c b/ase/awk/err.c index 0ce2348e..0c6da985 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.11 2006-04-17 16:12:02 bacon Exp $ + * $Id: err.c,v 1.12 2006-04-18 16:04:54 bacon Exp $ */ #include @@ -43,6 +43,7 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) XP_TEXT("duplicate name"), XP_TEXT("undefined identifier"), XP_TEXT("l-value required"), + XP_TEXT("too many arguments"), XP_TEXT("divide by zero"), XP_TEXT("invalid operand"), diff --git a/ase/awk/parse.c b/ase/awk/parse.c index fac1a09d..80c48c98 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.83 2006-04-16 16:30:59 bacon Exp $ + * $Id: parse.c,v 1.84 2006-04-18 16:04:54 bacon Exp $ */ #include @@ -1806,10 +1806,12 @@ static xp_awk_nde_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name) { xp_awk_nde_t* head, * curr, * nde; xp_awk_nde_call_t* call; + xp_size_t nargs; if (__get_token(awk) == -1) return XP_NULL; head = curr = XP_NULL; + nargs = 0; if (MATCH(awk,TOKEN_RPAREN)) { @@ -1831,6 +1833,8 @@ static xp_awk_nde_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name) else curr->next = nde; curr = nde; + nargs++; + if (MATCH(awk,TOKEN_RPAREN)) { if (__get_token(awk) == -1) @@ -1867,6 +1871,7 @@ static xp_awk_nde_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name) call->next = XP_NULL; call->name = name; call->args = head; + call->nargs = nargs; return (xp_awk_nde_t*)call; } diff --git a/ase/awk/run.c b/ase/awk/run.c index 73f98263..fd6883ea 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.58 2006-04-18 15:38:05 bacon Exp $ + * $Id: run.c,v 1.59 2006-04-18 16:04:58 bacon Exp $ */ #include @@ -334,6 +334,7 @@ static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde) /*xp_printf (XP_TEXT("executing block statements\n"));*/ while (p != XP_NULL && awk->run.exit_level == EXIT_NONE) { +/*xp_printf (XP_TEXT("running a statement\n"));*/ if (__run_statement(awk,p) == -1) { n = -1; @@ -524,7 +525,6 @@ static int __run_for_statement (xp_awk_t* awk, xp_awk_nde_for_t* nde) { xp_awk_val_t* val; -xp_printf (XP_TEXT("__run_for_state...\n")); if (nde->init != XP_NULL) { val = __eval_expression(awk,nde->init); @@ -589,7 +589,6 @@ xp_printf (XP_TEXT("__run_for_state...\n")); } } -xp_printf (XP_TEXT("end of __run_for_state...\n")); return 0; } @@ -1951,10 +1950,19 @@ static xp_awk_val_t* __eval_call (xp_awk_t* awk, xp_awk_nde_t* nde) xp_awk_nde_call_t* call = (xp_awk_nde_call_t*)nde; int n; -xp_printf (XP_TEXT(".....__eval_call\n")); +/*xp_printf (XP_TEXT(".....__eval_call\n"));*/ pair = xp_awk_map_get (&awk->tree.funcs, call->name); if (pair == XP_NULL) PANIC (awk, XP_AWK_ENOSUCHFUNC); + func = (xp_awk_func_t*)pair->val; + xp_assert (func != XP_NULL); + + if (call->nargs > func->nargs) + { + /* TODO: is this correct? what if i want to allow arbitarary numbers of arguments? */ + PANIC (awk, XP_AWK_ETOOMANYARGS); + } + /* * --------------------- * localn <- stack top @@ -2077,13 +2085,32 @@ xp_printf (XP_TEXT(".....__eval_call\n")); p = p->next; } + xp_assert (nargs == call->nargs); + + while (nargs < func->nargs) + { + /* push as many nils as the number of missing actual arguments */ + if (__raw_push(awk,xp_awk_val_nil) == -1) + { + while (nargs > 0) + { +/* TODO: test this portion. */ + --nargs; + xp_awk_refdownval (awk, STACK_ARG(awk,nargs)); + __raw_pop (awk); + } + + __raw_pop (awk); + __raw_pop (awk); + __raw_pop (awk); + PANIC (awk, XP_AWK_ENOMEM); + } + + nargs++; + } + awk->run.stack_base = saved_stack_top; STACK_NARGS(awk) = (void*)nargs; - - func = (xp_awk_func_t*)pair->val; - xp_assert (func != XP_NULL); - - /* TODO: do i need to check if the number of arguments matches the actual arguments...???? this might be the compiler job... */ /*xp_printf (XP_TEXT("running function body\n")); */ @@ -2117,7 +2144,7 @@ xp_printf (XP_TEXT(".....__eval_call\n")); awk->run.exit_level = EXIT_NONE; } -xp_printf (XP_TEXT("returning from function stack_top=%ld, stack_base=%ld\n"), awk->run.stack_top, awk->run.stack_base); +/*xp_printf (XP_TEXT("returning from function stack_top=%ld, stack_base=%ld\n"), awk->run.stack_top, awk->run.stack_base); */ return (n == -1)? XP_NULL: v; } diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 0dc5c071..a04baab6 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.34 2006-04-16 16:30:59 bacon Exp $ + * $Id: tree.h,v 1.35 2006-04-18 16:04:59 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -173,6 +173,7 @@ struct xp_awk_nde_call_t XP_AWK_NDE_HDR; xp_char_t* name; xp_awk_nde_t* args; + xp_size_t nargs; }; /* XP_AWK_NDE_IF */