*** empty log message ***

This commit is contained in:
hyung-hwan 2006-08-20 15:49:48 +00:00
parent b0770101b8
commit e590e6130a
8 changed files with 313 additions and 238 deletions

View File

@ -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 */

View File

@ -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 <xp/awk/awk_i.h>
@ -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"),

View File

@ -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 <xp/awk/awk_i.h>
@ -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)

View File

@ -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 <xp/awk/awk_i.h>
@ -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)

View File

@ -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,

View File

@ -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 <xp/awk/awk_i.h>
@ -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");

View File

@ -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);

View File

@ -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];
}
}