added experimental code to call function held in a variable

This commit is contained in:
hyung-hwan 2019-04-28 15:44:10 +00:00
parent abce018b2f
commit d64d0a73b4
7 changed files with 324 additions and 357 deletions

View File

@ -598,12 +598,27 @@ can't confict with named variables and globals variables.
Built-in Functions
-------------------------
- close
- fflush
- int
- typename
- isnil
- index
- length
- substr
- split
- tolower
- toupper
- gsub
- sub
- match
- sprintf
- mktime
- strftime
- systime
TBD.
Function Calls
-----------------------

View File

@ -369,6 +369,7 @@ enum qse_awk_nde_type_t
QSE_AWK_NDE_CND,
QSE_AWK_NDE_FNC,
QSE_AWK_NDE_FUN,
QSE_AWK_NDE_FCV,
QSE_AWK_NDE_INT,
QSE_AWK_NDE_FLT,
QSE_AWK_NDE_STR,

View File

@ -59,23 +59,23 @@ static qse_awk_fnc_t sysfnctab[] =
/* type info/conversion */
{ {QSE_T("int"), 3}, 0, { {1, 1, QSE_NULL}, fnc_int, 0 }, QSE_NULL},
{ {QSE_T("isnil"), 5}, 0, { {1, 1, QSE_NULL}, fnc_isnil, 0 }, QSE_NULL},
{ {QSE_T("typename"), 8}, 0, { {1, 1, QSE_NULL}, fnc_typename, 0 }, QSE_NULL},
{ {QSE_T("isnil"), 5}, 0, { {1, 1, QSE_NULL}, fnc_isnil, 0 }, QSE_NULL},
/* array sort */
{ {QSE_T("asort"), 5}, 0, { {1, 3, QSE_NULL}, fnc_asort, 0 }, QSE_NULL},
/* string functions */
{ {QSE_T("gsub"), 4}, 0, { {2, 3, QSE_T("xvr")}, qse_awk_fnc_gsub, 0 }, QSE_NULL},
{ {QSE_T("index"), 5}, 0, { {2, 3, QSE_NULL}, qse_awk_fnc_index, 0 }, QSE_NULL},
{ {QSE_T("substr"), 6}, 0, { {2, 3, QSE_NULL}, qse_awk_fnc_substr, 0 }, QSE_NULL},
{ {QSE_T("length"), 6}, 1, { {0, 1, QSE_NULL}, qse_awk_fnc_length, 0 }, QSE_NULL},
{ {QSE_T("match"), 5}, 0, { {2, 4, QSE_T("vxvr")}, qse_awk_fnc_match, 0 }, QSE_NULL},
{ {QSE_T("split"), 5}, 0, { {2, 3, QSE_T("vrx")}, qse_awk_fnc_split, 0 }, QSE_NULL},
{ {QSE_T("sprintf"), 7}, 0, { {1, A_MAX, QSE_NULL}, qse_awk_fnc_sprintf, 0 }, QSE_NULL},
{ {QSE_T("sub"), 3}, 0, { {2, 3, QSE_T("xvr")}, qse_awk_fnc_sub, 0 }, QSE_NULL},
{ {QSE_T("substr"), 6}, 0, { {2, 3, QSE_NULL}, qse_awk_fnc_substr, 0 }, QSE_NULL},
{ {QSE_T("tolower"), 7}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_tolower, 0 }, QSE_NULL},
{ {QSE_T("toupper"), 7}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_toupper, 0 }, QSE_NULL},
{ {QSE_T("gsub"), 4}, 0, { {2, 3, QSE_T("xvr")}, qse_awk_fnc_gsub, 0 }, QSE_NULL},
{ {QSE_T("sub"), 3}, 0, { {2, 3, QSE_T("xvr")}, qse_awk_fnc_sub, 0 }, QSE_NULL},
{ {QSE_T("match"), 5}, 0, { {2, 4, QSE_T("vxvr")}, qse_awk_fnc_match, 0 }, QSE_NULL},
{ {QSE_T("sprintf"), 7}, 0, { {1, A_MAX, QSE_NULL}, qse_awk_fnc_sprintf, 0 }, QSE_NULL},
/* math functions */
{ {QSE_T("sin"), 3}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},

View File

@ -111,6 +111,7 @@ enum tok_t
TOK_COLON,
TOK_DBLCOLON,
TOK_QUEST,
TOK_DBLAT,
/* == begin reserved words == */
/* === extended reserved words === */
@ -219,9 +220,11 @@ static qse_awk_nde_t* parse_unary_exp (qse_awk_t* awk, const qse_awk_loc_t* xloc
static qse_awk_nde_t* parse_increment (qse_awk_t* awk, const qse_awk_loc_t* xloc);
static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc);
static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, const qse_awk_loc_t* xloc);
static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc);
static qse_awk_nde_t* parse_fncall (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg);
#define FNCALL_FLAG_NOARG (1 << 0) /* no argument */
#define FNCALL_FLAG_FCV (1 << 1)
static qse_awk_nde_t* parse_fncall (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int flags);
static qse_awk_nde_t* parse_primary_ident_segs (qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* full, const qse_cstr_t segs[], int nsegs);
@ -568,32 +571,24 @@ static int parse (qse_awk_t* awk)
if (!(awk->opt.trait & QSE_AWK_IMPLICIT))
{
/* ensure that all functions called are defined
* in the EXPLICIT-only mode */
/* ensure that all functions called are defined in the EXPLICIT-only mode.
* o therwise, the error detection will get delay until run-time. */
qse_htb_pair_t* p;
qse_size_t buckno;
p = qse_htb_getfirstpair (awk->parse.funs, &buckno);
p = qse_htb_getfirstpair(awk->parse.funs, &buckno);
while (p != QSE_NULL)
{
if (qse_htb_search (awk->tree.funs,
QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
if (qse_htb_search (awk->tree.funs, QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
{
qse_awk_nde_t* nde;
/* see parse_fncall() for what is
* stored into awk->tree.funs */
nde = (qse_awk_nde_t*)QSE_HTB_VPTR(p);
SETERR_ARG_LOC (
awk,
QSE_AWK_EFUNNF,
QSE_HTB_KPTR(p),
QSE_HTB_KLEN(p),
&nde->loc
);
SETERR_ARG_LOC (awk, QSE_AWK_EFUNNF, QSE_HTB_KPTR(p), QSE_HTB_KLEN(p), &nde->loc);
goto oops;
}
@ -4276,9 +4271,7 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name)
/* check if it is an awk function being processed currently */
if (awk->tree.cur_fun.ptr)
{
if (qse_strxncmp (
awk->tree.cur_fun.ptr, awk->tree.cur_fun.len,
name->ptr, name->len) == 0)
if (qse_strxncmp (awk->tree.cur_fun.ptr, awk->tree.cur_fun.len, name->ptr, name->len) == 0)
{
/* the current function begin parsed */
return FNTYPE_FUN;
@ -4286,14 +4279,14 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name)
}
/* check the funtion name in the function table */
if (qse_htb_search (awk->tree.funs, name->ptr, name->len) != QSE_NULL)
if (qse_htb_search(awk->tree.funs, name->ptr, name->len) != QSE_NULL)
{
/* one of the functions defined previously */
return FNTYPE_FUN;
}
/* check if it is a function not resolved so far */
if (qse_htb_search (awk->parse.funs, name->ptr, name->len) != QSE_NULL)
if (qse_htb_search(awk->parse.funs, name->ptr, name->len) != QSE_NULL)
{
/* one of the function calls not resolved so far. */
return FNTYPE_FUN;
@ -4304,13 +4297,13 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name)
static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_cstr_t* name)
{
if (qse_awk_findfnc (awk, name) != QSE_NULL)
if (qse_awk_findfnc(awk, name) != QSE_NULL)
{
/* implicit function */
return FNTYPE_FNC;
}
return isfunname (awk, name);
return isfunname(awk, name);
}
@ -4680,7 +4673,7 @@ static qse_awk_nde_t* parse_primary_getline (qse_awk_t* awk, const qse_awk_loc_
}
}
if (isfnname (awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
if (isfnname(awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
}
ploc = awk->tok.loc;
@ -4851,7 +4844,7 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
}
}
if (isfnname (awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
if (isfnname(awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
}
ploc = awk->tok.loc;
@ -4894,31 +4887,39 @@ oops:
return QSE_NULL;
}
static qse_awk_nde_t* parse_variable (
qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_awk_nde_type_t type,
const qse_cstr_t* name, qse_size_t idxa)
static qse_awk_nde_t* parse_variable (qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_awk_nde_type_t type, const qse_cstr_t* name, qse_size_t idxa)
{
qse_awk_nde_var_t* nde;
int fcv = 0;
if (!(awk->opt.trait & QSE_AWK_BLANKCONCAT))
/*
if (MATCH(awk,TOK_LPAREN) &&
(!(awk->opt.trait & QSE_AWK_BLANKCONCAT) ||
(awk->tok.loc.line == xloc->line &&
awk->tok.loc.colm == xloc->colm + name->len)))
*/
if (MATCH(awk,TOK_LPAREN))
{
/* if concatenation by blanks is not allowed, the explicit
* concatenation operator(%%) must be used. so it is obvious
* that it is a function call, which is illegal for a variable.
* if implicit, "var_xxx (1)" may be concatenation of
* the value of var_xxx and 1.
*/
if (MATCH(awk,TOK_LPAREN))
if (awk->tok.loc.line == xloc->line && awk->tok.loc.colm == xloc->colm + name->len)
{
fcv = 1;
}
else if (!(awk->opt.trait & QSE_AWK_BLANKCONCAT))
{
/* if concatenation by blanks is not allowed, the explicit
* concatenation operator(%%) must be used. so it is obvious
* that it is a function call, which is illegal for a variable.
* if implicit, "var_xxx (1)" may be concatenation of
* the value of var_xxx and 1.
*/
/* a variable is not a function */
SETERR_ARG_LOC (
awk, QSE_AWK_EFUNNAM,
name->ptr, name->len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EFUNNAM, name->ptr, name->len, xloc);
return QSE_NULL;
}
}
nde = (qse_awk_nde_var_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*nde));
nde = (qse_awk_nde_var_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
if (nde == QSE_NULL)
{
ADJERR_LOC (awk, xloc);
@ -4933,11 +4934,11 @@ static qse_awk_nde_t* parse_variable (
nde->id.idxa = idxa;
nde->idx = QSE_NULL;
return (qse_awk_nde_t*)nde;
if (!fcv) return (qse_awk_nde_t*)nde;
return parse_fncall(awk, (const qse_cstr_t*)nde, QSE_NULL, xloc, FNCALL_FLAG_FCV);
}
static int dup_ident_and_get_next (
qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_cstr_t* name, int max)
static int dup_ident_and_get_next (qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_cstr_t* name, int max)
{
int nsegs = 0;
@ -4990,15 +4991,14 @@ oops:
return -1;
}
static qse_awk_nde_t* parse_primary_ident_noseg (
qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* name)
static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* name)
{
qse_awk_fnc_t* fnc;
qse_size_t idxa;
qse_awk_nde_t* nde = QSE_NULL;
/* check if name is an intrinsic function name */
fnc = qse_awk_findfnc (awk, name);
fnc = qse_awk_findfnc(awk, name);
if (fnc)
{
if (MATCH(awk,TOK_LPAREN) || fnc->dfl0)
@ -5024,40 +5024,39 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
/* fnc->dfl0 means that the function can be called without ().
* i.e. length */
nde = parse_fncall (awk, name, fnc, xloc, ((!MATCH(awk,TOK_LPAREN) && fnc->dfl0)? 1: 0));
nde = parse_fncall(awk, name, fnc, xloc, ((!MATCH(awk,TOK_LPAREN) && fnc->dfl0)? FNCALL_FLAG_NOARG: 0));
}
else
{
/* an intrinsic function should be in the form
* of the function call */
/* an intrinsic function should be in the form of the function call */
SETERR_TOK (awk, QSE_AWK_ELPAREN);
}
}
/* now we know that name is a normal identifier. */
else if (MATCH(awk,TOK_LBRACK))
{
nde = parse_hashidx (awk, name, xloc);
nde = parse_hashidx(awk, name, xloc);
}
else if ((idxa = qse_arr_rsearch (awk->parse.lcls, QSE_ARR_SIZE(awk->parse.lcls), name->ptr, name->len)) != QSE_ARR_NIL)
else if ((idxa = qse_arr_rsearch(awk->parse.lcls, QSE_ARR_SIZE(awk->parse.lcls), name->ptr, name->len)) != QSE_ARR_NIL)
{
/* local variable */
nde = parse_variable (awk, xloc, QSE_AWK_NDE_LCL, name, idxa);
nde = parse_variable(awk, xloc, QSE_AWK_NDE_LCL, name, idxa);
}
else if ((idxa = qse_arr_search (awk->parse.params, 0, name->ptr, name->len)) != QSE_ARR_NIL)
else if ((idxa = qse_arr_search(awk->parse.params, 0, name->ptr, name->len)) != QSE_ARR_NIL)
{
/* parameter */
nde = parse_variable (awk, xloc, QSE_AWK_NDE_ARG, name, idxa);
nde = parse_variable(awk, xloc, QSE_AWK_NDE_ARG, name, idxa);
}
else if ((idxa = get_global (awk, name)) != QSE_ARR_NIL)
else if ((idxa = get_global(awk, name)) != QSE_ARR_NIL)
{
/* global variable */
nde = parse_variable (awk, xloc, QSE_AWK_NDE_GBL, name, idxa);
nde = parse_variable(awk, xloc, QSE_AWK_NDE_GBL, name, idxa);
}
else
{
int fntype;
fntype = isfunname (awk, name);
fntype = isfunname(awk, name);
if (fntype)
{
@ -5066,18 +5065,13 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
if (MATCH(awk,TOK_LPAREN))
{
/* must be a function name */
QSE_ASSERT (qse_htb_search (
awk->parse.named, name->ptr, name->len) == QSE_NULL);
nde = parse_fncall (awk, name, QSE_NULL, xloc, 0);
QSE_ASSERT (qse_htb_search(awk->parse.named, name->ptr, name->len) == QSE_NULL);
nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
}
else
{
/* function name appeared without () */
SETERR_ARG_LOC (
awk, QSE_AWK_EFUNRED,
name->ptr, name->len, xloc
);
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
}
}
else if (awk->opt.trait & QSE_AWK_IMPLICIT)
@ -5098,18 +5092,14 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
{
/* it is a function call to an undefined function yet */
if (qse_htb_search (
awk->parse.named, name->ptr, name->len) != QSE_NULL)
if (qse_htb_search(awk->parse.named, name->ptr, name->len) != QSE_NULL)
{
/* the function call conflicts with a named variable */
SETERR_ARG_LOC (
awk, QSE_AWK_EVARRED,
name->ptr, name->len, xloc
);
SETERR_ARG_LOC (awk, QSE_AWK_EVARRED, name->ptr, name->len, xloc);
}
else
{
nde = parse_fncall (awk, name, QSE_NULL, xloc, 0);
nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
}
}
else
@ -5120,15 +5110,13 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
* while the name is not resolved to anything, we treat the space
* as concatention by blanks. so we handle the name as a named
* variable. */
tmp = (qse_awk_nde_var_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*tmp));
tmp = (qse_awk_nde_var_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*tmp));
if (tmp == QSE_NULL) ADJERR_LOC (awk, xloc);
else
{
/* collect unique instances of a named variable
* for reference */
if (qse_htb_upsert (
awk->parse.named,
name->ptr, name->len, QSE_NULL, 0) == QSE_NULL)
if (qse_htb_upsert (awk->parse.named, name->ptr, name->len, QSE_NULL, 0) == QSE_NULL)
{
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
QSE_AWK_FREE (awk, tmp);
@ -5152,8 +5140,8 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
if (MATCH(awk,TOK_LPAREN))
{
/* it is a function call as the name is followed
* by ( and implicit variables are disabled. */
nde = parse_fncall (awk, name, QSE_NULL, xloc, 0);
* by ( with/without spaces and implicit variables are disabled. */
nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
}
else
{
@ -5166,9 +5154,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
return nde;
}
static qse_awk_nde_t* parse_primary_ident_segs (
qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* full,
const qse_cstr_t segs[], int nsegs)
static qse_awk_nde_t* parse_primary_ident_segs (qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* full, const qse_cstr_t segs[], int nsegs)
{
/* parse xxx::yyy */
@ -5178,7 +5164,7 @@ static qse_awk_nde_t* parse_primary_ident_segs (
qse_awk_fnc_t fnc;
CLRERR (awk);
mod = query_module (awk, segs, nsegs, &sym);
mod = query_module(awk, segs, nsegs, &sym);
if (mod == QSE_NULL)
{
if (ISNOERR(awk)) SETERR_LOC (awk, QSE_AWK_ENOSUP, xloc);
@ -5202,7 +5188,6 @@ static qse_awk_nde_t* parse_primary_ident_segs (
fnc.name.len = full->len;
fnc.spec = sym.u.fnc;
fnc.mod = mod;
nde = parse_fncall (awk, full, &fnc, xloc, 0);
}
else
@ -5288,8 +5273,7 @@ static qse_awk_nde_t* parse_primary_ident (
return nde;
}
static qse_awk_nde_t* parse_hashidx (
qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc)
static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc)
{
qse_awk_nde_t* idx, * tmp, * last;
qse_awk_nde_var_t* nde;
@ -5346,7 +5330,7 @@ static qse_awk_nde_t* parse_hashidx (
return QSE_NULL;
}
nde = (qse_awk_nde_var_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*nde));
nde = (qse_awk_nde_var_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
if (nde == QSE_NULL)
{
qse_awk_clrpt (awk, idx);
@ -5355,11 +5339,7 @@ static qse_awk_nde_t* parse_hashidx (
}
/* search the local variable list */
idxa = qse_arr_rsearch (
awk->parse.lcls,
QSE_ARR_SIZE(awk->parse.lcls),
name->ptr, name->len
);
idxa = qse_arr_rsearch(awk->parse.lcls, QSE_ARR_SIZE(awk->parse.lcls), name->ptr, name->len);
if (idxa != QSE_ARR_NIL)
{
nde->type = QSE_AWK_NDE_LCLIDX;
@ -5374,7 +5354,7 @@ static qse_awk_nde_t* parse_hashidx (
}
/* search the parameter name list */
idxa = qse_arr_search (awk->parse.params, 0, name->ptr, name->len);
idxa = qse_arr_search(awk->parse.params, 0, name->ptr, name->len);
if (idxa != QSE_ARR_NIL)
{
nde->type = QSE_AWK_NDE_ARGIDX;
@ -5405,17 +5385,15 @@ static qse_awk_nde_t* parse_hashidx (
if (awk->opt.trait & QSE_AWK_IMPLICIT)
{
int fnname = isfnname (awk, name);
int fnname = isfnname(awk, name);
switch (fnname)
{
case FNTYPE_FNC:
SETERR_ARG_LOC (
awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
goto exit_func;
case FNTYPE_FUN:
SETERR_ARG_LOC (
awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
goto exit_func;
}
@ -5441,9 +5419,7 @@ exit_func:
return QSE_NULL;
}
static qse_awk_nde_t* parse_fncall (
qse_awk_t* awk, const qse_cstr_t* name,
qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg)
static qse_awk_nde_t* parse_fncall (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int flags)
{
qse_awk_nde_t* head, * curr, * nde;
qse_awk_nde_fncall_t* call;
@ -5454,7 +5430,7 @@ static qse_awk_nde_t* parse_fncall (
call = QSE_NULL;
nargs = 0;
if (noarg) goto make_node;
if (flags & FNCALL_FLAG_NOARG) goto make_node;
if (get_token(awk) <= -1) goto oops;
if (MATCH(awk,TOK_RPAREN))
@ -5465,14 +5441,13 @@ static qse_awk_nde_t* parse_fncall (
else
{
/* parse function parameters */
while (1)
{
eloc = awk->tok.loc;
nde = parse_expr_withdc (awk, &eloc);
if (nde == QSE_NULL) goto oops;
nde = parse_expr_withdc(awk, &eloc);
if (!nde) goto oops;
if (head == QSE_NULL) head = nde;
if (!head) head = nde;
else curr->next = nde;
curr = nde;
@ -5500,14 +5475,22 @@ static qse_awk_nde_t* parse_fncall (
}
make_node:
call = (qse_awk_nde_fncall_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*call));
if (call == QSE_NULL)
call = (qse_awk_nde_fncall_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*call));
if (!call)
{
ADJERR_LOC (awk, xloc);
goto oops;
}
if (fnc)
if (flags & FNCALL_FLAG_FCV)
{
call->type = QSE_AWK_NDE_FCV;
call->loc = *xloc;
call->u.fcv.var = (qse_awk_nde_var_t*)name; /* name is a pointer to a variable node */
call->args = head;
call->nargs = nargs;
}
else if (fnc)
{
call->type = QSE_AWK_NDE_FNC;
call->loc = *xloc;
@ -5540,10 +5523,8 @@ make_node:
call->args = head;
call->nargs = nargs;
/* store a non-builtin function call into the awk->parse.funs
* table */
if (qse_htb_upsert (
awk->parse.funs, name->ptr, name->len, call, 0) == QSE_NULL)
/* store a non-builtin function call into the awk->parse.funs table */
if (!qse_htb_upsert(awk->parse.funs, name->ptr, name->len, call, 0))
{
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
goto oops;
@ -6233,29 +6214,41 @@ retry:
ADD_TOKEN_CHAR (awk, tok, c);
GET_CHAR_TO (awk, c);
if (c != QSE_T('_') && !QSE_AWK_ISALPHA(awk, c))
/*
if (c == QSE_T('@'))
{
SET_TOKEN_TYPE (awk, tok, TOK_DBLAT);
GET_CHAR (awk);
}*/
/* other special extended operators here
else if (c == QSE_T('*'))
{
}*/
/*else*/ if (c != QSE_T('_') && !QSE_AWK_ISALPHA(awk, c))
{
/* this extended keyword is empty,
* not followed by a valid word */
SETERR_LOC (awk, QSE_AWK_EXKWEM, &(awk)->tok.loc);
return -1;
}
/* expect normal identifier starting with an alphabet */
do
else
{
ADD_TOKEN_CHAR (awk, tok, c);
GET_CHAR_TO (awk, c);
}
while (c == QSE_T('_') || QSE_AWK_ISALPHA(awk, c) || QSE_AWK_ISDIGIT(awk, c));
/* expect normal identifier starting with an alphabet */
do
{
ADD_TOKEN_CHAR (awk, tok, c);
GET_CHAR_TO (awk, c);
}
while (c == QSE_T('_') || QSE_AWK_ISALPHA(awk, c) || QSE_AWK_ISDIGIT(awk, c));
type = classify_ident(awk, QSE_STR_XSTR(tok->name));
if (type == TOK_IDENT)
{
SETERR_TOK (awk, QSE_AWK_EXKWNR);
return -1;
type = classify_ident(awk, QSE_STR_XSTR(tok->name));
if (type == TOK_IDENT)
{
SETERR_TOK (awk, QSE_AWK_EXKWNR);
return -1;
}
SET_TOKEN_TYPE (awk, tok, type);
}
SET_TOKEN_TYPE (awk, tok, type);
}
else if (c == QSE_T('B'))
{

View File

@ -230,6 +230,7 @@ static qse_awk_val_t* eval_fun_ex (
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* eval_fcv (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* __eval_call (
qse_awk_rtx_t* run,
@ -252,7 +253,7 @@ static qse_awk_val_t** get_reference_indexed (
qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val);
static qse_awk_val_t* eval_int (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* eval_real (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* eval_flt (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* eval_str (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* eval_mbs (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
@ -3327,8 +3328,9 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
eval_cnd,
eval_fnc,
eval_fun,
eval_fcv,
eval_int,
eval_real,
eval_flt,
eval_str,
eval_mbs,
eval_rex,
@ -3482,8 +3484,7 @@ static qse_awk_val_t* eval_assignment (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
return ret;
}
static qse_awk_val_t* do_assignment (
qse_awk_rtx_t* rtx, qse_awk_nde_t* var, qse_awk_val_t* val)
static qse_awk_val_t* do_assignment (qse_awk_rtx_t* rtx, qse_awk_nde_t* var, qse_awk_val_t* val)
{
qse_awk_val_t* ret;
qse_awk_errnum_t errnum;
@ -3535,8 +3536,7 @@ exit_on_error:
return QSE_NULL;
}
static qse_awk_val_t* do_assignment_nonidx (
qse_awk_rtx_t* run, qse_awk_nde_var_t* var, qse_awk_val_t* val)
static qse_awk_val_t* do_assignment_nonidx (qse_awk_rtx_t* run, qse_awk_nde_var_t* var, qse_awk_val_t* val)
{
qse_awk_val_type_t vtype;
@ -3662,8 +3662,7 @@ static qse_awk_val_t* do_assignment_nonidx (
return val;
}
static qse_awk_val_t* do_assignment_idx (
qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var, qse_awk_val_t* val)
static qse_awk_val_t* do_assignment_idx (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var, qse_awk_val_t* val)
{
qse_awk_val_map_t* map;
qse_awk_val_type_t mvtype;
@ -3814,8 +3813,7 @@ retry:
return val;
}
static qse_awk_val_t* do_assignment_pos (
qse_awk_rtx_t* rtx, qse_awk_nde_pos_t* pos, qse_awk_val_t* val)
static qse_awk_val_t* do_assignment_pos (qse_awk_rtx_t* rtx, qse_awk_nde_pos_t* pos, qse_awk_val_t* val)
{
qse_awk_val_t* v;
qse_awk_val_type_t vtype;
@ -4027,8 +4025,7 @@ static qse_awk_val_t* eval_binop_lor (
return res;
}
static qse_awk_val_t* eval_binop_land (
qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
static qse_awk_val_t* eval_binop_land (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{
/*
qse_awk_val_t* res = QSE_NULL;
@ -4079,8 +4076,7 @@ static qse_awk_val_t* eval_binop_land (
return res;
}
static qse_awk_val_t* eval_binop_in (
qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
static qse_awk_val_t* eval_binop_in (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{
qse_awk_val_t* rv;
qse_awk_val_type_t rvtype;
@ -4710,68 +4706,59 @@ static int teq_val (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* righ
return n;
}
static qse_awk_val_t* eval_binop_teq (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_teq (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
return teq_val (rtx, left, right)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
static qse_awk_val_t* eval_binop_tne (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_tne (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
return teq_val (rtx, left, right)? QSE_AWK_VAL_ZERO: QSE_AWK_VAL_ONE;
}
static qse_awk_val_t* eval_binop_eq (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_eq (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL;
return (n == 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
static qse_awk_val_t* eval_binop_ne (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_ne (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL;
return (n != 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
static qse_awk_val_t* eval_binop_gt (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_gt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL;
return (n > 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
static qse_awk_val_t* eval_binop_ge (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_ge (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL;
return (n >= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
static qse_awk_val_t* eval_binop_lt (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_lt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL;
return (n < 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
static qse_awk_val_t* eval_binop_le (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_le (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL;
return (n <= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
static qse_awk_val_t* eval_binop_lshift (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_lshift (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
qse_awk_int_t l1, l2;
@ -4785,8 +4772,7 @@ static qse_awk_val_t* eval_binop_lshift (
return qse_awk_rtx_makeintval(rtx, l1 << l2);
}
static qse_awk_val_t* eval_binop_rshift (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_rshift (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
qse_awk_int_t l1, l2;
@ -4800,8 +4786,7 @@ static qse_awk_val_t* eval_binop_rshift (
return qse_awk_rtx_makeintval (rtx, l1 >> l2);
}
static qse_awk_val_t* eval_binop_plus (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_plus (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n1, n2, n3;
qse_awk_int_t l1, l2;
@ -4831,8 +4816,7 @@ static qse_awk_val_t* eval_binop_plus (
qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1+(qse_awk_flt_t)r2);
}
static qse_awk_val_t* eval_binop_minus (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_minus (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n1, n2, n3;
qse_awk_int_t l1, l2;
@ -4855,8 +4839,7 @@ static qse_awk_val_t* eval_binop_minus (
qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1-(qse_awk_flt_t)r2);
}
static qse_awk_val_t* eval_binop_mul (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_mul (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n1, n2, n3;
qse_awk_int_t l1, l2;
@ -4879,8 +4862,7 @@ static qse_awk_val_t* eval_binop_mul (
qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1*(qse_awk_flt_t)r2);
}
static qse_awk_val_t* eval_binop_div (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_div (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n1, n2, n3;
qse_awk_int_t l1, l2;
@ -4937,8 +4919,7 @@ static qse_awk_val_t* eval_binop_div (
return res;
}
static qse_awk_val_t* eval_binop_idiv (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_idiv (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n1, n2, n3;
qse_awk_int_t l1, l2;
@ -4986,8 +4967,7 @@ static qse_awk_val_t* eval_binop_idiv (
return res;
}
static qse_awk_val_t* eval_binop_mod (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_mod (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n1, n2, n3;
qse_awk_int_t l1, l2;
@ -5044,8 +5024,7 @@ static qse_awk_val_t* eval_binop_mod (
return res;
}
static qse_awk_val_t* eval_binop_exp (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static qse_awk_val_t* eval_binop_exp (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
int n1, n2, n3;
qse_awk_int_t l1, l2;
@ -5190,8 +5169,7 @@ static qse_awk_val_t* eval_binop_match0 (
return res;
}
static qse_awk_val_t* eval_binop_ma (
qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
static qse_awk_val_t* eval_binop_ma (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{
qse_awk_val_t* lv, * rv, * res;
@ -5220,8 +5198,7 @@ static qse_awk_val_t* eval_binop_ma (
return res;
}
static qse_awk_val_t* eval_binop_nm (
qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
static qse_awk_val_t* eval_binop_nm (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{
qse_awk_val_t* lv, * rv, * res;
@ -5618,12 +5595,8 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
qse_awk_rtx_refupval (run, tv);
QSE_ASSERT (
cnd->left->next == QSE_NULL &&
cnd->right->next == QSE_NULL);
v = (qse_awk_rtx_valtobool (run, tv))?
eval_expression (run, cnd->left):
eval_expression (run, cnd->right);
QSE_ASSERT (cnd->left->next == QSE_NULL && cnd->right->next == QSE_NULL);
v = (qse_awk_rtx_valtobool (run, tv))? eval_expression(run, cnd->left): eval_expression(run, cnd->right);
qse_awk_rtx_refdownval (run, tv);
return v;
@ -5632,34 +5605,23 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{
/* intrinsic function */
qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
/* the parser must make sure taht the number of arguments
* is proper */
QSE_ASSERT (call->nargs >= call->u.fnc.spec.arg.min &&
call->nargs <= call->u.fnc.spec.arg.max);
return eval_call (
run, nde, call->u.fnc.spec.arg.spec,
QSE_NULL, QSE_NULL, QSE_NULL);
QSE_ASSERT (call->nargs >= call->u.fnc.spec.arg.min && call->nargs <= call->u.fnc.spec.arg.max);
return eval_call(run, nde, call->u.fnc.spec.arg.spec, QSE_NULL, QSE_NULL, QSE_NULL);
}
static qse_awk_val_t* eval_fun_ex (
qse_awk_rtx_t* rtx, qse_awk_nde_t* nde,
void(*errhandler)(void*), void* eharg)
static QSE_INLINE qse_awk_val_t* eval_fun_ex (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, void(*errhandler)(void*), void* eharg)
{
qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
qse_awk_fun_t* fun;
qse_htb_pair_t* pair;
pair = qse_htb_search (rtx->awk->tree.funs,
call->u.fun.name.ptr, call->u.fun.name.len);
pair = qse_htb_search(rtx->awk->tree.funs, call->u.fun.name.ptr, call->u.fun.name.len);
if (pair == QSE_NULL)
{
SETERR_ARGX_LOC (
rtx, QSE_AWK_EFUNNF,
&call->u.fun.name, &nde->loc);
SETERR_ARGX_LOC (rtx, QSE_AWK_EFUNNF, &call->u.fun.name, &nde->loc);
return QSE_NULL;
}
@ -5674,18 +5636,42 @@ static qse_awk_val_t* eval_fun_ex (
return QSE_NULL;
}
return eval_call (rtx, nde, QSE_NULL, fun, errhandler, eharg);
return eval_call(rtx, nde, QSE_NULL, fun, errhandler, eharg);
}
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
return eval_fun_ex (run, nde, QSE_NULL, QSE_NULL);
return eval_fun_ex(rtx, nde, QSE_NULL, QSE_NULL);
}
static qse_awk_val_t* eval_fcv (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
qse_awk_val_t* fv, * rv;
fv = eval_expression(rtx, (qse_awk_nde_t*)call->u.fcv.var);
if (!fv) return QSE_NULL;
qse_awk_rtx_refupval (rtx, fv);
if (QSE_AWK_RTX_GETVALTYPE(rtx, fv) != QSE_AWK_VAL_FUN)
{
/*SETERR_ARGX_LOC (rtx, QSE_AWK_EFUNNF, &call->u.fun.name, &nde->loc);*/
/*printf ("NOT FUNCTION VALUE\n");*/
rv = QSE_NULL;
}
else
{
rv = eval_call(rtx, nde, QSE_NULL, ((qse_awk_val_fun_t*)fv)->fun, QSE_NULL, QSE_NULL );
}
qse_awk_rtx_refdownval (rtx, fv);
return rv;
}
/* run->stack_base has not been set for this
* stack frame. so the RTX_STACK_ARG macro cannot be used as in
* qse_awk_rtx_refdownval (run, RTX_STACK_ARG(run,nargs));*/
#define UNWIND_RTX_RTX_STACK_ARG(rtx,nargs) \
#define UNWIND_RTX_STACK_ARG(rtx,nargs) \
do { \
while ((nargs) > 0) \
{ \
@ -5695,7 +5681,7 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
} \
} while (0)
#define UNWIND_RTX_RTX_STACK_BASE(rtx) \
#define UNWIND_RTX_STACK_BASE(rtx) \
do { \
__raw_pop (rtx); /* nargs */ \
__raw_pop (rtx); /* return */ \
@ -5705,8 +5691,8 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
#define UNWIND_RTX_STACK(rtx,nargs) \
do { \
UNWIND_RTX_RTX_STACK_ARG(rtx,nargs); \
UNWIND_RTX_RTX_STACK_BASE(rtx); \
UNWIND_RTX_STACK_ARG(rtx,nargs); \
UNWIND_RTX_STACK_BASE(rtx); \
} while (0)
static qse_awk_val_t* __eval_call (
@ -5810,7 +5796,7 @@ static qse_awk_val_t* __eval_call (
nargs = argpusher (run, call, apdata);
if (nargs == (qse_size_t)-1)
{
UNWIND_RTX_RTX_STACK_BASE (run);
UNWIND_RTX_STACK_BASE (run);
return QSE_NULL;
}
@ -5957,8 +5943,7 @@ static qse_awk_val_t* __eval_call (
return (n == -1)? QSE_NULL: v;
}
static qse_size_t push_arg_from_vals (
qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
static qse_size_t push_arg_from_vals (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
{
struct pafv* pafv = (struct pafv*)data;
qse_size_t nargs = 0;
@ -5975,7 +5960,7 @@ static qse_size_t push_arg_from_vals (
qse_awk_rtx_refupval (rtx, pafv->args[nargs]);
qse_awk_rtx_refdownval (rtx, pafv->args[nargs]);
UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
UNWIND_RTX_STACK_ARG (rtx, nargs);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
return (qse_size_t)-1;
}
@ -5986,8 +5971,7 @@ static qse_size_t push_arg_from_vals (
return nargs;
}
static qse_size_t push_arg_from_nde (
qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
static qse_size_t push_arg_from_nde (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
{
qse_awk_nde_t* p;
qse_awk_val_t* v;
@ -6009,7 +5993,7 @@ static qse_size_t push_arg_from_nde (
if (get_reference (rtx, p, &ref) == -1)
{
UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
UNWIND_RTX_STACK_ARG (rtx, nargs);
return (qse_size_t)-1;
}
@ -6032,7 +6016,7 @@ static qse_size_t push_arg_from_nde (
if (v == QSE_NULL)
{
UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
UNWIND_RTX_STACK_ARG (rtx, nargs);
return (qse_size_t)-1;
}
@ -6046,7 +6030,7 @@ static qse_size_t push_arg_from_nde (
qse_awk_rtx_refupval (rtx, v);
qse_awk_rtx_refdownval (rtx, v);
UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
UNWIND_RTX_STACK_ARG (rtx, nargs);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
return (qse_size_t)-1;
}
@ -6057,19 +6041,12 @@ static qse_size_t push_arg_from_nde (
return nargs;
}
static qse_awk_val_t* eval_call (
qse_awk_rtx_t* rtx, qse_awk_nde_t* nde,
const qse_char_t* fnc_arg_spec, qse_awk_fun_t* fun,
void(*errhandler)(void*), void* eharg)
static qse_awk_val_t* eval_call (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, const qse_char_t* fnc_arg_spec, qse_awk_fun_t* fun, void(*errhandler)(void*), void* eharg)
{
return __eval_call (
rtx, nde, fnc_arg_spec, fun,
push_arg_from_nde, (void*)fnc_arg_spec,
errhandler, eharg);
return __eval_call (rtx, nde, fnc_arg_spec, fun, push_arg_from_nde, (void*)fnc_arg_spec, errhandler, eharg);
}
static int get_reference (
qse_awk_rtx_t* run, qse_awk_nde_t* nde, qse_awk_val_t*** ref)
static int get_reference (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, qse_awk_val_t*** ref)
{
qse_awk_nde_var_t* tgt = (qse_awk_nde_var_t*)nde;
qse_awk_val_t** tmp;
@ -6082,19 +6059,16 @@ static int get_reference (
{
qse_htb_pair_t* pair;
pair = qse_htb_search (
run->named, tgt->id.name.ptr, tgt->id.name.len);
pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
if (pair == QSE_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 = qse_htb_upsert (
run->named, tgt->id.name.ptr,
tgt->id.name.len, qse_awk_val_nil, 0);
pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
if (pair == QSE_NULL)
{
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return -1;
}
}
@ -6104,60 +6078,53 @@ static int get_reference (
}
case QSE_AWK_NDE_GBL:
/* *ref = (qse_awk_val_t**)&RTX_STACK_GBL(run,tgt->id.idxa); */
/* *ref = (qse_awk_val_t**)&RTX_STACK_GBL(rtx,tgt->id.idxa); */
*ref = (qse_awk_val_t**)((qse_size_t)tgt->id.idxa);
return 0;
case QSE_AWK_NDE_LCL:
*ref = (qse_awk_val_t**)&RTX_STACK_LCL(run,tgt->id.idxa);
*ref = (qse_awk_val_t**)&RTX_STACK_LCL(rtx,tgt->id.idxa);
return 0;
case QSE_AWK_NDE_ARG:
*ref = (qse_awk_val_t**)&RTX_STACK_ARG(run,tgt->id.idxa);
*ref = (qse_awk_val_t**)&RTX_STACK_ARG(rtx,tgt->id.idxa);
return 0;
case QSE_AWK_NDE_NAMEDIDX:
{
qse_htb_pair_t* pair;
pair = qse_htb_search (
run->named, tgt->id.name.ptr, tgt->id.name.len);
pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
if (pair == QSE_NULL)
{
pair = qse_htb_upsert (
run->named, tgt->id.name.ptr,
tgt->id.name.len, qse_awk_val_nil, 0);
pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
if (pair == QSE_NULL)
{
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return -1;
}
}
tmp = get_reference_indexed (
run, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
tmp = get_reference_indexed(rtx, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
if (tmp == QSE_NULL) return -1;
*ref = tmp;
return 0;
}
case QSE_AWK_NDE_GBLIDX:
tmp = get_reference_indexed (run, tgt,
(qse_awk_val_t**)&RTX_STACK_GBL(run,tgt->id.idxa));
tmp = get_reference_indexed (rtx, tgt, (qse_awk_val_t**)&RTX_STACK_GBL(rtx,tgt->id.idxa));
if (tmp == QSE_NULL) return -1;
*ref = tmp;
return 0;
case QSE_AWK_NDE_LCLIDX:
tmp = get_reference_indexed (run, tgt,
(qse_awk_val_t**)&RTX_STACK_LCL(run,tgt->id.idxa));
tmp = get_reference_indexed (rtx, tgt, (qse_awk_val_t**)&RTX_STACK_LCL(rtx,tgt->id.idxa));
if (tmp == QSE_NULL) return -1;
*ref = tmp;
return 0;
case QSE_AWK_NDE_ARGIDX:
tmp = get_reference_indexed (run, tgt,
(qse_awk_val_t**)&RTX_STACK_ARG(run,tgt->id.idxa));
tmp = get_reference_indexed(rtx, tgt, (qse_awk_val_t**)&RTX_STACK_ARG(rtx,tgt->id.idxa));
if (tmp == QSE_NULL) return -1;
*ref = tmp;
return 0;
@ -6170,22 +6137,22 @@ static int get_reference (
/* the position number is returned for the positional
* variable unlike other reference types. */
v = eval_expression (run, ((qse_awk_nde_pos_t*)nde)->val);
v = eval_expression(rtx, ((qse_awk_nde_pos_t*)nde)->val);
if (v == QSE_NULL) return -1;
qse_awk_rtx_refupval (run, v);
n = qse_awk_rtx_valtoint (run, v, &lv);
qse_awk_rtx_refdownval (run, v);
qse_awk_rtx_refupval (rtx, v);
n = qse_awk_rtx_valtoint(rtx, v, &lv);
qse_awk_rtx_refdownval (rtx, v);
if (n <= -1)
{
SETERR_LOC (run, QSE_AWK_EPOSIDX, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &nde->loc);
return -1;
}
if (!IS_VALID_POSIDX(lv))
{
SETERR_LOC (run, QSE_AWK_EPOSIDX, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &nde->loc);
return -1;
}
@ -6194,13 +6161,12 @@ static int get_reference (
}
default:
SETERR_LOC (run, QSE_AWK_ENOTREF, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_ENOTREF, &nde->loc);
return -1;
}
}
static qse_awk_val_t** get_reference_indexed (
qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
static qse_awk_val_t** get_reference_indexed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
{
qse_htb_pair_t* pair;
qse_char_t* str;
@ -6210,144 +6176,117 @@ static qse_awk_val_t** get_reference_indexed (
QSE_ASSERT (val != QSE_NULL);
vtype = QSE_AWK_RTX_GETVALTYPE (rtx, *val);
vtype = QSE_AWK_RTX_GETVALTYPE(rtx, *val);
if (vtype == QSE_AWK_VAL_NIL)
{
qse_awk_val_t* tmp;
tmp = qse_awk_rtx_makemapval (run);
tmp = qse_awk_rtx_makemapval (rtx);
if (tmp == QSE_NULL)
{
ADJERR_LOC (run, &nde->loc);
ADJERR_LOC (rtx, &nde->loc);
return QSE_NULL;
}
qse_awk_rtx_refdownval (run, *val);
qse_awk_rtx_refdownval (rtx, *val);
*val = tmp;
qse_awk_rtx_refupval (run, (qse_awk_val_t*)*val);
qse_awk_rtx_refupval (rtx, (qse_awk_val_t*)*val);
}
else if (vtype != QSE_AWK_VAL_MAP)
{
SETERR_LOC (run, QSE_AWK_ENOTMAP, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_ENOTMAP, &nde->loc);
return QSE_NULL;
}
QSE_ASSERT (nde->idx != QSE_NULL);
len = QSE_COUNTOF(idxbuf);
str = idxnde_to_str (run, nde->idx, idxbuf, &len);
str = idxnde_to_str (rtx, nde->idx, idxbuf, &len);
if (str == QSE_NULL) return QSE_NULL;
pair = qse_htb_search ((*(qse_awk_val_map_t**)val)->map, str, len);
pair = qse_htb_search((*(qse_awk_val_map_t**)val)->map, str, len);
if (pair == QSE_NULL)
{
pair = qse_htb_upsert (
(*(qse_awk_val_map_t**)val)->map,
str, len, qse_awk_val_nil, 0);
pair = qse_htb_upsert((*(qse_awk_val_map_t**)val)->map, str, len, qse_awk_val_nil, 0);
if (pair == QSE_NULL)
{
if (str != idxbuf) QSE_AWK_FREE (run->awk, str);
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return QSE_NULL;
}
qse_awk_rtx_refupval (run, QSE_HTB_VPTR(pair));
qse_awk_rtx_refupval (rtx, QSE_HTB_VPTR(pair));
}
if (str != idxbuf) QSE_AWK_FREE (run->awk, str);
if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
return (qse_awk_val_t**)&QSE_HTB_VPTR(pair);
}
static qse_awk_val_t* eval_int (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_int (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_val_t* val;
val = qse_awk_rtx_makeintval (run, ((qse_awk_nde_int_t*)nde)->val);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
val = qse_awk_rtx_makeintval(rtx, ((qse_awk_nde_int_t*)nde)->val);
if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
else if (QSE_AWK_VTR_IS_POINTER(val)) ((qse_awk_val_int_t*)val)->nde = nde;
return val;
}
static qse_awk_val_t* eval_real (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_flt (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_val_t* val;
val = qse_awk_rtx_makefltval (run, ((qse_awk_nde_flt_t*)nde)->val);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
val = qse_awk_rtx_makefltval(rtx, ((qse_awk_nde_flt_t*)nde)->val);
if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
else ((qse_awk_val_flt_t*)val)->nde = nde;
return val;
}
static qse_awk_val_t* eval_str (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_str (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_val_t* val;
val = qse_awk_rtx_makestrval (run,
((qse_awk_nde_str_t*)nde)->ptr,
((qse_awk_nde_str_t*)nde)->len);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
val = qse_awk_rtx_makestrval(rtx, ((qse_awk_nde_str_t*)nde)->ptr, ((qse_awk_nde_str_t*)nde)->len);
if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
return val;
}
static qse_awk_val_t* eval_mbs (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_mbs (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_val_t* val;
val = qse_awk_rtx_makembsval (run,
((qse_awk_nde_mbs_t*)nde)->ptr,
((qse_awk_nde_mbs_t*)nde)->len);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
val = qse_awk_rtx_makembsval(rtx, ((qse_awk_nde_mbs_t*)nde)->ptr, ((qse_awk_nde_mbs_t*)nde)->len);
if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
return val;
}
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_val_t* val;
val = qse_awk_rtx_makerexval (run,
&((qse_awk_nde_rex_t*)nde)->str,
((qse_awk_nde_rex_t*)nde)->code
);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
val = qse_awk_rtx_makerexval(rtx, &((qse_awk_nde_rex_t*)nde)->str, ((qse_awk_nde_rex_t*)nde)->code);
if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
return val;
}
static qse_awk_val_t* eval_named (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_named (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_htb_pair_t* pair;
pair = qse_htb_search (
run->named,
((qse_awk_nde_var_t*)nde)->id.name.ptr,
((qse_awk_nde_var_t*)nde)->id.name.len
);
pair = qse_htb_search (rtx->named, ((qse_awk_nde_var_t*)nde)->id.name.ptr, ((qse_awk_nde_var_t*)nde)->id.name.len);
return (pair == QSE_NULL)? qse_awk_val_nil: QSE_HTB_VPTR(pair);
}
static qse_awk_val_t* eval_gbl (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_gbl (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
return RTX_STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa);
return RTX_STACK_GBL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa);
}
static qse_awk_val_t* eval_lcl (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_lcl (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
return RTX_STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa);
return RTX_STACK_LCL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa);
}
static qse_awk_val_t* eval_arg (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_arg (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
return RTX_STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa);
return RTX_STACK_ARG(rtx,((qse_awk_nde_var_t*)nde)->id.idxa);
}
static qse_awk_val_t* eval_indexed (
qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
static qse_awk_val_t* eval_indexed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
{
qse_htb_pair_t* pair;
qse_char_t* str;
@ -6357,79 +6296,74 @@ static qse_awk_val_t* eval_indexed (
QSE_ASSERT (val != QSE_NULL);
vtype = QSE_AWK_RTX_GETVALTYPE (run, *val);
vtype = QSE_AWK_RTX_GETVALTYPE(rtx, *val);
if (vtype == QSE_AWK_VAL_NIL)
{
qse_awk_val_t* tmp;
tmp = qse_awk_rtx_makemapval (run);
tmp = qse_awk_rtx_makemapval(rtx);
if (tmp == QSE_NULL)
{
ADJERR_LOC (run, &nde->loc);
ADJERR_LOC (rtx, &nde->loc);
return QSE_NULL;
}
qse_awk_rtx_refdownval (run, *val);
qse_awk_rtx_refdownval (rtx, *val);
*val = tmp;
qse_awk_rtx_refupval (run, (qse_awk_val_t*)*val);
qse_awk_rtx_refupval (rtx, (qse_awk_val_t*)*val);
}
else if (vtype != QSE_AWK_VAL_MAP)
{
SETERR_LOC (run, QSE_AWK_ENOTMAP, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_ENOTMAP, &nde->loc);
return QSE_NULL;
}
QSE_ASSERT (nde->idx != QSE_NULL);
len = QSE_COUNTOF(idxbuf);
str = idxnde_to_str (run, nde->idx, idxbuf, &len);
str = idxnde_to_str(rtx, nde->idx, idxbuf, &len);
if (str == QSE_NULL) return QSE_NULL;
pair = qse_htb_search ((*(qse_awk_val_map_t**)val)->map, str, len);
if (str != idxbuf) QSE_AWK_FREE (run->awk, str);
pair = qse_htb_search((*(qse_awk_val_map_t**)val)->map, str, len);
if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
return (pair == QSE_NULL)? qse_awk_val_nil:
(qse_awk_val_t*)QSE_HTB_VPTR(pair);
return (pair == QSE_NULL)? qse_awk_val_nil: (qse_awk_val_t*)QSE_HTB_VPTR(pair);
}
static qse_awk_val_t* eval_namedidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_namedidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_nde_var_t* tgt = (qse_awk_nde_var_t*)nde;
qse_htb_pair_t* pair;
pair = qse_htb_search (run->named, tgt->id.name.ptr, tgt->id.name.len);
pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
if (pair == QSE_NULL)
{
pair = qse_htb_upsert (run->named,
tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
if (pair == QSE_NULL)
{
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return QSE_NULL;
}
qse_awk_rtx_refupval (run, QSE_HTB_VPTR(pair));
qse_awk_rtx_refupval (rtx, QSE_HTB_VPTR(pair));
}
return eval_indexed (run, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
return eval_indexed (rtx, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
}
static qse_awk_val_t* eval_gblidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_gblidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
return eval_indexed (run, (qse_awk_nde_var_t*)nde,
(qse_awk_val_t**)&RTX_STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa));
return eval_indexed(rtx, (qse_awk_nde_var_t*)nde, (qse_awk_val_t**)&RTX_STACK_GBL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa));
}
static qse_awk_val_t* eval_lclidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_lclidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
return eval_indexed (run, (qse_awk_nde_var_t*)nde,
(qse_awk_val_t**)&RTX_STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa));
return eval_indexed(rtx, (qse_awk_nde_var_t*)nde, (qse_awk_val_t**)&RTX_STACK_LCL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa));
}
static qse_awk_val_t* eval_argidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_argidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
return eval_indexed (run, (qse_awk_nde_var_t*)nde,
(qse_awk_val_t**)&RTX_STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa));
return eval_indexed(rtx, (qse_awk_nde_var_t*)nde, (qse_awk_val_t**)&RTX_STACK_ARG(rtx,((qse_awk_nde_var_t*)nde)->id.idxa));
}
static qse_awk_val_t* eval_pos (qse_awk_rtx_t* run, qse_awk_nde_t* nde)

View File

@ -730,6 +730,16 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
break;
}
case QSE_AWK_NDE_FCV:
{
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
PRINT_EXPR (awk, (qse_awk_nde_t*)px->u.fcv.var);
PUT_SRCSTR (awk, QSE_T("("));
PRINT_EXPR_LIST (awk, px->args);
PUT_SRCSTR (awk, QSE_T(")"));
break;
}
case QSE_AWK_NDE_GETLINE:
{
qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)nde;
@ -1443,6 +1453,15 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
break;
}
case QSE_AWK_NDE_FCV:
{
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
qse_awk_clrpt (awk, px->u.fcv.var);
qse_awk_clrpt (awk, px->args);
QSE_AWK_FREE (awk, p);
break;
}
case QSE_AWK_NDE_GETLINE:
{
qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)p;

View File

@ -206,6 +206,11 @@ struct qse_awk_nde_fncall_t
qse_awk_fnc_info_t info;
qse_awk_fnc_spec_t spec;
} fnc;
struct
{
qse_awk_nde_var_t* var;
} fcv;
} u;
qse_awk_nde_t* args;
qse_size_t nargs;