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 Built-in Functions
------------------------- -------------------------
- close
- fflush
- int
- typename
- isnil
- index - index
- length - length
- substr
- split
- tolower
- toupper
- gsub
- sub
- match
- sprintf
- mktime
- strftime
- systime
TBD. TBD.
Function Calls Function Calls
----------------------- -----------------------

View File

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

View File

@ -59,23 +59,23 @@ static qse_awk_fnc_t sysfnctab[] =
/* type info/conversion */ /* type info/conversion */
{ {QSE_T("int"), 3}, 0, { {1, 1, QSE_NULL}, fnc_int, 0 }, QSE_NULL}, { {QSE_T("int"), 3}, 0, { {1, 1, QSE_NULL}, fnc_int, 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}, { {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},
/* array sort */ /* array sort */
{ {QSE_T("asort"), 5}, 0, { {1, 3, QSE_NULL}, fnc_asort, 0 }, QSE_NULL}, { {QSE_T("asort"), 5}, 0, { {1, 3, QSE_NULL}, fnc_asort, 0 }, QSE_NULL},
/* string functions */ /* 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("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("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("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("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("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 */ /* math functions */
{ {QSE_T("sin"), 3}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL}, { {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_COLON,
TOK_DBLCOLON, TOK_DBLCOLON,
TOK_QUEST, TOK_QUEST,
TOK_DBLAT,
/* == begin reserved words == */ /* == begin reserved words == */
/* === extended 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_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 (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_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_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); 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)) if (!(awk->opt.trait & QSE_AWK_IMPLICIT))
{ {
/* ensure that all functions called are defined /* ensure that all functions called are defined in the EXPLICIT-only mode.
* in the EXPLICIT-only mode */ * o therwise, the error detection will get delay until run-time. */
qse_htb_pair_t* p; qse_htb_pair_t* p;
qse_size_t buckno; qse_size_t buckno;
p = qse_htb_getfirstpair (awk->parse.funs, &buckno); p = qse_htb_getfirstpair(awk->parse.funs, &buckno);
while (p != QSE_NULL) while (p != QSE_NULL)
{ {
if (qse_htb_search (awk->tree.funs, if (qse_htb_search (awk->tree.funs, QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
{ {
qse_awk_nde_t* nde; qse_awk_nde_t* nde;
/* see parse_fncall() for what is /* see parse_fncall() for what is
* stored into awk->tree.funs */ * stored into awk->tree.funs */
nde = (qse_awk_nde_t*)QSE_HTB_VPTR(p); nde = (qse_awk_nde_t*)QSE_HTB_VPTR(p);
SETERR_ARG_LOC ( SETERR_ARG_LOC (awk, QSE_AWK_EFUNNF, QSE_HTB_KPTR(p), QSE_HTB_KLEN(p), &nde->loc);
awk,
QSE_AWK_EFUNNF,
QSE_HTB_KPTR(p),
QSE_HTB_KLEN(p),
&nde->loc
);
goto oops; 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 */ /* check if it is an awk function being processed currently */
if (awk->tree.cur_fun.ptr) if (awk->tree.cur_fun.ptr)
{ {
if (qse_strxncmp ( if (qse_strxncmp (awk->tree.cur_fun.ptr, awk->tree.cur_fun.len, name->ptr, name->len) == 0)
awk->tree.cur_fun.ptr, awk->tree.cur_fun.len,
name->ptr, name->len) == 0)
{ {
/* the current function begin parsed */ /* the current function begin parsed */
return FNTYPE_FUN; 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 */ /* 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 */ /* one of the functions defined previously */
return FNTYPE_FUN; return FNTYPE_FUN;
} }
/* check if it is a function not resolved so far */ /* 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. */ /* one of the function calls not resolved so far. */
return FNTYPE_FUN; 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) 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 */ /* implicit function */
return FNTYPE_FNC; 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; 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; ploc = awk->tok.loc;
@ -4894,13 +4887,25 @@ oops:
return QSE_NULL; return QSE_NULL;
} }
static qse_awk_nde_t* parse_variable ( 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_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; 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 (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 /* if concatenation by blanks is not allowed, the explicit
* concatenation operator(%%) must be used. so it is obvious * concatenation operator(%%) must be used. so it is obvious
@ -4908,17 +4913,13 @@ static qse_awk_nde_t* parse_variable (
* if implicit, "var_xxx (1)" may be concatenation of * if implicit, "var_xxx (1)" may be concatenation of
* the value of var_xxx and 1. * the value of var_xxx and 1.
*/ */
if (MATCH(awk,TOK_LPAREN))
{
/* a variable is not a function */ /* a variable is not a function */
SETERR_ARG_LOC ( SETERR_ARG_LOC (awk, QSE_AWK_EFUNNAM, name->ptr, name->len, xloc);
awk, QSE_AWK_EFUNNAM,
name->ptr, name->len, xloc);
return QSE_NULL; 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) if (nde == QSE_NULL)
{ {
ADJERR_LOC (awk, xloc); ADJERR_LOC (awk, xloc);
@ -4933,11 +4934,11 @@ static qse_awk_nde_t* parse_variable (
nde->id.idxa = idxa; nde->id.idxa = idxa;
nde->idx = QSE_NULL; 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 ( static int dup_ident_and_get_next (qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_cstr_t* name, int max)
qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_cstr_t* name, int max)
{ {
int nsegs = 0; int nsegs = 0;
@ -4990,15 +4991,14 @@ oops:
return -1; return -1;
} }
static qse_awk_nde_t* parse_primary_ident_noseg ( 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_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* name)
{ {
qse_awk_fnc_t* fnc; qse_awk_fnc_t* fnc;
qse_size_t idxa; qse_size_t idxa;
qse_awk_nde_t* nde = QSE_NULL; qse_awk_nde_t* nde = QSE_NULL;
/* check if name is an intrinsic function name */ /* check if name is an intrinsic function name */
fnc = qse_awk_findfnc (awk, name); fnc = qse_awk_findfnc(awk, name);
if (fnc) if (fnc)
{ {
if (MATCH(awk,TOK_LPAREN) || fnc->dfl0) 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 (). /* fnc->dfl0 means that the function can be called without ().
* i.e. length */ * 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 else
{ {
/* an intrinsic function should be in the form /* an intrinsic function should be in the form of the function call */
* of the function call */
SETERR_TOK (awk, QSE_AWK_ELPAREN); SETERR_TOK (awk, QSE_AWK_ELPAREN);
} }
} }
/* now we know that name is a normal identifier. */ /* now we know that name is a normal identifier. */
else if (MATCH(awk,TOK_LBRACK)) 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 */ /* 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 */ /* 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 */ /* 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 else
{ {
int fntype; int fntype;
fntype = isfunname (awk, name); fntype = isfunname(awk, name);
if (fntype) if (fntype)
{ {
@ -5066,18 +5065,13 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
if (MATCH(awk,TOK_LPAREN)) if (MATCH(awk,TOK_LPAREN))
{ {
/* must be a function name */ /* must be a function name */
QSE_ASSERT (qse_htb_search ( QSE_ASSERT (qse_htb_search(awk->parse.named, name->ptr, name->len) == QSE_NULL);
awk->parse.named, name->ptr, name->len) == QSE_NULL); nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
nde = parse_fncall (awk, name, QSE_NULL, xloc, 0);
} }
else else
{ {
/* function name appeared without () */ /* function name appeared without () */
SETERR_ARG_LOC ( SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
awk, QSE_AWK_EFUNRED,
name->ptr, name->len, xloc
);
} }
} }
else if (awk->opt.trait & QSE_AWK_IMPLICIT) 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 */ /* it is a function call to an undefined function yet */
if (qse_htb_search ( if (qse_htb_search(awk->parse.named, name->ptr, name->len) != QSE_NULL)
awk->parse.named, name->ptr, name->len) != QSE_NULL)
{ {
/* the function call conflicts with a named variable */ /* the function call conflicts with a named variable */
SETERR_ARG_LOC ( SETERR_ARG_LOC (awk, QSE_AWK_EVARRED, name->ptr, name->len, xloc);
awk, QSE_AWK_EVARRED,
name->ptr, name->len, xloc
);
} }
else else
{ {
nde = parse_fncall (awk, name, QSE_NULL, xloc, 0); nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
} }
} }
else 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 * while the name is not resolved to anything, we treat the space
* as concatention by blanks. so we handle the name as a named * as concatention by blanks. so we handle the name as a named
* variable. */ * 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); if (tmp == QSE_NULL) ADJERR_LOC (awk, xloc);
else else
{ {
/* collect unique instances of a named variable /* collect unique instances of a named variable
* for reference */ * for reference */
if (qse_htb_upsert ( if (qse_htb_upsert (awk->parse.named, name->ptr, name->len, QSE_NULL, 0) == QSE_NULL)
awk->parse.named,
name->ptr, name->len, QSE_NULL, 0) == QSE_NULL)
{ {
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
QSE_AWK_FREE (awk, tmp); QSE_AWK_FREE (awk, tmp);
@ -5152,8 +5140,8 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
if (MATCH(awk,TOK_LPAREN)) if (MATCH(awk,TOK_LPAREN))
{ {
/* it is a function call as the name is followed /* it is a function call as the name is followed
* by ( and implicit variables are disabled. */ * by ( with/without spaces and implicit variables are disabled. */
nde = parse_fncall (awk, name, QSE_NULL, xloc, 0); nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
} }
else else
{ {
@ -5166,9 +5154,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
return nde; return nde;
} }
static qse_awk_nde_t* parse_primary_ident_segs ( 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)
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 */ /* parse xxx::yyy */
@ -5178,7 +5164,7 @@ static qse_awk_nde_t* parse_primary_ident_segs (
qse_awk_fnc_t fnc; qse_awk_fnc_t fnc;
CLRERR (awk); CLRERR (awk);
mod = query_module (awk, segs, nsegs, &sym); mod = query_module(awk, segs, nsegs, &sym);
if (mod == QSE_NULL) if (mod == QSE_NULL)
{ {
if (ISNOERR(awk)) SETERR_LOC (awk, QSE_AWK_ENOSUP, xloc); 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.name.len = full->len;
fnc.spec = sym.u.fnc; fnc.spec = sym.u.fnc;
fnc.mod = mod; fnc.mod = mod;
nde = parse_fncall (awk, full, &fnc, xloc, 0); nde = parse_fncall (awk, full, &fnc, xloc, 0);
} }
else else
@ -5288,8 +5273,7 @@ static qse_awk_nde_t* parse_primary_ident (
return nde; return nde;
} }
static qse_awk_nde_t* parse_hashidx ( static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc)
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_t* idx, * tmp, * last;
qse_awk_nde_var_t* nde; qse_awk_nde_var_t* nde;
@ -5346,7 +5330,7 @@ static qse_awk_nde_t* parse_hashidx (
return QSE_NULL; 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) if (nde == QSE_NULL)
{ {
qse_awk_clrpt (awk, idx); qse_awk_clrpt (awk, idx);
@ -5355,11 +5339,7 @@ static qse_awk_nde_t* parse_hashidx (
} }
/* search the local variable list */ /* search the local variable list */
idxa = qse_arr_rsearch ( idxa = qse_arr_rsearch(awk->parse.lcls, QSE_ARR_SIZE(awk->parse.lcls), name->ptr, name->len);
awk->parse.lcls,
QSE_ARR_SIZE(awk->parse.lcls),
name->ptr, name->len
);
if (idxa != QSE_ARR_NIL) if (idxa != QSE_ARR_NIL)
{ {
nde->type = QSE_AWK_NDE_LCLIDX; nde->type = QSE_AWK_NDE_LCLIDX;
@ -5374,7 +5354,7 @@ static qse_awk_nde_t* parse_hashidx (
} }
/* search the parameter name list */ /* 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) if (idxa != QSE_ARR_NIL)
{ {
nde->type = QSE_AWK_NDE_ARGIDX; nde->type = QSE_AWK_NDE_ARGIDX;
@ -5405,17 +5385,15 @@ static qse_awk_nde_t* parse_hashidx (
if (awk->opt.trait & QSE_AWK_IMPLICIT) if (awk->opt.trait & QSE_AWK_IMPLICIT)
{ {
int fnname = isfnname (awk, name); int fnname = isfnname(awk, name);
switch (fnname) switch (fnname)
{ {
case FNTYPE_FNC: case FNTYPE_FNC:
SETERR_ARG_LOC ( SETERR_ARG_LOC (awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
goto exit_func; goto exit_func;
case FNTYPE_FUN: case FNTYPE_FUN:
SETERR_ARG_LOC ( SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
goto exit_func; goto exit_func;
} }
@ -5441,9 +5419,7 @@ exit_func:
return QSE_NULL; return QSE_NULL;
} }
static qse_awk_nde_t* parse_fncall ( 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_t* awk, const qse_cstr_t* name,
qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg)
{ {
qse_awk_nde_t* head, * curr, * nde; qse_awk_nde_t* head, * curr, * nde;
qse_awk_nde_fncall_t* call; qse_awk_nde_fncall_t* call;
@ -5454,7 +5430,7 @@ static qse_awk_nde_t* parse_fncall (
call = QSE_NULL; call = QSE_NULL;
nargs = 0; nargs = 0;
if (noarg) goto make_node; if (flags & FNCALL_FLAG_NOARG) goto make_node;
if (get_token(awk) <= -1) goto oops; if (get_token(awk) <= -1) goto oops;
if (MATCH(awk,TOK_RPAREN)) if (MATCH(awk,TOK_RPAREN))
@ -5465,14 +5441,13 @@ static qse_awk_nde_t* parse_fncall (
else else
{ {
/* parse function parameters */ /* parse function parameters */
while (1) while (1)
{ {
eloc = awk->tok.loc; eloc = awk->tok.loc;
nde = parse_expr_withdc (awk, &eloc); nde = parse_expr_withdc(awk, &eloc);
if (nde == QSE_NULL) goto oops; if (!nde) goto oops;
if (head == QSE_NULL) head = nde; if (!head) head = nde;
else curr->next = nde; else curr->next = nde;
curr = nde; curr = nde;
@ -5500,14 +5475,22 @@ static qse_awk_nde_t* parse_fncall (
} }
make_node: make_node:
call = (qse_awk_nde_fncall_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*call)); call = (qse_awk_nde_fncall_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*call));
if (call == QSE_NULL) if (!call)
{ {
ADJERR_LOC (awk, xloc); ADJERR_LOC (awk, xloc);
goto oops; 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->type = QSE_AWK_NDE_FNC;
call->loc = *xloc; call->loc = *xloc;
@ -5540,10 +5523,8 @@ make_node:
call->args = head; call->args = head;
call->nargs = nargs; call->nargs = nargs;
/* store a non-builtin function call into the awk->parse.funs /* store a non-builtin function call into the awk->parse.funs table */
* table */ if (!qse_htb_upsert(awk->parse.funs, name->ptr, name->len, call, 0))
if (qse_htb_upsert (
awk->parse.funs, name->ptr, name->len, call, 0) == QSE_NULL)
{ {
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
goto oops; goto oops;
@ -6233,14 +6214,25 @@ retry:
ADD_TOKEN_CHAR (awk, tok, c); ADD_TOKEN_CHAR (awk, tok, c);
GET_CHAR_TO (awk, 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, /* this extended keyword is empty,
* not followed by a valid word */ * not followed by a valid word */
SETERR_LOC (awk, QSE_AWK_EXKWEM, &(awk)->tok.loc); SETERR_LOC (awk, QSE_AWK_EXKWEM, &(awk)->tok.loc);
return -1; return -1;
} }
else
{
/* expect normal identifier starting with an alphabet */ /* expect normal identifier starting with an alphabet */
do do
{ {
@ -6257,6 +6249,7 @@ retry:
} }
SET_TOKEN_TYPE (awk, tok, type); SET_TOKEN_TYPE (awk, tok, type);
} }
}
else if (c == QSE_T('B')) else if (c == QSE_T('B'))
{ {
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);

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_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_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 ( static qse_awk_val_t* __eval_call (
qse_awk_rtx_t* run, 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); 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_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_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_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); 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_cnd,
eval_fnc, eval_fnc,
eval_fun, eval_fun,
eval_fcv,
eval_int, eval_int,
eval_real, eval_flt,
eval_str, eval_str,
eval_mbs, eval_mbs,
eval_rex, 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; return ret;
} }
static qse_awk_val_t* do_assignment ( static qse_awk_val_t* do_assignment (qse_awk_rtx_t* rtx, qse_awk_nde_t* var, qse_awk_val_t* val)
qse_awk_rtx_t* rtx, qse_awk_nde_t* var, qse_awk_val_t* val)
{ {
qse_awk_val_t* ret; qse_awk_val_t* ret;
qse_awk_errnum_t errnum; qse_awk_errnum_t errnum;
@ -3535,8 +3536,7 @@ exit_on_error:
return QSE_NULL; return QSE_NULL;
} }
static qse_awk_val_t* do_assignment_nonidx ( 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_rtx_t* run, qse_awk_nde_var_t* var, qse_awk_val_t* val)
{ {
qse_awk_val_type_t vtype; qse_awk_val_type_t vtype;
@ -3662,8 +3662,7 @@ static qse_awk_val_t* do_assignment_nonidx (
return val; return val;
} }
static qse_awk_val_t* do_assignment_idx ( 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_rtx_t* rtx, qse_awk_nde_var_t* var, qse_awk_val_t* val)
{ {
qse_awk_val_map_t* map; qse_awk_val_map_t* map;
qse_awk_val_type_t mvtype; qse_awk_val_type_t mvtype;
@ -3814,8 +3813,7 @@ retry:
return val; return val;
} }
static qse_awk_val_t* do_assignment_pos ( 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_rtx_t* rtx, qse_awk_nde_pos_t* pos, qse_awk_val_t* val)
{ {
qse_awk_val_t* v; qse_awk_val_t* v;
qse_awk_val_type_t vtype; qse_awk_val_type_t vtype;
@ -4027,8 +4025,7 @@ static qse_awk_val_t* eval_binop_lor (
return res; return res;
} }
static qse_awk_val_t* eval_binop_land ( 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_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{ {
/* /*
qse_awk_val_t* res = QSE_NULL; qse_awk_val_t* res = QSE_NULL;
@ -4079,8 +4076,7 @@ static qse_awk_val_t* eval_binop_land (
return res; return res;
} }
static qse_awk_val_t* eval_binop_in ( 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_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{ {
qse_awk_val_t* rv; qse_awk_val_t* rv;
qse_awk_val_type_t rvtype; 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; return n;
} }
static qse_awk_val_t* eval_binop_teq ( static qse_awk_val_t* eval_binop_teq (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
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; return teq_val (rtx, left, right)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
} }
static qse_awk_val_t* eval_binop_tne ( static qse_awk_val_t* eval_binop_tne (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
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; return teq_val (rtx, left, right)? QSE_AWK_VAL_ZERO: QSE_AWK_VAL_ONE;
} }
static qse_awk_val_t* eval_binop_eq ( static qse_awk_val_t* eval_binop_eq (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n = __cmp_val(rtx, left, right); int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL; if (n == CMP_ERROR) return QSE_NULL;
return (n == 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO; return (n == 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
} }
static qse_awk_val_t* eval_binop_ne ( static qse_awk_val_t* eval_binop_ne (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n = __cmp_val(rtx, left, right); int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL; if (n == CMP_ERROR) return QSE_NULL;
return (n != 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO; return (n != 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
} }
static qse_awk_val_t* eval_binop_gt ( static qse_awk_val_t* eval_binop_gt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n = __cmp_val(rtx, left, right); int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL; if (n == CMP_ERROR) return QSE_NULL;
return (n > 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO; return (n > 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
} }
static qse_awk_val_t* eval_binop_ge ( static qse_awk_val_t* eval_binop_ge (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n = __cmp_val(rtx, left, right); int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL; if (n == CMP_ERROR) return QSE_NULL;
return (n >= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO; return (n >= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
} }
static qse_awk_val_t* eval_binop_lt ( static qse_awk_val_t* eval_binop_lt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n = __cmp_val(rtx, left, right); int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL; if (n == CMP_ERROR) return QSE_NULL;
return (n < 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO; return (n < 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
} }
static qse_awk_val_t* eval_binop_le ( static qse_awk_val_t* eval_binop_le (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n = __cmp_val(rtx, left, right); int n = __cmp_val(rtx, left, right);
if (n == CMP_ERROR) return QSE_NULL; if (n == CMP_ERROR) return QSE_NULL;
return (n <= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO; return (n <= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
} }
static qse_awk_val_t* eval_binop_lshift ( 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_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
qse_awk_int_t l1, l2; 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); return qse_awk_rtx_makeintval(rtx, l1 << l2);
} }
static qse_awk_val_t* eval_binop_rshift ( 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_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
qse_awk_int_t l1, l2; 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); return qse_awk_rtx_makeintval (rtx, l1 >> l2);
} }
static qse_awk_val_t* eval_binop_plus ( static qse_awk_val_t* eval_binop_plus (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n1, n2, n3; int n1, n2, n3;
qse_awk_int_t l1, l2; 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); qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1+(qse_awk_flt_t)r2);
} }
static qse_awk_val_t* eval_binop_minus ( static qse_awk_val_t* eval_binop_minus (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n1, n2, n3; int n1, n2, n3;
qse_awk_int_t l1, l2; 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); qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1-(qse_awk_flt_t)r2);
} }
static qse_awk_val_t* eval_binop_mul ( static qse_awk_val_t* eval_binop_mul (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n1, n2, n3; int n1, n2, n3;
qse_awk_int_t l1, l2; 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); qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1*(qse_awk_flt_t)r2);
} }
static qse_awk_val_t* eval_binop_div ( static qse_awk_val_t* eval_binop_div (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n1, n2, n3; int n1, n2, n3;
qse_awk_int_t l1, l2; qse_awk_int_t l1, l2;
@ -4937,8 +4919,7 @@ static qse_awk_val_t* eval_binop_div (
return res; return res;
} }
static qse_awk_val_t* eval_binop_idiv ( static qse_awk_val_t* eval_binop_idiv (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n1, n2, n3; int n1, n2, n3;
qse_awk_int_t l1, l2; qse_awk_int_t l1, l2;
@ -4986,8 +4967,7 @@ static qse_awk_val_t* eval_binop_idiv (
return res; return res;
} }
static qse_awk_val_t* eval_binop_mod ( static qse_awk_val_t* eval_binop_mod (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n1, n2, n3; int n1, n2, n3;
qse_awk_int_t l1, l2; qse_awk_int_t l1, l2;
@ -5044,8 +5024,7 @@ static qse_awk_val_t* eval_binop_mod (
return res; return res;
} }
static qse_awk_val_t* eval_binop_exp ( static qse_awk_val_t* eval_binop_exp (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{ {
int n1, n2, n3; int n1, n2, n3;
qse_awk_int_t l1, l2; qse_awk_int_t l1, l2;
@ -5190,8 +5169,7 @@ static qse_awk_val_t* eval_binop_match0 (
return res; return res;
} }
static qse_awk_val_t* eval_binop_ma ( 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_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{ {
qse_awk_val_t* lv, * rv, * res; qse_awk_val_t* lv, * rv, * res;
@ -5220,8 +5198,7 @@ static qse_awk_val_t* eval_binop_ma (
return res; return res;
} }
static qse_awk_val_t* eval_binop_nm ( 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_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
{ {
qse_awk_val_t* lv, * rv, * res; 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_awk_rtx_refupval (run, tv);
QSE_ASSERT ( QSE_ASSERT (cnd->left->next == QSE_NULL && cnd->right->next == QSE_NULL);
cnd->left->next == QSE_NULL && v = (qse_awk_rtx_valtobool (run, tv))? eval_expression(run, cnd->left): eval_expression(run, cnd->right);
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); qse_awk_rtx_refdownval (run, tv);
return v; 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) static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
/* intrinsic function */ /* intrinsic function */
qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde; qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
/* the parser must make sure taht the number of arguments /* the parser must make sure taht the number of arguments
* is proper */ * is proper */
QSE_ASSERT (call->nargs >= call->u.fnc.spec.arg.min && QSE_ASSERT (call->nargs >= call->u.fnc.spec.arg.min && call->nargs <= call->u.fnc.spec.arg.max);
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);
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 ( 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_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_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
qse_awk_fun_t* fun; qse_awk_fun_t* fun;
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
pair = qse_htb_search (rtx->awk->tree.funs, pair = qse_htb_search(rtx->awk->tree.funs, call->u.fun.name.ptr, call->u.fun.name.len);
call->u.fun.name.ptr, call->u.fun.name.len);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
SETERR_ARGX_LOC ( SETERR_ARGX_LOC (rtx, QSE_AWK_EFUNNF, &call->u.fun.name, &nde->loc);
rtx, QSE_AWK_EFUNNF,
&call->u.fun.name, &nde->loc);
return QSE_NULL; return QSE_NULL;
} }
@ -5674,18 +5636,42 @@ static qse_awk_val_t* eval_fun_ex (
return QSE_NULL; 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 /* run->stack_base has not been set for this
* stack frame. so the RTX_STACK_ARG macro cannot be used as in * stack frame. so the RTX_STACK_ARG macro cannot be used as in
* qse_awk_rtx_refdownval (run, RTX_STACK_ARG(run,nargs));*/ * 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 { \ do { \
while ((nargs) > 0) \ 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) } while (0)
#define UNWIND_RTX_RTX_STACK_BASE(rtx) \ #define UNWIND_RTX_STACK_BASE(rtx) \
do { \ do { \
__raw_pop (rtx); /* nargs */ \ __raw_pop (rtx); /* nargs */ \
__raw_pop (rtx); /* return */ \ __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) \ #define UNWIND_RTX_STACK(rtx,nargs) \
do { \ do { \
UNWIND_RTX_RTX_STACK_ARG(rtx,nargs); \ UNWIND_RTX_STACK_ARG(rtx,nargs); \
UNWIND_RTX_RTX_STACK_BASE(rtx); \ UNWIND_RTX_STACK_BASE(rtx); \
} while (0) } while (0)
static qse_awk_val_t* __eval_call ( static qse_awk_val_t* __eval_call (
@ -5810,7 +5796,7 @@ static qse_awk_val_t* __eval_call (
nargs = argpusher (run, call, apdata); nargs = argpusher (run, call, apdata);
if (nargs == (qse_size_t)-1) if (nargs == (qse_size_t)-1)
{ {
UNWIND_RTX_RTX_STACK_BASE (run); UNWIND_RTX_STACK_BASE (run);
return QSE_NULL; return QSE_NULL;
} }
@ -5957,8 +5943,7 @@ static qse_awk_val_t* __eval_call (
return (n == -1)? QSE_NULL: v; return (n == -1)? QSE_NULL: v;
} }
static qse_size_t push_arg_from_vals ( static qse_size_t push_arg_from_vals (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
{ {
struct pafv* pafv = (struct pafv*)data; struct pafv* pafv = (struct pafv*)data;
qse_size_t nargs = 0; 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_refupval (rtx, pafv->args[nargs]);
qse_awk_rtx_refdownval (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); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
return (qse_size_t)-1; return (qse_size_t)-1;
} }
@ -5986,8 +5971,7 @@ static qse_size_t push_arg_from_vals (
return nargs; return nargs;
} }
static qse_size_t push_arg_from_nde ( static qse_size_t push_arg_from_nde (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
{ {
qse_awk_nde_t* p; qse_awk_nde_t* p;
qse_awk_val_t* v; qse_awk_val_t* v;
@ -6009,7 +5993,7 @@ static qse_size_t push_arg_from_nde (
if (get_reference (rtx, p, &ref) == -1) 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; return (qse_size_t)-1;
} }
@ -6032,7 +6016,7 @@ static qse_size_t push_arg_from_nde (
if (v == QSE_NULL) if (v == QSE_NULL)
{ {
UNWIND_RTX_RTX_STACK_ARG (rtx, nargs); UNWIND_RTX_STACK_ARG (rtx, nargs);
return (qse_size_t)-1; 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_refupval (rtx, v);
qse_awk_rtx_refdownval (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); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
return (qse_size_t)-1; return (qse_size_t)-1;
} }
@ -6057,19 +6041,12 @@ static qse_size_t push_arg_from_nde (
return nargs; return nargs;
} }
static qse_awk_val_t* eval_call ( 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)
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 ( return __eval_call (rtx, nde, fnc_arg_spec, fun, push_arg_from_nde, (void*)fnc_arg_spec, errhandler, eharg);
rtx, nde, fnc_arg_spec, fun,
push_arg_from_nde, (void*)fnc_arg_spec,
errhandler, eharg);
} }
static int get_reference ( static int get_reference (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, qse_awk_val_t*** ref)
qse_awk_rtx_t* run, qse_awk_nde_t* nde, qse_awk_val_t*** ref)
{ {
qse_awk_nde_var_t* tgt = (qse_awk_nde_var_t*)nde; qse_awk_nde_var_t* tgt = (qse_awk_nde_var_t*)nde;
qse_awk_val_t** tmp; qse_awk_val_t** tmp;
@ -6082,19 +6059,16 @@ static int get_reference (
{ {
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
pair = qse_htb_search ( pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
run->named, tgt->id.name.ptr, tgt->id.name.len);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
/* it is bad that the named variable has to be /* it is bad that the named variable has to be
* created in the function named "__get_refernce". * created in the function named "__get_refernce".
* would there be any better ways to avoid this? */ * would there be any better ways to avoid this? */
pair = qse_htb_upsert ( pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
run->named, tgt->id.name.ptr,
tgt->id.name.len, qse_awk_val_nil, 0);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return -1; return -1;
} }
} }
@ -6104,60 +6078,53 @@ static int get_reference (
} }
case QSE_AWK_NDE_GBL: 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); *ref = (qse_awk_val_t**)((qse_size_t)tgt->id.idxa);
return 0; return 0;
case QSE_AWK_NDE_LCL: 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; return 0;
case QSE_AWK_NDE_ARG: 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; return 0;
case QSE_AWK_NDE_NAMEDIDX: case QSE_AWK_NDE_NAMEDIDX:
{ {
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
pair = qse_htb_search ( pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
run->named, tgt->id.name.ptr, tgt->id.name.len);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
pair = qse_htb_upsert ( pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
run->named, tgt->id.name.ptr,
tgt->id.name.len, qse_awk_val_nil, 0);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return -1; return -1;
} }
} }
tmp = get_reference_indexed ( tmp = get_reference_indexed(rtx, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
run, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0; return 0;
} }
case QSE_AWK_NDE_GBLIDX: case QSE_AWK_NDE_GBLIDX:
tmp = get_reference_indexed (run, tgt, tmp = get_reference_indexed (rtx, tgt, (qse_awk_val_t**)&RTX_STACK_GBL(rtx,tgt->id.idxa));
(qse_awk_val_t**)&RTX_STACK_GBL(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0; return 0;
case QSE_AWK_NDE_LCLIDX: case QSE_AWK_NDE_LCLIDX:
tmp = get_reference_indexed (run, tgt, tmp = get_reference_indexed (rtx, tgt, (qse_awk_val_t**)&RTX_STACK_LCL(rtx,tgt->id.idxa));
(qse_awk_val_t**)&RTX_STACK_LCL(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0; return 0;
case QSE_AWK_NDE_ARGIDX: case QSE_AWK_NDE_ARGIDX:
tmp = get_reference_indexed (run, tgt, tmp = get_reference_indexed(rtx, tgt, (qse_awk_val_t**)&RTX_STACK_ARG(rtx,tgt->id.idxa));
(qse_awk_val_t**)&RTX_STACK_ARG(run,tgt->id.idxa));
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL) return -1;
*ref = tmp; *ref = tmp;
return 0; return 0;
@ -6170,22 +6137,22 @@ static int get_reference (
/* the position number is returned for the positional /* the position number is returned for the positional
* variable unlike other reference types. */ * 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; if (v == QSE_NULL) return -1;
qse_awk_rtx_refupval (run, v); qse_awk_rtx_refupval (rtx, v);
n = qse_awk_rtx_valtoint (run, v, &lv); n = qse_awk_rtx_valtoint(rtx, v, &lv);
qse_awk_rtx_refdownval (run, v); qse_awk_rtx_refdownval (rtx, v);
if (n <= -1) if (n <= -1)
{ {
SETERR_LOC (run, QSE_AWK_EPOSIDX, &nde->loc); SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &nde->loc);
return -1; return -1;
} }
if (!IS_VALID_POSIDX(lv)) if (!IS_VALID_POSIDX(lv))
{ {
SETERR_LOC (run, QSE_AWK_EPOSIDX, &nde->loc); SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &nde->loc);
return -1; return -1;
} }
@ -6194,13 +6161,12 @@ static int get_reference (
} }
default: default:
SETERR_LOC (run, QSE_AWK_ENOTREF, &nde->loc); SETERR_LOC (rtx, QSE_AWK_ENOTREF, &nde->loc);
return -1; return -1;
} }
} }
static qse_awk_val_t** get_reference_indexed ( 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_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
{ {
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
qse_char_t* str; qse_char_t* str;
@ -6210,144 +6176,117 @@ static qse_awk_val_t** get_reference_indexed (
QSE_ASSERT (val != QSE_NULL); 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) if (vtype == QSE_AWK_VAL_NIL)
{ {
qse_awk_val_t* tmp; qse_awk_val_t* tmp;
tmp = qse_awk_rtx_makemapval (run); tmp = qse_awk_rtx_makemapval (rtx);
if (tmp == QSE_NULL) if (tmp == QSE_NULL)
{ {
ADJERR_LOC (run, &nde->loc); ADJERR_LOC (rtx, &nde->loc);
return QSE_NULL; return QSE_NULL;
} }
qse_awk_rtx_refdownval (run, *val); qse_awk_rtx_refdownval (rtx, *val);
*val = tmp; *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) 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; return QSE_NULL;
} }
QSE_ASSERT (nde->idx != QSE_NULL); QSE_ASSERT (nde->idx != QSE_NULL);
len = QSE_COUNTOF(idxbuf); 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; 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) if (pair == QSE_NULL)
{ {
pair = qse_htb_upsert ( pair = qse_htb_upsert((*(qse_awk_val_map_t**)val)->map, str, len, qse_awk_val_nil, 0);
(*(qse_awk_val_map_t**)val)->map,
str, len, qse_awk_val_nil, 0);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
if (str != idxbuf) QSE_AWK_FREE (run->awk, str); if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return QSE_NULL; 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); 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; qse_awk_val_t* val;
val = qse_awk_rtx_makeintval(rtx, ((qse_awk_nde_int_t*)nde)->val);
val = qse_awk_rtx_makeintval (run, ((qse_awk_nde_int_t*)nde)->val); if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
else if (QSE_AWK_VTR_IS_POINTER(val)) ((qse_awk_val_int_t*)val)->nde = nde; else if (QSE_AWK_VTR_IS_POINTER(val)) ((qse_awk_val_int_t*)val)->nde = nde;
return val; 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; qse_awk_val_t* val;
val = qse_awk_rtx_makefltval(rtx, ((qse_awk_nde_flt_t*)nde)->val);
val = qse_awk_rtx_makefltval (run, ((qse_awk_nde_flt_t*)nde)->val); if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
else ((qse_awk_val_flt_t*)val)->nde = nde; else ((qse_awk_val_flt_t*)val)->nde = nde;
return val; 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; qse_awk_val_t* val;
val = qse_awk_rtx_makestrval(rtx, ((qse_awk_nde_str_t*)nde)->ptr, ((qse_awk_nde_str_t*)nde)->len);
val = qse_awk_rtx_makestrval (run, if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
((qse_awk_nde_str_t*)nde)->ptr,
((qse_awk_nde_str_t*)nde)->len);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
return val; 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; qse_awk_val_t* val;
val = qse_awk_rtx_makembsval(rtx, ((qse_awk_nde_mbs_t*)nde)->ptr, ((qse_awk_nde_mbs_t*)nde)->len);
val = qse_awk_rtx_makembsval (run, if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
((qse_awk_nde_mbs_t*)nde)->ptr,
((qse_awk_nde_mbs_t*)nde)->len);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
return val; return val;
} }
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
{ {
qse_awk_val_t* val; qse_awk_val_t* val;
val = qse_awk_rtx_makerexval(rtx, &((qse_awk_nde_rex_t*)nde)->str, ((qse_awk_nde_rex_t*)nde)->code);
val = qse_awk_rtx_makerexval (run, if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
&((qse_awk_nde_rex_t*)nde)->str,
((qse_awk_nde_rex_t*)nde)->code
);
if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
return val; 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; qse_htb_pair_t* pair;
pair = qse_htb_search (rtx->named, ((qse_awk_nde_var_t*)nde)->id.name.ptr, ((qse_awk_nde_var_t*)nde)->id.name.len);
pair = qse_htb_search (
run->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); 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 ( static qse_awk_val_t* eval_indexed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
{ {
qse_htb_pair_t* pair; qse_htb_pair_t* pair;
qse_char_t* str; qse_char_t* str;
@ -6357,79 +6296,74 @@ static qse_awk_val_t* eval_indexed (
QSE_ASSERT (val != QSE_NULL); 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) if (vtype == QSE_AWK_VAL_NIL)
{ {
qse_awk_val_t* tmp; qse_awk_val_t* tmp;
tmp = qse_awk_rtx_makemapval (run); tmp = qse_awk_rtx_makemapval(rtx);
if (tmp == QSE_NULL) if (tmp == QSE_NULL)
{ {
ADJERR_LOC (run, &nde->loc); ADJERR_LOC (rtx, &nde->loc);
return QSE_NULL; return QSE_NULL;
} }
qse_awk_rtx_refdownval (run, *val); qse_awk_rtx_refdownval (rtx, *val);
*val = tmp; *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) 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; return QSE_NULL;
} }
QSE_ASSERT (nde->idx != QSE_NULL); QSE_ASSERT (nde->idx != QSE_NULL);
len = QSE_COUNTOF(idxbuf); 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; 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 (str != idxbuf) QSE_AWK_FREE (run->awk, str); if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
return (pair == QSE_NULL)? qse_awk_val_nil: return (pair == QSE_NULL)? qse_awk_val_nil: (qse_awk_val_t*)QSE_HTB_VPTR(pair);
(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_awk_nde_var_t* tgt = (qse_awk_nde_var_t*)nde;
qse_htb_pair_t* pair; 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) if (pair == QSE_NULL)
{ {
pair = qse_htb_upsert (run->named, pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc); SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
return QSE_NULL; 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, 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));
(qse_awk_val_t**)&RTX_STACK_GBL(run,((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, 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));
(qse_awk_val_t**)&RTX_STACK_LCL(run,((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, 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));
(qse_awk_val_t**)&RTX_STACK_ARG(run,((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) 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; 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: case QSE_AWK_NDE_GETLINE:
{ {
qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)nde; 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; 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: case QSE_AWK_NDE_GETLINE:
{ {
qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)p; 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_info_t info;
qse_awk_fnc_spec_t spec; qse_awk_fnc_spec_t spec;
} fnc; } fnc;
struct
{
qse_awk_nde_var_t* var;
} fcv;
} u; } u;
qse_awk_nde_t* args; qse_awk_nde_t* args;
qse_size_t nargs; qse_size_t nargs;