diff --git a/ase/awk/awk.h b/ase/awk/awk.h index d9e4372b..1aabbaea 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.97 2006-08-16 08:55:42 bacon Exp $ + * $Id: awk.h,v 1.98 2006-08-20 15:49:06 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -207,20 +207,23 @@ enum XP_AWK_EGETLINE, /* getline expected */ /* run time error */ - XP_AWK_EDIVBYZERO, /* divide by zero */ - XP_AWK_EOPERAND, /* invalid operand */ - XP_AWK_EPOSIDX, /* wrong position index */ - XP_AWK_ENOSUCHFUNC, /* no such function */ - XP_AWK_ENOTASSIGNABLE, /* value not assignable */ - XP_AWK_ENOTINDEXABLE, /* not indexable variable */ - XP_AWK_ENOTDELETABLE, /* not deletable variable */ - XP_AWK_ENOTSCALARIZABLE, /* not scalarizable variable */ - XP_AWK_EVALTYPE, /* wrong value type */ - XP_AWK_EPIPE, /* pipe operation error */ - XP_AWK_ENEXTCALL, /* next called from BEGIN or END */ - XP_AWK_ENEXTFILECALL, /* nextfile called from BEGIN or END */ - XP_AWK_EIOIMPL, /* wrong implementation of user io handler */ - XP_AWK_EINTERNAL, /* internal error */ + XP_AWK_EDIVBYZERO, /* divide by zero */ + XP_AWK_EOPERAND, /* invalid operand */ + XP_AWK_EPOSIDX, /* wrong position index */ + XP_AWK_ENOSUCHFUNC, /* no such function */ + XP_AWK_ENOTASSIGNABLE, /* value not assignable */ + XP_AWK_ENOTINDEXABLE, /* not indexable variable */ + XP_AWK_ENOTDELETABLE, /* not deletable variable */ + XP_AWK_ENOTREFERENCEABLE, /* not referenceable value */ + XP_AWK_EIDXVALASSMAP, /* indexed value cannot be assigned a map */ + XP_AWK_EMAPTOSCALAR, /* cannot change a map to a scalar value */ + XP_AWK_ESCALARTOMAP, /* cannot change a scalar value to a map */ + XP_AWK_EVALTYPE, /* wrong value type */ + XP_AWK_EPIPE, /* pipe operation error */ + XP_AWK_ENEXTCALL, /* next called from BEGIN or END */ + XP_AWK_ENEXTFILECALL, /* nextfile called from BEGIN or END */ + XP_AWK_EIOIMPL, /* wrong implementation of user io handler */ + XP_AWK_EINTERNAL, /* internal error */ /* regular expression error */ XP_AWK_EREXRPAREN, /* a right parenthesis is expected */ diff --git a/ase/awk/err.c b/ase/awk/err.c index 061cef3c..641cd12d 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.36 2006-08-16 08:55:43 bacon Exp $ + * $Id: err.c,v 1.37 2006-08-20 15:49:06 bacon Exp $ */ #include @@ -87,7 +87,10 @@ const xp_char_t* xp_awk_geterrstr (int errnum) XP_T("value not assignable"), XP_T("variable not indexable"), XP_T("variable not deletable"), - XP_T("variable not scalarizable"), + XP_T("value not referenceable"), + XP_T("indexed value cannot be assigned a map"), + XP_T("cannot change a map to a scalar value"), + XP_T("cannot change a scalar value to a map"), XP_T("wrong value type"), XP_T("pipe operation error"), XP_T("next cannot be called from the BEGIN or END block"), diff --git a/ase/awk/func.c b/ase/awk/func.c index c36d4391..8aed742a 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.23 2006-08-19 16:34:24 bacon Exp $ + * $Id: func.c,v 1.24 2006-08-20 15:49:06 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_T("vmv"), __bfn_split }, + { XP_T("split"), 5, 0, 2, 3, XP_T("vrv"), __bfn_split }, { XP_T("tolower"), 7, 0, 1, 1, XP_NULL, __bfn_tolower }, { XP_T("toupper"), 7, 0, 1, 1, XP_NULL, __bfn_toupper }, @@ -408,109 +408,6 @@ static int __bfn_substr (xp_awk_t* awk, void* run) return 0; } -#if 0 -static int __bfn_split (xp_awk_t* awk, void* run) -{ - xp_size_t nargs; - xp_awk_val_t* a0, * a1, * a2, * r; - xp_char_t* str, * p, * tok; - xp_size_t len, left, tok_len; - xp_long_t num; - int errnum; - xp_char_t key[32]; - - nargs = xp_awk_getnargs (run); - xp_assert (nargs >= 2 && nargs <= 3); - - a0 = xp_awk_getarg (run, 0); - a1 = xp_awk_getarg (run, 1); - a2 = (nargs >= 3)? xp_awk_getarg (run, 2): XP_NULL; - - if (a0->type == XP_AWK_VAL_STR) - { - str = ((xp_awk_val_str_t*)a0)->buf; - len = ((xp_awk_val_str_t*)a0)->len; - } - else - { - str = xp_awk_valtostr (a0, &errnum, xp_true, XP_NULL, &len); - if (str == XP_NULL) - { - xp_awk_seterrnum (run, errnum); - return -1; - } - } - - 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) - { - /* TODO: use FS when a2 is missing. apply a difference scheme */ - p = xp_strxtok (p, left, XP_T(" \t"), &tok, &tok_len); - - if (num == 0 && p == XP_NULL && tok_len == 0) - { - /* no field at all*/ - break; - } - - xp_assert ((tok != XP_NULL && tok_len > 0) || tok_len == 0); - - /* create the field string */ - r = xp_awk_makestrval (tok, tok_len); - if (r == XP_NULL) - { - if (a0->type != XP_AWK_VAL_STR) xp_free (str); - xp_awk_seterrnum (run, XP_AWK_ENOMEM); - return -1; - } - - /* 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) - xp_sprintf (key, xp_countof(key), XP_T("%I64d"), (__int64)num); - #elif defined(vax) || defined(__vax) || defined(_SCO_DS) - xp_sprintf (key, xp_countof(key), XP_T("%ld"), (long)num); - #else - xp_sprintf (key, xp_countof(key), XP_T("%lld"), (long long)num); - #endif - - if (xp_awk_map_putx ( - ((xp_awk_val_map_t*)a1)->map, - key, xp_strlen(key), r, XP_NULL) == -1) - { - if (a0->type != XP_AWK_VAL_STR) xp_free (str); - xp_awk_seterrnum (run, XP_AWK_ENOMEM); - 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); - } - - if (a0->type != XP_AWK_VAL_STR) xp_free (str); - - r = xp_awk_makeintval (run, num); - if (r == XP_NULL) - { - xp_awk_seterrnum (run, XP_AWK_ENOMEM); - return -1; - } - - xp_awk_setretval (run, r); - return 0; -} -#endif static int __bfn_split (xp_awk_t* awk, void* run) { xp_size_t nargs; @@ -528,6 +425,25 @@ static int __bfn_split (xp_awk_t* awk, void* run) a1 = xp_awk_getarg (run, 1); a2 = (nargs >= 3)? xp_awk_getarg (run, 2): XP_NULL; + xp_assert (a1->type == XP_AWK_VAL_REF); + + if (((xp_awk_val_ref_t*)a1)->id >= XP_AWK_VAL_REF_NAMEDIDX && + ((xp_awk_val_ref_t*)a1)->id <= XP_AWK_VAL_REF_ARGIDX) + { + /* an indexed value should not be assigned another map */ + xp_awk_seterrnum (run, XP_AWK_EIDXVALASSMAP); + return -1; + } + + a1r = (xp_awk_val_t**)((xp_awk_val_ref_t*)a1)->adr; + if ((*a1r)->type != XP_AWK_VAL_NIL && + (*a1r)->type != XP_AWK_VAL_MAP) + { + /* cannot change a scalar value to a map */ + xp_awk_seterrnum (run, XP_AWK_ESCALARTOMAP); + return -1; + } + if (a0->type == XP_AWK_VAL_STR) { str = ((xp_awk_val_str_t*)a0)->buf; @@ -543,10 +459,6 @@ static int __bfn_split (xp_awk_t* awk, void* run) } } - xp_assert (a1->type == XP_AWK_VAL_INT); - a1r = (xp_awk_val_t**)((xp_awk_val_int_t*)a1)->val; - -/* TODO: check memory leaks and other errors */ t1 = xp_awk_makemapval (run); if (t1 == XP_NULL) { @@ -562,7 +474,7 @@ static int __bfn_split (xp_awk_t* awk, void* run) p = str; left = len; num = 0; while (p != XP_NULL) { - /* TODO: use FS when a2 is missing. apply a difference scheme */ +/* TODO: use FS when a2 is missing. apply a difference scheme */ p = xp_strxtok (p, left, XP_T(" \t"), &tok, &tok_len); if (num == 0 && p == XP_NULL && tok_len == 0) diff --git a/ase/awk/run.c b/ase/awk/run.c index 9e8ef547..05c36271 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.171 2006-08-19 16:34:24 bacon Exp $ + * $Id: run.c,v 1.172 2006-08-20 15:49:06 bacon Exp $ */ #include @@ -147,7 +147,10 @@ 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, const xp_char_t* bfn_arg_spec, xp_awk_afn_t* afn); -static void* __get_reference (xp_awk_run_t* run, xp_awk_nde_t* nde); + +static xp_awk_val_t** __get_reference (xp_awk_run_t* run, xp_awk_nde_t* nde); +static xp_awk_val_t** __get_reference_indexed ( + xp_awk_run_t* run, xp_awk_nde_var_t* nde, xp_awk_val_t** val); 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); @@ -1930,7 +1933,7 @@ static xp_awk_val_t* __do_assignment_scalar ( { /* once a variable becomes an array, * it cannot be changed to a scalar variable */ - PANIC (run, XP_AWK_ENOTSCALARIZABLE); + PANIC (run, XP_AWK_EMAPTOSCALAR); } n = xp_awk_map_putx (&run->named, @@ -1946,7 +1949,7 @@ static xp_awk_val_t* __do_assignment_scalar ( { /* once a variable becomes an array, * it cannot be changed to a scalar variable */ - PANIC (run, XP_AWK_ENOTSCALARIZABLE); + PANIC (run, XP_AWK_EMAPTOSCALAR); } /* TODO: if var->id.idxa == XP_AWK_GLOBAL_NF recompute $0, etc */ @@ -1961,7 +1964,7 @@ static xp_awk_val_t* __do_assignment_scalar ( { /* once the variable becomes an array, * it cannot be changed to a scalar variable */ - PANIC (run, XP_AWK_ENOTSCALARIZABLE); + PANIC (run, XP_AWK_EMAPTOSCALAR); } xp_awk_refdownval (run, old); @@ -1975,7 +1978,7 @@ static xp_awk_val_t* __do_assignment_scalar ( { /* once the variable becomes an array, * it cannot be changed to a scalar variable */ - PANIC (run, XP_AWK_ENOTSCALARIZABLE); + PANIC (run, XP_AWK_EMAPTOSCALAR); } xp_awk_refdownval (run, old); @@ -3865,24 +3868,25 @@ static xp_awk_val_t* __eval_call ( /* TODO: spec length check */ spec = bfn_arg_spec[nargs]; - if (spec == XP_T('m')) + if (spec == XP_T('r')) { - void* ref; + xp_awk_val_t** ref; xp_awk_val_t* tmp; ref = __get_reference (run, p); - if (ref == XP_NULL) { xp_awk_refupval (v); xp_awk_refdownval (run, v); UNWIND_RUN_STACK (run, nargs); - /* TODO: change error code */ - PANIC (run, XP_AWK_EVALTYPE); + return XP_NULL; } - tmp = xp_awk_makeintval (run, (xp_long_t)ref); + /* p->type-XP_AWK_NDE_NAMED assumes that the + * derived value matches XP_AWK_VAL_REF_XXX */ + tmp = xp_awk_makerefval ( + run, p->type-XP_AWK_NDE_NAMED, ref); if (tmp == XP_NULL) { xp_awk_refupval (v); @@ -3897,45 +3901,6 @@ static xp_awk_val_t* __eval_call ( v = tmp; } - -#if 0 - if (spec == XP_T('m')) - { - if (v->type == XP_AWK_VAL_NIL) - { - xp_awk_val_t* tmp; - - tmp = xp_awk_makemapval (run); - if (tmp == XP_NULL) - { - xp_awk_refupval (v); - xp_awk_refdownval (run, v); - - UNWIND_RUN_STACK (run, nargs); - PANIC (run, XP_AWK_ENOMEM); - } - - xp_awk_refupval (v); - xp_awk_refdownval (run, v); - - v = tmp; - } - else if (v->type != XP_AWK_VAL_MAP) - { - xp_awk_refupval (v); - xp_awk_refdownval (run, v); - - UNWIND_RUN_STACK (run, nargs); - /* TODO: change the error code */ - PANIC (run, XP_AWK_EVALTYPE); - } - } - /* - else if (spec = XP_T('s')) - { - } - */ -#endif } if (__raw_push(run,v) == -1) @@ -4027,24 +3992,136 @@ static xp_awk_val_t* __eval_call ( return (n == -1)? XP_NULL: v; } -static void* __get_reference (xp_awk_run_t* run, xp_awk_nde_t* nde) +static xp_awk_val_t** __get_reference (xp_awk_run_t* run, xp_awk_nde_t* nde) { xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; + /* refer to __eval_indexed for application of similar concept */ + + if (nde->type == XP_AWK_NDE_NAMED) + { + xp_awk_pair_t* pair; + + pair = xp_awk_map_get ( + &run->named, tgt->id.name, tgt->id.name_len); + if (pair == XP_NULL) + { + /* it is bad that the named variable has to be + * created in the function named "__get_refernce". + * would there be any better ways to avoid this? */ + pair = xp_awk_map_put ( + &run->named, tgt->id.name, + tgt->id.name_len, xp_awk_val_nil); + if (pair == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + } + + return (xp_awk_val_t**)&pair->val; + } + if (nde->type == XP_AWK_NDE_GLOBAL) - return &STACK_GLOBAL(run,tgt->id.idxa); + { + return (xp_awk_val_t**)&STACK_GLOBAL(run,tgt->id.idxa); + } if (nde->type == XP_AWK_NDE_LOCAL) - return &STACK_LOCAL(run,tgt->id.idxa); + { + return (xp_awk_val_t**)&STACK_LOCAL(run,tgt->id.idxa); + } if (nde->type == XP_AWK_NDE_ARG) - return &STACK_ARG(run,tgt->id.idxa); + { + return (xp_awk_val_t**)&STACK_ARG(run,tgt->id.idxa); + } - /* TODO: NAMED ... */ + if (nde->type == XP_AWK_NDE_NAMEDIDX) + { + xp_awk_pair_t* pair; - return XP_NULL; + pair = xp_awk_map_get ( + &run->named, tgt->id.name, tgt->id.name_len); + if (pair == XP_NULL) + { + pair = xp_awk_map_put ( + &run->named, tgt->id.name, + tgt->id.name_len, xp_awk_val_nil); + if (pair == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + } + + return __get_reference_indexed ( + run, tgt, (xp_awk_val_t**)&pair->val); + } + + + if (nde->type == XP_AWK_NDE_GLOBALIDX) + { + return __get_reference_indexed (run, tgt, + (xp_awk_val_t**)&STACK_GLOBAL(run,tgt->id.idxa)); + } + + if (nde->type == XP_AWK_NDE_LOCALIDX) + { + return __get_reference_indexed (run, tgt, + (xp_awk_val_t**)&STACK_LOCAL(run,tgt->id.idxa)); + } + + if (nde->type == XP_AWK_NDE_ARGIDX) + { + return __get_reference_indexed (run, tgt, + (xp_awk_val_t**)&STACK_ARG(run,tgt->id.idxa)); + } + + PANIC (run, XP_AWK_ENOTREFERENCEABLE); } - + +static xp_awk_val_t** __get_reference_indexed ( + xp_awk_run_t* run, xp_awk_nde_var_t* nde, xp_awk_val_t** val) +{ + xp_awk_pair_t* pair; + xp_char_t* str; + xp_size_t len; + + xp_assert (val != XP_NULL); + + if ((*val)->type == XP_AWK_VAL_NIL) + { + xp_awk_val_t* tmp; + + tmp = xp_awk_makemapval (run); + if (tmp == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + + xp_awk_refdownval (run, *val); + *val = tmp; + xp_awk_refupval ((xp_awk_val_t*)*val); + } + else if ((*val)->type != XP_AWK_VAL_MAP) + { + PANIC (run, XP_AWK_ENOTINDEXABLE); + } + + xp_assert (nde->idx != XP_NULL); + + str = __idxnde_to_str (run, nde->idx, &len); + if (str == XP_NULL) return XP_NULL; + + pair = xp_awk_map_get ((*(xp_awk_val_map_t**)val)->map, str, len); + if (pair == XP_NULL) + { + pair = xp_awk_map_put ( + (*(xp_awk_val_map_t**)val)->map, + str, len, xp_awk_val_nil); + if (pair == XP_NULL) + { + xp_free (str); + PANIC (run, XP_AWK_ENOMEM); + } + + xp_awk_refupval (pair->val); + } + + xp_free (str); + return (xp_awk_val_t**)&pair->val; +} + static xp_awk_val_t* __eval_int (xp_awk_run_t* run, xp_awk_nde_t* nde) { xp_awk_val_t* val; @@ -4091,40 +4168,50 @@ static xp_awk_val_t* __eval_rex (xp_awk_run_t* run, xp_awk_nde_t* nde) static xp_awk_val_t* __eval_named (xp_awk_run_t* run, xp_awk_nde_t* nde) { xp_awk_pair_t* pair; - xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; - pair = xp_awk_map_get (&run->named, tgt->id.name, tgt->id.name_len); + pair = xp_awk_map_get (&run->named, + ((xp_awk_nde_var_t*)nde)->id.name, + ((xp_awk_nde_var_t*)nde)->id.name_len); + return (pair == XP_NULL)? xp_awk_val_nil: pair->val; } static xp_awk_val_t* __eval_global (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; - return STACK_GLOBAL(run,tgt->id.idxa); + return STACK_GLOBAL(run,((xp_awk_nde_var_t*)nde)->id.idxa); } static xp_awk_val_t* __eval_local (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; - return STACK_LOCAL(run,tgt->id.idxa); + return STACK_LOCAL(run,((xp_awk_nde_var_t*)nde)->id.idxa); } static xp_awk_val_t* __eval_arg (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; - return STACK_ARG(run,tgt->id.idxa); + return STACK_ARG(run,((xp_awk_nde_var_t*)nde)->id.idxa); } static xp_awk_val_t* __eval_indexed ( - xp_awk_run_t* run, xp_awk_nde_var_t* nde, xp_awk_val_map_t* map) + xp_awk_run_t* run, xp_awk_nde_var_t* nde, xp_awk_val_t** val) { - xp_awk_val_t* res; xp_awk_pair_t* pair; xp_char_t* str; xp_size_t len; - /* TODO: should it be an error? should it return nil? */ - if (map->type != XP_AWK_VAL_MAP) + xp_assert (val != XP_NULL); + + if ((*val)->type == XP_AWK_VAL_NIL) + { + xp_awk_val_t* tmp; + + tmp = xp_awk_makemapval (run); + if (tmp == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + + xp_awk_refdownval (run, *val); + *val = tmp; + xp_awk_refupval ((xp_awk_val_t*)*val); + } + else if ((*val)->type != XP_AWK_VAL_MAP) { PANIC (run, XP_AWK_ENOTINDEXABLE); } @@ -4134,12 +4221,10 @@ static xp_awk_val_t* __eval_indexed ( str = __idxnde_to_str (run, nde->idx, &len); if (str == XP_NULL) return XP_NULL; -/* TODO: check this out........ */ - pair = xp_awk_map_get (((xp_awk_val_map_t*)map)->map, str, len); - res = (pair == XP_NULL)? xp_awk_val_nil: (xp_awk_val_t*)pair->val; - + pair = xp_awk_map_get ((*(xp_awk_val_map_t**)val)->map, str, len); xp_free (str); - return res; + + return (pair == XP_NULL)? xp_awk_val_nil: (xp_awk_val_t*)pair->val; } static xp_awk_val_t* __eval_namedidx (xp_awk_run_t* run, xp_awk_nde_t* nde) @@ -4148,26 +4233,34 @@ static xp_awk_val_t* __eval_namedidx (xp_awk_run_t* run, xp_awk_nde_t* nde) xp_awk_pair_t* pair; pair = xp_awk_map_get (&run->named, tgt->id.name, tgt->id.name_len); - return __eval_indexed (run, tgt, - (pair == XP_NULL)? xp_awk_val_nil: pair->val); + if (pair == XP_NULL) + { + pair = xp_awk_map_put (&run->named, + tgt->id.name, tgt->id.name_len, xp_awk_val_nil); + if (pair == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + + xp_awk_refupval (pair->val); + } + + return __eval_indexed (run, tgt, (xp_awk_val_t**)&pair->val); } static xp_awk_val_t* __eval_globalidx (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; - return __eval_indexed (run, tgt, STACK_GLOBAL(run,tgt->id.idxa)); + return __eval_indexed (run, (xp_awk_nde_var_t*)nde, + (xp_awk_val_t**)&STACK_GLOBAL(run,((xp_awk_nde_var_t*)nde)->id.idxa)); } static xp_awk_val_t* __eval_localidx (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; - return __eval_indexed (run, tgt, STACK_LOCAL(run,tgt->id.idxa)); + return __eval_indexed (run, (xp_awk_nde_var_t*)nde, + (xp_awk_val_t**)&STACK_LOCAL(run,((xp_awk_nde_var_t*)nde)->id.idxa)); } static xp_awk_val_t* __eval_argidx (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; - return __eval_indexed (run, tgt, STACK_ARG(run,tgt->id.idxa)); + return __eval_indexed (run, (xp_awk_nde_var_t*)nde, + (xp_awk_val_t**)&STACK_ARG(run,((xp_awk_nde_var_t*)nde)->id.idxa)); } static xp_awk_val_t* __eval_pos (xp_awk_run_t* run, xp_awk_nde_t* nde) diff --git a/ase/awk/tree.h b/ase/awk/tree.h index e45c8bf9..7f7064a6 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.69 2006-08-18 17:46:07 bacon Exp $ + * $Id: tree.h,v 1.70 2006-08-20 15:49:06 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -48,7 +48,8 @@ enum XP_AWK_NDE_REX, /* keep this order for the following items otherwise, you may have - * to change __eval_incpre and __eval_incpst in run.c*/ + * to change __eval_incpre and __eval_incpst in run.c as well as + * XP_AWK_VAL_REF_XXX in val.h */ XP_AWK_NDE_NAMED, XP_AWK_NDE_GLOBAL, XP_AWK_NDE_LOCAL, diff --git a/ase/awk/val.c b/ase/awk/val.c index b3056a5e..5e8fbc84 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.50 2006-08-16 11:35:54 bacon Exp $ + * $Id: val.c,v 1.51 2006-08-20 15:49:07 bacon Exp $ */ #include @@ -194,6 +194,20 @@ xp_awk_val_t* xp_awk_makemapval (xp_awk_run_t* run) return (xp_awk_val_t*)val; } +xp_awk_val_t* xp_awk_makerefval (xp_awk_run_t* run, int id, xp_awk_val_t** adr) +{ + xp_awk_val_ref_t* val; + + val = (xp_awk_val_ref_t*) xp_malloc (xp_sizeof(xp_awk_val_ref_t)); + if (val == XP_NULL) return XP_NULL; + + val->type = XP_AWK_VAL_REF; + val->ref = 0; + val->id = id; + val->adr = adr; + + return (xp_awk_val_t*)val; +} xp_bool_t xp_awk_isbuiltinval (xp_awk_val_t* val) { @@ -211,13 +225,12 @@ void xp_awk_freeval (xp_awk_run_t* run, xp_awk_val_t* val, xp_bool_t cache) /*xp_printf (XP_T("freeing [cache=%d] ... "), cache); xp_awk_printval (val); xp_printf (XP_T("\n"));*/ - switch (val->type) + if (val->type == XP_AWK_VAL_NIL) { - case XP_AWK_VAL_NIL: xp_free (val); - return; - - case XP_AWK_VAL_INT: + } + else if (val->type == XP_AWK_VAL_INT) + { if (cache == xp_true && run->icache_count < xp_countof(run->icache)) { @@ -225,9 +238,9 @@ xp_printf (XP_T("\n"));*/ (xp_awk_val_int_t*)val; } else xp_free (val); - return; - - case XP_AWK_VAL_REAL: + } + else if (val->type == XP_AWK_VAL_REAL) + { if (cache == xp_true && run->rcache_count < xp_countof(run->rcache)) { @@ -235,26 +248,31 @@ xp_printf (XP_T("\n"));*/ (xp_awk_val_real_t*)val; } else xp_free (val); - return; - - case XP_AWK_VAL_STR: + } + else if (val->type == XP_AWK_VAL_STR) + { xp_free (((xp_awk_val_str_t*)val)->buf); xp_free (val); - return; - - case XP_AWK_VAL_REX: + } + else if (val->type == XP_AWK_VAL_REX) + { xp_free (((xp_awk_val_rex_t*)val)->buf); xp_awk_freerex (((xp_awk_val_rex_t*)val)->code); xp_free (val); - return; - - case XP_AWK_VAL_MAP: + } + else if (val->type == XP_AWK_VAL_MAP) + { xp_awk_map_close (((xp_awk_val_map_t*)val)->map); xp_free (val); - return; } - - xp_assert (!"should never happen - invalid value type"); + else if (val->type == XP_AWK_VAL_REF) + { + xp_free (val); + } + else + { + xp_assert (!"should never happen - invalid value type"); + } } void xp_awk_refupval (xp_awk_val_t* val) @@ -318,6 +336,8 @@ xp_bool_t xp_awk_valtobool (xp_awk_val_t* val) return ((xp_awk_val_rex_t*)val)->len > 0; case XP_AWK_VAL_MAP: return xp_false; /* TODO: is this correct? */ + case XP_AWK_VAL_REF: + return xp_false; /* TODO: is this correct? */ } xp_assert (!"should never happen - invalid value type"); @@ -623,6 +643,12 @@ void xp_awk_printval (xp_awk_val_t* val) xp_awk_map_walk (((xp_awk_val_map_t*)val)->map, __print_pair, XP_NULL); xp_printf (XP_T("]")); break; + + case XP_AWK_VAL_REF: + xp_printf (XP_T("REF[id=%d,val="), ((xp_awk_val_ref_t*)val)->id); + xp_awk_printval (*((xp_awk_val_ref_t*)val)->adr); + xp_printf (XP_T("]")); + break; default: xp_assert (!"should never happen - invalid value type"); diff --git a/ase/awk/val.h b/ase/awk/val.h index 19bf65f9..d6394e52 100644 --- a/ase/awk/val.h +++ b/ase/awk/val.h @@ -1,5 +1,5 @@ /* - * $Id: val.h,v 1.35 2006-08-03 05:05:48 bacon Exp $ + * $Id: val.h,v 1.36 2006-08-20 15:49:07 bacon Exp $ */ #ifndef _XP_AWK_VAL_H_ @@ -16,7 +16,22 @@ enum XP_AWK_VAL_REAL = 2, XP_AWK_VAL_STR = 3, XP_AWK_VAL_REX = 4, - XP_AWK_VAL_MAP = 5 + XP_AWK_VAL_MAP = 5, + XP_AWK_VAL_REF = 6 +}; + +enum +{ + /* keep these items in the same order as corresponding items + * in tree.h */ + XP_AWK_VAL_REF_NAMED, + XP_AWK_VAL_REF_GLOBAL, + XP_AWK_VAL_REF_LOCAL, + XP_AWK_VAL_REF_ARG, + XP_AWK_VAL_REF_NAMEDIDX, + XP_AWK_VAL_REF_GLOBALIDX, + XP_AWK_VAL_REF_LOCALIDX, + XP_AWK_VAL_REF_ARGIDX }; typedef struct xp_awk_val_nil_t xp_awk_val_nil_t; @@ -25,6 +40,7 @@ typedef struct xp_awk_val_real_t xp_awk_val_real_t; typedef struct xp_awk_val_str_t xp_awk_val_str_t; typedef struct xp_awk_val_rex_t xp_awk_val_rex_t; typedef struct xp_awk_val_map_t xp_awk_val_map_t; +typedef struct xp_awk_val_ref_t xp_awk_val_ref_t; #if XP_SIZEOF_INT == 2 #define XP_AWK_VAL_HDR \ @@ -89,6 +105,15 @@ struct xp_awk_val_map_t xp_awk_map_t* map; }; +/* XP_AWK_VAL_REF */ +struct xp_awk_val_ref_t +{ + XP_AWK_VAL_HDR; + + int id; + xp_awk_val_t** adr; +}; + #ifdef __cplusplus extern "C" { #endif @@ -108,6 +133,8 @@ xp_awk_val_t* xp_awk_makestrval2 ( xp_awk_val_t* xp_awk_makerexval ( const xp_char_t* buf, xp_size_t len, void* code); xp_awk_val_t* xp_awk_makemapval (xp_awk_run_t* run); +xp_awk_val_t* xp_awk_makerefval ( + xp_awk_run_t* run, int id, xp_awk_val_t** adr); xp_bool_t xp_awk_isbuiltinval (xp_awk_val_t* val); diff --git a/ase/test/awk/t28.awk b/ase/test/awk/t28.awk index 17dc38c3..bae8b70c 100644 --- a/ase/test/awk/t28.awk +++ b/ase/test/awk/t28.awk @@ -1,4 +1,8 @@ +//global xyz; + END { + //local xyz; + print index ("abc", "abc"); print index ("abc", "b"); print index ("abc", "kabc"); @@ -22,9 +26,15 @@ END { arr[0] = "xxx"; //print split ("abc def abc", arr); - print split ("abc def abc", 10); - for (i in arr) + print split ("abc def abc", j); + + //xyz = 20; + //print xyz; + print split ("abc def abc", ((xyz))); + //for (i in arr) + + for (i in xyz) { - print i, " ", arr[i]; + print i, " ", xyz[i]; } }