diff --git a/ase/awk/func.c b/ase/awk/func.c index 1fd3b5cb..9eee7867 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.20 2006-08-17 14:10:20 bacon Exp $ + * $Id: func.c,v 1.21 2006-08-18 07:52:20 bacon Exp $ */ #include @@ -39,7 +39,7 @@ static xp_awk_bfn_t __sys_bfn[] = { XP_T("index"), 5, 0, 2, 2, XP_NULL, __bfn_index }, { XP_T("length"), 6, 0, 1, 1, XP_NULL, __bfn_length }, { XP_T("substr"), 6, 0, 2, 3, XP_NULL, __bfn_substr }, - { XP_T("split"), 5, 0, 2, 3, XP_NULL, __bfn_split }, + { XP_T("split"), 5, 0, 2, 3, XP_T("vmv"), __bfn_split }, { XP_T("tolower"), 7, 0, 1, 1, XP_NULL, __bfn_tolower }, { XP_T("toupper"), 7, 0, 1, 1, XP_NULL, __bfn_toupper }, @@ -440,19 +440,10 @@ static int __bfn_split (xp_awk_t* awk, void* run) } } - if (a1->type == XP_AWK_VAL_MAP) - { - /* clear the map */ - xp_awk_map_clear (((xp_awk_val_map_t*)a1)->map); - } - else - { -/* TODO: what should i do when it is nil??? */ - /* change it to a map */ - } - xp_assert (a1->type == XP_AWK_VAL_MAP); + xp_awk_map_clear (((xp_awk_val_map_t*)a1)->map); + p = str; left = len; num = 0; while (p != XP_NULL) { @@ -476,8 +467,8 @@ static int __bfn_split (xp_awk_t* awk, void* run) return -1; } - /* put it into the array */ - /* TODO: remove dependency on xp_sprintf */ + /* put it into the map */ +/* TODO: remove dependency on xp_sprintf */ #if defined(__LCC__) xp_sprintf (key, xp_countof(key), XP_T("%lld"), (long long)num); #elif defined(__BORLANDC__) || defined(_MSC_VER) @@ -497,6 +488,11 @@ static int __bfn_split (xp_awk_t* awk, void* run) return -1; } + /* don't forget to update the reference count + * when you handle the assignment-like situation + * with the internal data structures */ + xp_awk_refupval (r); + num++; len = len - (p - str); } diff --git a/ase/awk/run.c b/ase/awk/run.c index ae7f6680..700b3631 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.168 2006-08-17 14:10:20 bacon Exp $ + * $Id: run.c,v 1.169 2006-08-18 07:52:20 bacon Exp $ */ #include @@ -146,7 +146,8 @@ static xp_awk_val_t* __eval_cnd (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_bfn (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_afn (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_call ( - xp_awk_run_t* run, xp_awk_nde_t* nde, xp_awk_afn_t* afn); + xp_awk_run_t* run, xp_awk_nde_t* nde, + const xp_char_t* bfn_arg_spec, xp_awk_afn_t* afn); static xp_awk_val_t* __eval_int (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_real (xp_awk_run_t* run, xp_awk_nde_t* nde); @@ -164,7 +165,11 @@ static xp_awk_val_t* __eval_pos (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde); static int __raw_push (xp_awk_run_t* run, void* val); -static void __raw_pop (xp_awk_run_t* run); +#define __raw_pop(run) \ + do { \ + xp_assert ((run)->stack_top > (run)->stack_base); \ + (run)->stack_top--; \ + } while (0) static void __raw_pop_times (xp_awk_run_t* run, xp_size_t times); static int __read_record (xp_awk_run_t* run); @@ -568,7 +573,6 @@ static int __run_main (xp_awk_run_t* run) /* restore the stack top in a cheesy(?) way */ run->stack_top = saved_stack_top; /* pops off global variables in a decent way */ - /*__raw_pop_times (run, run->nglobals);*/ __raw_pop_times (run, run->awk->tree.nglobals); PANIC_I (run, XP_AWK_ENOMEM); } @@ -576,7 +580,6 @@ static int __run_main (xp_awk_run_t* run) if (__raw_push(run,(void*)saved_stack_top) == -1) { run->stack_top = saved_stack_top; - /*__raw_pop_times (run, run->nglobals);*/ __raw_pop_times (run, run->awk->tree.nglobals); PANIC_I (run, XP_AWK_ENOMEM); } @@ -585,7 +588,6 @@ static int __run_main (xp_awk_run_t* run) if (__raw_push(run,xp_awk_val_nil) == -1) { run->stack_top = saved_stack_top; - /*__raw_pop_times (run, run->nglobals);*/ __raw_pop_times (run, run->awk->tree.nglobals); PANIC_I (run, XP_AWK_ENOMEM); } @@ -594,7 +596,6 @@ static int __run_main (xp_awk_run_t* run) if (__raw_push(run,xp_awk_val_nil) == -1) { run->stack_top = saved_stack_top; - /*__raw_pop_times (run, run->nglobals);*/ __raw_pop_times (run, run->awk->tree.nglobals); PANIC_I (run, XP_AWK_ENOMEM); } @@ -3719,7 +3720,7 @@ static xp_awk_val_t* __eval_bfn (xp_awk_run_t* run, xp_awk_nde_t* nde) PANIC (run, XP_AWK_ETOOMANYARGS); } - return __eval_call (run, nde, XP_NULL); + return __eval_call (run, nde, call->what.bfn.arg_spec, XP_NULL); } static xp_awk_val_t* __eval_afn (xp_awk_run_t* run, xp_awk_nde_t* nde) @@ -3741,11 +3742,30 @@ static xp_awk_val_t* __eval_afn (xp_awk_run_t* run, xp_awk_nde_t* nde) PANIC (run, XP_AWK_ETOOMANYARGS); } - return __eval_call (run, nde, afn); + return __eval_call (run, nde, XP_NULL, afn); } + +/* run->stack_base has not been set for this + * stack frame. so STACK_ARG cannot be used */ +/*xp_awk_refdownval (run, STACK_ARG(run,nargs));*/ +#define UNWIND_RUN_STACK(run,nargs) \ + do { \ + while ((nargs) > 0) \ + { \ + --(nargs); \ + xp_awk_refdownval ((run), \ + (run)->stack[(run)->stack_top-1]); \ + __raw_pop (run); \ + } \ + __raw_pop (run); \ + __raw_pop (run); \ + __raw_pop (run); \ + } while (0) + static xp_awk_val_t* __eval_call ( - xp_awk_run_t* run, xp_awk_nde_t* nde, xp_awk_afn_t* afn) + xp_awk_run_t* run, xp_awk_nde_t* nde, + const xp_char_t* bfn_arg_spec, xp_awk_afn_t* afn) { xp_awk_nde_call_t* call = (xp_awk_nde_call_t*)nde; xp_size_t saved_stack_top; @@ -3804,6 +3824,7 @@ static xp_awk_val_t* __eval_call ( { PANIC (run, XP_AWK_ENOMEM); } + if (__raw_push(run,(void*)saved_stack_top) == -1) { __raw_pop (run); @@ -3834,40 +3855,47 @@ static xp_awk_val_t* __eval_call ( v = __eval_expression(run,p); if (v == XP_NULL) { - while (nargs > 0) - { -/* TODO: test this portion. */ - --nargs; - xp_awk_refdownval (run, STACK_ARG(run,nargs)); - __raw_pop (run); - } - - __raw_pop (run); - __raw_pop (run); - __raw_pop (run); + UNWIND_RUN_STACK (run, nargs); return XP_NULL; } + if (bfn_arg_spec != XP_NULL) + { + xp_char_t spec; + + /* TODO: spec length check */ + spec = bfn_arg_spec[nargs]; + if (spec == XP_T('m')) + { + /*if (v->type == XP_AWK_VAL_NIL) + { + convert it to a map... + do assignment if the value is by the variable + } + else*/ if (v->type != XP_AWK_VAL_MAP) + { + /* trigger an error */ + xp_awk_refupval (v); + xp_awk_refdownval (run, v); + + UNWIND_RUN_STACK (run, nargs); + /* TODO: change the error code */ + PANIC (run, XP_AWK_EVALTYPE); + } + } + } + if (__raw_push(run,v) == -1) { /* ugly - v needs to be freed if it doesn't have * any reference. but its reference has not been - * updated for the successful stack push. so it adds - * up a reference and dereferences it*/ + * updated yet as it is carried out after the + * successful stack push. so it adds up a reference + * and dereferences it */ xp_awk_refupval (v); xp_awk_refdownval (run, v); - while (nargs > 0) - { -/* TODO: test this portion. */ - --nargs; - xp_awk_refdownval (run, STACK_ARG(run,nargs)); - __raw_pop (run); - } - - __raw_pop (run); - __raw_pop (run); - __raw_pop (run); + UNWIND_RUN_STACK (run, nargs); PANIC (run, XP_AWK_ENOMEM); } @@ -3887,17 +3915,7 @@ static xp_awk_val_t* __eval_call ( /* push as many nils as the number of missing actual arguments */ if (__raw_push(run,xp_awk_val_nil) == -1) { - while (nargs > 0) - { - /* TODO: test this portion. */ - --nargs; - xp_awk_refdownval (run, STACK_ARG(run,nargs)); - __raw_pop (run); - } - - __raw_pop (run); - __raw_pop (run); - __raw_pop (run); + UNWIND_RUN_STACK (run, nargs); PANIC (run, XP_AWK_ENOMEM); } @@ -4275,12 +4293,6 @@ static int __raw_push (xp_awk_run_t* run, void* val) return 0; } -static void __raw_pop (xp_awk_run_t* run) -{ - xp_assert (run->stack_top > run->stack_base); - run->stack_top--; -} - static void __raw_pop_times (xp_awk_run_t* run, xp_size_t times) { while (times > 0) diff --git a/ase/test/awk/t28.awk b/ase/test/awk/t28.awk index c99eb848..17dc38c3 100644 --- a/ase/test/awk/t28.awk +++ b/ase/test/awk/t28.awk @@ -21,7 +21,8 @@ END { print toupper ("AbcDEF"); arr[0] = "xxx"; - print split ("abc def abc", arr); + //print split ("abc def abc", arr); + print split ("abc def abc", 10); for (i in arr) { print i, " ", arr[i]; diff --git a/ase/test/awk/xptestawk.dsp b/ase/test/awk/xptestawk.dsp index 0e864530..27e2f290 100644 --- a/ase/test/awk/xptestawk.dsp +++ b/ase/test/awk/xptestawk.dsp @@ -87,7 +87,7 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\rex3.c +SOURCE=.\awk.c # End Source File # End Group # Begin Group "Header Files"