*** empty log message ***
This commit is contained in:
parent
b0770101b8
commit
e590e6130a
@ -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 */
|
||||
|
@ -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"),
|
||||
|
132
ase/awk/func.c
132
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 <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)
|
||||
|
259
ase/awk/run.c
259
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 <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)
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user