have implemented the function-pointer-as-value feature experimentally
This commit is contained in:
parent
d64d0a73b4
commit
3368c91834
@ -367,14 +367,15 @@ enum qse_awk_nde_type_t
|
|||||||
QSE_AWK_NDE_EXP_INCPRE,
|
QSE_AWK_NDE_EXP_INCPRE,
|
||||||
QSE_AWK_NDE_EXP_INCPST,
|
QSE_AWK_NDE_EXP_INCPST,
|
||||||
QSE_AWK_NDE_CND,
|
QSE_AWK_NDE_CND,
|
||||||
QSE_AWK_NDE_FNC,
|
QSE_AWK_NDE_FNCALL_FNC,
|
||||||
QSE_AWK_NDE_FUN,
|
QSE_AWK_NDE_FNCALL_FUN,
|
||||||
QSE_AWK_NDE_FCV,
|
QSE_AWK_NDE_FNCALL_VAR,
|
||||||
QSE_AWK_NDE_INT,
|
QSE_AWK_NDE_INT,
|
||||||
QSE_AWK_NDE_FLT,
|
QSE_AWK_NDE_FLT,
|
||||||
QSE_AWK_NDE_STR,
|
QSE_AWK_NDE_STR,
|
||||||
QSE_AWK_NDE_MBS,
|
QSE_AWK_NDE_MBS,
|
||||||
QSE_AWK_NDE_REX,
|
QSE_AWK_NDE_REX,
|
||||||
|
QSE_AWK_NDE_FUN,
|
||||||
|
|
||||||
/* keep this order for the following items otherwise, you may have
|
/* keep this order for the following items otherwise, you may have
|
||||||
* to change eval_incpre and eval_incpst in run.c as well as
|
* to change eval_incpre and eval_incpst in run.c as well as
|
||||||
@ -1276,6 +1277,7 @@ enum qse_awk_errnum_t
|
|||||||
QSE_AWK_EARGTF, /**< too few arguments */
|
QSE_AWK_EARGTF, /**< too few arguments */
|
||||||
QSE_AWK_EARGTM, /**< too many arguments */
|
QSE_AWK_EARGTM, /**< too many arguments */
|
||||||
QSE_AWK_EFUNNF, /**< function '${0}' not found */
|
QSE_AWK_EFUNNF, /**< function '${0}' not found */
|
||||||
|
QSE_AWK_ENOTFUN, /**< non-function value in '%{0}' */
|
||||||
QSE_AWK_ENOTDEL, /**< '${0}' not deletable */
|
QSE_AWK_ENOTDEL, /**< '${0}' not deletable */
|
||||||
QSE_AWK_ENOTMAP, /**< value not a map */
|
QSE_AWK_ENOTMAP, /**< value not a map */
|
||||||
QSE_AWK_ENOTMAPIN, /**< right-hand side of 'in' not a map */
|
QSE_AWK_ENOTMAPIN, /**< right-hand side of 'in' not a map */
|
||||||
|
@ -54,6 +54,22 @@ typedef struct qse_awk_tree_t qse_awk_tree_t;
|
|||||||
#define FEATURE_SCACHE_BLOCK_UNIT 16
|
#define FEATURE_SCACHE_BLOCK_UNIT 16
|
||||||
#define FEATURE_SCACHE_BLOCK_SIZE 128
|
#define FEATURE_SCACHE_BLOCK_SIZE 128
|
||||||
|
|
||||||
|
/* [NOTE] the function value support implemented is very limited.
|
||||||
|
* it supports very primitive way to call a function via a variable.
|
||||||
|
* only user-defined functions are supported. neither builtin functions
|
||||||
|
* nor module functions are not supported yet.
|
||||||
|
* -----------------------------------------------------
|
||||||
|
* function x(a,b,c) { print a, b, c; }
|
||||||
|
* BEGIN { q = x; q(1, 2, 3); } # this works
|
||||||
|
* BEGIN { q[1]=x; q[1](1,2,3); } # this doesn't work. same as q[1] %% (1, 2, 3) or q[1] %% 3
|
||||||
|
* BEGIN { q[1]=x; y=q[1]; y(1,2,3); } # this works.
|
||||||
|
* -----------------------------------------------------
|
||||||
|
* function __printer(a,b,c) { print a, b, c; }
|
||||||
|
* function show(printer, a,b,c) { printer(a, b, c); }
|
||||||
|
* BEGIN { show(__printer, 10, 20, 30); } ## passing the function value as an argumnet is ok.
|
||||||
|
*/
|
||||||
|
#define ENABLE_FEATURE_FUN_AS_VALUE
|
||||||
|
|
||||||
#define QSE_AWK_MAX_GBLS 9999
|
#define QSE_AWK_MAX_GBLS 9999
|
||||||
#define QSE_AWK_MAX_LCLS 9999
|
#define QSE_AWK_MAX_LCLS 9999
|
||||||
#define QSE_AWK_MAX_PARAMS 9999
|
#define QSE_AWK_MAX_PARAMS 9999
|
||||||
|
@ -119,6 +119,7 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
|
|||||||
QSE_T("too few arguments"),
|
QSE_T("too few arguments"),
|
||||||
QSE_T("too many arguments"),
|
QSE_T("too many arguments"),
|
||||||
QSE_T("function '${0}' not found"),
|
QSE_T("function '${0}' not found"),
|
||||||
|
QSE_T("non-function value in '${0}'"),
|
||||||
QSE_T("'${0}' not deletable"),
|
QSE_T("'${0}' not deletable"),
|
||||||
QSE_T("value not a map"),
|
QSE_T("value not a map"),
|
||||||
QSE_T("right-hand side of the 'in' operator not a map"),
|
QSE_T("right-hand side of the 'in' operator not a map"),
|
||||||
|
@ -96,7 +96,7 @@ enum tok_t
|
|||||||
TOK_LS,
|
TOK_LS,
|
||||||
TOK_IN,
|
TOK_IN,
|
||||||
TOK_EXP,
|
TOK_EXP,
|
||||||
TOK_CONCAT,
|
TOK_CONCAT, /* %% */
|
||||||
|
|
||||||
TOK_LPAREN,
|
TOK_LPAREN,
|
||||||
TOK_RPAREN,
|
TOK_RPAREN,
|
||||||
@ -111,7 +111,7 @@ enum tok_t
|
|||||||
TOK_COLON,
|
TOK_COLON,
|
||||||
TOK_DBLCOLON,
|
TOK_DBLCOLON,
|
||||||
TOK_QUEST,
|
TOK_QUEST,
|
||||||
TOK_DBLAT,
|
/*TOK_DBLAT,*/
|
||||||
|
|
||||||
/* == begin reserved words == */
|
/* == begin reserved words == */
|
||||||
/* === extended reserved words === */
|
/* === extended reserved words === */
|
||||||
@ -223,7 +223,7 @@ static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, const qse_awk_loc_t*
|
|||||||
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);
|
||||||
|
|
||||||
#define FNCALL_FLAG_NOARG (1 << 0) /* no argument */
|
#define FNCALL_FLAG_NOARG (1 << 0) /* no argument */
|
||||||
#define FNCALL_FLAG_FCV (1 << 1)
|
#define FNCALL_FLAG_VAR (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_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);
|
||||||
@ -1117,17 +1117,17 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* duplicate the name before it's overridden by get_token() */
|
/* duplicate the name before it's overridden by get_token() */
|
||||||
name.ptr = qse_strxdup (name.ptr, name.len, awk->mmgr);
|
name.ptr = qse_awk_strxdup(awk, name.ptr, name.len);
|
||||||
if (name.ptr == QSE_NULL)
|
if (name.ptr == QSE_NULL)
|
||||||
{
|
{
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
ADJERR_LOC (awk, &awk->tok.loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the next token */
|
/* get the next token */
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1136,14 +1136,14 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
{
|
{
|
||||||
/* a function name is not followed by a left parenthesis */
|
/* a function name is not followed by a left parenthesis */
|
||||||
SETERR_TOK (awk, QSE_AWK_ELPAREN);
|
SETERR_TOK (awk, QSE_AWK_ELPAREN);
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the next token */
|
/* get the next token */
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1156,7 +1156,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
/* no function parameter found. get the next token */
|
/* no function parameter found. get the next token */
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1169,7 +1169,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
|
|
||||||
if (!MATCH(awk,TOK_IDENT))
|
if (!MATCH(awk,TOK_IDENT))
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
SETERR_TOK (awk, QSE_AWK_EBADPAR);
|
SETERR_TOK (awk, QSE_AWK_EBADPAR);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
@ -1192,7 +1192,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
qse_strxncmp (pa, pal, name.ptr, name.len) == 0) ||
|
qse_strxncmp (pa, pal, name.ptr, name.len) == 0) ||
|
||||||
qse_arr_search (awk->parse.params, 0, pa, pal) != QSE_ARR_NIL)
|
qse_arr_search (awk->parse.params, 0, pa, pal) != QSE_ARR_NIL)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
SETERR_ARG_LOC (
|
SETERR_ARG_LOC (
|
||||||
awk, QSE_AWK_EDUPPAR,
|
awk, QSE_AWK_EDUPPAR,
|
||||||
@ -1203,35 +1203,32 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
/* push the parameter to the parameter list */
|
/* push the parameter to the parameter list */
|
||||||
if (QSE_ARR_SIZE(awk->parse.params) >= QSE_AWK_MAX_PARAMS)
|
if (QSE_ARR_SIZE(awk->parse.params) >= QSE_AWK_MAX_PARAMS)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
SETERR_LOC (awk, QSE_AWK_EPARTM, &awk->tok.loc);
|
SETERR_LOC (awk, QSE_AWK_EPARTM, &awk->tok.loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qse_arr_insert (
|
if (qse_arr_insert(awk->parse.params, QSE_ARR_SIZE(awk->parse.params), pa, pal) == QSE_ARR_NIL)
|
||||||
awk->parse.params,
|
|
||||||
QSE_ARR_SIZE(awk->parse.params),
|
|
||||||
pa, pal) == QSE_ARR_NIL)
|
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_token (awk) <= -1)
|
if (get_token (awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MATCH(awk,TOK_RPAREN)) break;
|
if (MATCH(awk,TOK_RPAREN)) break;
|
||||||
|
|
||||||
if (!MATCH(awk,TOK_COMMA))
|
if (!MATCH(awk,TOK_COMMA))
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
SETERR_TOK (awk, QSE_AWK_ECOMMA);
|
SETERR_TOK (awk, QSE_AWK_ECOMMA);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
@ -1241,7 +1238,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
{
|
{
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -1251,7 +1248,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
|
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -1265,7 +1262,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
{
|
{
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -1274,15 +1271,14 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
/* check if the function body starts with a left brace */
|
/* check if the function body starts with a left brace */
|
||||||
if (!MATCH(awk,TOK_LBRACE))
|
if (!MATCH(awk,TOK_LBRACE))
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
|
|
||||||
SETERR_TOK (awk, QSE_AWK_ELBRACE);
|
SETERR_TOK (awk, QSE_AWK_ELBRACE);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -1302,7 +1298,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
|
|
||||||
if (body == QSE_NULL)
|
if (body == QSE_NULL)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -1313,10 +1309,10 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
/* parameter names are not required anymore. clear them */
|
/* parameter names are not required anymore. clear them */
|
||||||
qse_arr_clear (awk->parse.params);
|
qse_arr_clear (awk->parse.params);
|
||||||
|
|
||||||
fun = (qse_awk_fun_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*fun));
|
fun = (qse_awk_fun_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*fun));
|
||||||
if (fun == QSE_NULL)
|
if (fun == QSE_NULL)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_awk_clrpt (awk, body);
|
qse_awk_clrpt (awk, body);
|
||||||
ADJERR_LOC (awk, &awk->tok.loc);
|
ADJERR_LOC (awk, &awk->tok.loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
@ -1327,15 +1323,15 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
fun->nargs = nargs;
|
fun->nargs = nargs;
|
||||||
fun->body = body;
|
fun->body = body;
|
||||||
|
|
||||||
pair = qse_htb_insert (awk->tree.funs, name.ptr, name.len, fun, 0);
|
pair = qse_htb_insert(awk->tree.funs, name.ptr, name.len, fun, 0);
|
||||||
if (pair == QSE_NULL)
|
if (pair == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* if qse_htb_insert() fails for other reasons than memory
|
/* if qse_htb_insert() fails for other reasons than memory
|
||||||
* shortage, there should be implementaion errors as duplicate
|
* shortage, there should be implementaion errors as duplicate
|
||||||
* functions are detected earlier in this function */
|
* functions are detected earlier in this function */
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
qse_awk_clrpt (awk, body);
|
qse_awk_clrpt (awk, body);
|
||||||
QSE_AWK_FREE (awk, fun);
|
qse_awk_freemem (awk, fun);
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -1344,7 +1340,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
|||||||
* of the pair */
|
* of the pair */
|
||||||
fun->name.ptr = QSE_HTB_KPTR(pair);
|
fun->name.ptr = QSE_HTB_KPTR(pair);
|
||||||
fun->name.len = QSE_HTB_KLEN(pair);
|
fun->name.len = QSE_HTB_KLEN(pair);
|
||||||
QSE_AWK_FREE (awk, name.ptr);
|
qse_awk_freemem (awk, name.ptr);
|
||||||
|
|
||||||
/* remove an undefined function call entry from the parse.fun table */
|
/* remove an undefined function call entry from the parse.fun table */
|
||||||
qse_htb_delete (awk->parse.funs, fun->name.ptr, name.len);
|
qse_htb_delete (awk->parse.funs, fun->name.ptr, name.len);
|
||||||
@ -1415,16 +1411,15 @@ static qse_awk_chain_t* parse_action_block (
|
|||||||
{
|
{
|
||||||
QSE_ASSERT (MATCH(awk,TOK_LBRACE));
|
QSE_ASSERT (MATCH(awk,TOK_LBRACE));
|
||||||
if (get_token(awk) <= -1) return QSE_NULL;
|
if (get_token(awk) <= -1) return QSE_NULL;
|
||||||
nde = parse_block_dc (awk, &xloc, 1);
|
nde = parse_block_dc(awk, &xloc, 1);
|
||||||
if (nde == QSE_NULL) return QSE_NULL;
|
if (nde == QSE_NULL) return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
chain = (qse_awk_chain_t*)
|
chain = (qse_awk_chain_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*chain));
|
||||||
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_chain_t));
|
|
||||||
if (chain == QSE_NULL)
|
if (chain == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_clrpt (awk, nde);
|
qse_awk_clrpt (awk, nde);
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &xloc);
|
ADJERR_LOC (awk, &xloc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3052,8 +3047,7 @@ static qse_awk_nde_t* parse_statement_nb (
|
|||||||
return nde;
|
return nde;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_statement (
|
static qse_awk_nde_t* parse_statement (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* nde;
|
qse_awk_nde_t* nde;
|
||||||
|
|
||||||
@ -3065,12 +3059,11 @@ static qse_awk_nde_t* parse_statement (
|
|||||||
|
|
||||||
if (MATCH(awk,TOK_SEMICOLON))
|
if (MATCH(awk,TOK_SEMICOLON))
|
||||||
{
|
{
|
||||||
/* null statement */
|
/* null statement */
|
||||||
nde = (qse_awk_nde_t*)
|
nde = (qse_awk_nde_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
|
||||||
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_t));
|
if (!nde)
|
||||||
if (nde == QSE_NULL)
|
|
||||||
{
|
{
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
ADJERR_LOC (awk, xloc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3080,7 +3073,7 @@ static qse_awk_nde_t* parse_statement (
|
|||||||
|
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, nde);
|
qse_awk_freemem (awk, nde);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3150,8 +3143,7 @@ static int assign_to_opcode (qse_awk_t* awk)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_expr_basic (
|
static qse_awk_nde_t* parse_expr_basic (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* nde, * n1, * n2;
|
qse_awk_nde_t* nde, * n1, * n2;
|
||||||
|
|
||||||
@ -3170,7 +3162,7 @@ static qse_awk_nde_t* parse_expr_basic (
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
eloc = awk->tok.loc;
|
eloc = awk->tok.loc;
|
||||||
n1 = parse_expr_withdc (awk, &eloc);
|
n1 = parse_expr_withdc (awk, &eloc);
|
||||||
if (n1 == QSE_NULL)
|
if (n1 == QSE_NULL)
|
||||||
{
|
{
|
||||||
@ -3201,14 +3193,13 @@ static qse_awk_nde_t* parse_expr_basic (
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cnd = (qse_awk_nde_cnd_t*) QSE_AWK_ALLOC (
|
cnd = (qse_awk_nde_cnd_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*cnd));
|
||||||
awk, QSE_SIZEOF(qse_awk_nde_cnd_t));
|
|
||||||
if (cnd == QSE_NULL)
|
if (cnd == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_clrpt (awk, nde);
|
qse_awk_clrpt (awk, nde);
|
||||||
qse_awk_clrpt (awk, n1);
|
qse_awk_clrpt (awk, n1);
|
||||||
qse_awk_clrpt (awk, n2);
|
qse_awk_clrpt (awk, n2);
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
ADJERR_LOC (awk, xloc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3225,8 +3216,7 @@ static qse_awk_nde_t* parse_expr_basic (
|
|||||||
return nde;
|
return nde;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_expr (
|
static qse_awk_nde_t* parse_expr (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* x, * y;
|
qse_awk_nde_t* x, * y;
|
||||||
qse_awk_nde_ass_t* nde;
|
qse_awk_nde_ass_t* nde;
|
||||||
@ -3258,7 +3248,6 @@ static qse_awk_nde_t* parse_expr (
|
|||||||
|
|
||||||
{
|
{
|
||||||
qse_awk_loc_t eloc;
|
qse_awk_loc_t eloc;
|
||||||
|
|
||||||
eloc = awk->tok.loc;
|
eloc = awk->tok.loc;
|
||||||
y = parse_expr_withdc (awk, &eloc);
|
y = parse_expr_withdc (awk, &eloc);
|
||||||
}
|
}
|
||||||
@ -3268,14 +3257,12 @@ static qse_awk_nde_t* parse_expr (
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nde = (qse_awk_nde_ass_t*)
|
nde = (qse_awk_nde_ass_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
|
||||||
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_ass_t));
|
|
||||||
if (nde == QSE_NULL)
|
if (nde == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_clrpt (awk, x);
|
qse_awk_clrpt (awk, x);
|
||||||
qse_awk_clrpt (awk, y);
|
qse_awk_clrpt (awk, y);
|
||||||
|
ADJERR_LOC (awk, xloc);
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3289,8 +3276,7 @@ static qse_awk_nde_t* parse_expr (
|
|||||||
return (qse_awk_nde_t*)nde;
|
return (qse_awk_nde_t*)nde;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_expr_withdc (
|
static qse_awk_nde_t* parse_expr_withdc (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* nde;
|
qse_awk_nde_t* nde;
|
||||||
|
|
||||||
@ -4271,7 +4257,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 (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 */
|
/* the current function begin parsed */
|
||||||
return FNTYPE_FUN;
|
return FNTYPE_FUN;
|
||||||
@ -4306,7 +4292,6 @@ static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_cstr_t* name)
|
|||||||
return isfunname(awk, name);
|
return isfunname(awk, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_primary_int (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
static qse_awk_nde_t* parse_primary_int (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
{
|
{
|
||||||
qse_awk_nde_int_t* nde;
|
qse_awk_nde_int_t* nde;
|
||||||
@ -4786,7 +4771,7 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|||||||
qse_awk_nde_t* var = QSE_NULL;
|
qse_awk_nde_t* var = QSE_NULL;
|
||||||
qse_awk_loc_t ploc;
|
qse_awk_loc_t ploc;
|
||||||
|
|
||||||
left = parse_primary_nopipe (awk, xloc);
|
left = parse_primary_nopipe(awk, xloc);
|
||||||
if (left == QSE_NULL) goto oops;
|
if (left == QSE_NULL) goto oops;
|
||||||
|
|
||||||
/* handle the piping part */
|
/* handle the piping part */
|
||||||
@ -4800,8 +4785,7 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|||||||
{
|
{
|
||||||
intype = QSE_AWK_IN_PIPE;
|
intype = QSE_AWK_IN_PIPE;
|
||||||
}
|
}
|
||||||
else if (MATCH(awk,TOK_LOR) &&
|
else if (MATCH(awk,TOK_LOR) && (awk->opt.trait & QSE_AWK_RWPIPE))
|
||||||
(awk->opt.trait & QSE_AWK_RWPIPE))
|
|
||||||
{
|
{
|
||||||
intype = QSE_AWK_IN_RWPIPE;
|
intype = QSE_AWK_IN_RWPIPE;
|
||||||
}
|
}
|
||||||
@ -4810,11 +4794,10 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|||||||
if (intype == -1) break;
|
if (intype == -1) break;
|
||||||
|
|
||||||
if (preget_token(awk) <= -1) goto oops;
|
if (preget_token(awk) <= -1) goto oops;
|
||||||
|
|
||||||
if (awk->ntok.type != TOK_GETLINE) break;
|
if (awk->ntok.type != TOK_GETLINE) break;
|
||||||
|
|
||||||
/* consume ntok('getline') */
|
/* consume ntok('getline') */
|
||||||
get_token (awk);
|
get_token(awk); /* no error check needed as it's guaranteeded to succeed for preget_token() above */
|
||||||
|
|
||||||
/* get the next token */
|
/* get the next token */
|
||||||
if (get_token(awk) <= -1) goto oops;
|
if (get_token(awk) <= -1) goto oops;
|
||||||
@ -4861,7 +4844,7 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
novar:
|
novar:
|
||||||
nde = (qse_awk_nde_getline_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*nde));
|
nde = (qse_awk_nde_getline_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
|
||||||
if (nde == QSE_NULL)
|
if (nde == QSE_NULL)
|
||||||
{
|
{
|
||||||
ADJERR_LOC (awk, xloc);
|
ADJERR_LOC (awk, xloc);
|
||||||
@ -4890,22 +4873,24 @@ oops:
|
|||||||
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;
|
qse_awk_nde_var_t* nde;
|
||||||
int fcv = 0;
|
int is_fcv = 0;
|
||||||
|
|
||||||
|
if (MATCH(awk,TOK_LPAREN))
|
||||||
|
{
|
||||||
|
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||||
/*
|
/*
|
||||||
if (MATCH(awk,TOK_LPAREN) &&
|
if (MATCH(awk,TOK_LPAREN) &&
|
||||||
(!(awk->opt.trait & QSE_AWK_BLANKCONCAT) ||
|
(!(awk->opt.trait & QSE_AWK_BLANKCONCAT) ||
|
||||||
(awk->tok.loc.line == xloc->line &&
|
(awk->tok.loc.line == xloc->line &&
|
||||||
awk->tok.loc.colm == xloc->colm + name->len)))
|
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)
|
if (awk->tok.loc.line == xloc->line && awk->tok.loc.colm == xloc->colm + name->len)
|
||||||
{
|
{
|
||||||
fcv = 1;
|
is_fcv = 1;
|
||||||
}
|
}
|
||||||
else if (!(awk->opt.trait & QSE_AWK_BLANKCONCAT))
|
else
|
||||||
|
#endif
|
||||||
|
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
|
||||||
@ -4934,8 +4919,12 @@ static qse_awk_nde_t* parse_variable (qse_awk_t* awk, const qse_awk_loc_t* xloc,
|
|||||||
nde->id.idxa = idxa;
|
nde->id.idxa = idxa;
|
||||||
nde->idx = QSE_NULL;
|
nde->idx = QSE_NULL;
|
||||||
|
|
||||||
if (!fcv) return (qse_awk_nde_t*)nde;
|
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||||
return parse_fncall(awk, (const qse_cstr_t*)nde, QSE_NULL, xloc, FNCALL_FLAG_FCV);
|
if (!is_fcv) return (qse_awk_nde_t*)nde;
|
||||||
|
return parse_fncall(awk, (const qse_cstr_t*)nde, QSE_NULL, xloc, FNCALL_FLAG_VAR);
|
||||||
|
#else
|
||||||
|
return (qse_awk_nde_t*)nde;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -4950,10 +4939,10 @@ static int dup_ident_and_get_next (qse_awk_t* awk, const qse_awk_loc_t* xloc, qs
|
|||||||
name[nsegs].len = QSE_STR_LEN(awk->tok.name);
|
name[nsegs].len = QSE_STR_LEN(awk->tok.name);
|
||||||
|
|
||||||
/* duplicate the identifier */
|
/* duplicate the identifier */
|
||||||
name[nsegs].ptr = qse_strxdup (name[nsegs].ptr, name[nsegs].len, awk->mmgr);
|
name[nsegs].ptr = qse_awk_strxdup(awk, name[nsegs].ptr, name[nsegs].len);
|
||||||
if (name[nsegs].ptr == QSE_NULL)
|
if (name[nsegs].ptr == QSE_NULL)
|
||||||
{
|
{
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
ADJERR_LOC (awk, xloc);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4987,10 +4976,33 @@ static int dup_ident_and_get_next (qse_awk_t* awk, const qse_awk_loc_t* xloc, qs
|
|||||||
return nsegs;
|
return nsegs;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
while (nsegs > 0) QSE_AWK_FREE (awk, name[--nsegs].ptr);
|
while (nsegs > 0) qse_awk_freemem (awk, name[--nsegs].ptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||||
|
static qse_awk_nde_t* parse_fun_as_value (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc)
|
||||||
|
{
|
||||||
|
qse_awk_nde_fun_t* nde;
|
||||||
|
|
||||||
|
/* create the node for the literal */
|
||||||
|
nde = (qse_awk_nde_fun_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
|
||||||
|
if (nde == QSE_NULL)
|
||||||
|
{
|
||||||
|
ADJERR_LOC (awk, xloc);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nde->type = QSE_AWK_NDE_FUN;
|
||||||
|
nde->loc = *xloc;
|
||||||
|
nde->name.ptr = name->ptr;
|
||||||
|
nde->name.len = name->len;
|
||||||
|
|
||||||
|
|
||||||
|
return (qse_awk_nde_t*)nde;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
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_awk_fnc_t* fnc;
|
||||||
@ -5071,7 +5083,11 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* function name appeared without () */
|
/* function name appeared without () */
|
||||||
|
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||||
|
nde = parse_fun_as_value(awk, name, xloc);
|
||||||
|
#else
|
||||||
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
|
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (awk->opt.trait & QSE_AWK_IMPLICIT)
|
else if (awk->opt.trait & QSE_AWK_IMPLICIT)
|
||||||
@ -5084,6 +5100,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
|
|||||||
* by a left parenthesis if concatenation by blanks
|
* by a left parenthesis if concatenation by blanks
|
||||||
* is not allowed.
|
* is not allowed.
|
||||||
*/
|
*/
|
||||||
|
int is_fncall_var = 0;
|
||||||
|
|
||||||
if (MATCH(awk,TOK_LPAREN) &&
|
if (MATCH(awk,TOK_LPAREN) &&
|
||||||
(!(awk->opt.trait & QSE_AWK_BLANKCONCAT) ||
|
(!(awk->opt.trait & QSE_AWK_BLANKCONCAT) ||
|
||||||
@ -5091,11 +5108,15 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
|
|||||||
awk->tok.loc.colm == xloc->colm + name->len)))
|
awk->tok.loc.colm == xloc->colm + name->len)))
|
||||||
{
|
{
|
||||||
/* it is a function call to an undefined function yet */
|
/* 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 */
|
/* the function call conflicts with a named variable */
|
||||||
|
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||||
|
is_fncall_var = 1;
|
||||||
|
goto named_var;
|
||||||
|
#else
|
||||||
SETERR_ARG_LOC (awk, QSE_AWK_EVARRED, name->ptr, name->len, xloc);
|
SETERR_ARG_LOC (awk, QSE_AWK_EVARRED, name->ptr, name->len, xloc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5106,6 +5127,10 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
|
|||||||
{
|
{
|
||||||
qse_awk_nde_var_t* tmp;
|
qse_awk_nde_var_t* tmp;
|
||||||
|
|
||||||
|
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||||
|
named_var:
|
||||||
|
#endif
|
||||||
|
|
||||||
/* if there is a space between the name and the left parenthesis
|
/* if there is a space between the name and the left parenthesis
|
||||||
* 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
|
||||||
@ -5116,7 +5141,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
|
|||||||
{
|
{
|
||||||
/* collect unique instances of a named variable
|
/* collect unique instances of a named variable
|
||||||
* for reference */
|
* 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);
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
QSE_AWK_FREE (awk, tmp);
|
QSE_AWK_FREE (awk, tmp);
|
||||||
@ -5129,8 +5154,12 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
|
|||||||
tmp->id.name.len = name->len;
|
tmp->id.name.len = name->len;
|
||||||
tmp->id.idxa = (qse_size_t)-1;
|
tmp->id.idxa = (qse_size_t)-1;
|
||||||
tmp->idx = QSE_NULL;
|
tmp->idx = QSE_NULL;
|
||||||
|
|
||||||
nde = (qse_awk_nde_t*)tmp;
|
nde = (qse_awk_nde_t*)tmp;
|
||||||
|
|
||||||
|
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||||
|
if (is_fncall_var)
|
||||||
|
nde = parse_fncall(awk, (const qse_cstr_t*)nde, QSE_NULL, xloc, FNCALL_FLAG_VAR);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5216,8 +5245,7 @@ static qse_awk_nde_t* parse_primary_ident_segs (qse_awk_t* awk, const qse_awk_lo
|
|||||||
return nde;
|
return nde;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_primary_ident (
|
static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* nde = QSE_NULL;
|
qse_awk_nde_t* nde = QSE_NULL;
|
||||||
qse_cstr_t name[2]; /* TODO: support more than 2 segments??? */
|
qse_cstr_t name[2]; /* TODO: support more than 2 segments??? */
|
||||||
@ -5225,13 +5253,13 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
|
|
||||||
QSE_ASSERT (MATCH(awk,TOK_IDENT));
|
QSE_ASSERT (MATCH(awk,TOK_IDENT));
|
||||||
|
|
||||||
nsegs = dup_ident_and_get_next (awk, xloc, name, QSE_COUNTOF(name));
|
nsegs = dup_ident_and_get_next(awk, xloc, name, QSE_COUNTOF(name));
|
||||||
if (nsegs <= -1) return QSE_NULL;
|
if (nsegs <= -1) return QSE_NULL;
|
||||||
|
|
||||||
if (nsegs <= 1)
|
if (nsegs <= 1)
|
||||||
{
|
{
|
||||||
nde = parse_primary_ident_noseg (awk, xloc, &name[0]);
|
nde = parse_primary_ident_noseg (awk, xloc, &name[0]);
|
||||||
if (!nde) QSE_AWK_FREE (awk, name[0].ptr);
|
if (!nde) qse_awk_freemem (awk, name[0].ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5240,7 +5268,7 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (capa = 0, i = 0; i < nsegs; i++) capa += name[i].len + 2; /* +2 for :: */
|
for (capa = 0, i = 0; i < nsegs; i++) capa += name[i].len + 2; /* +2 for :: */
|
||||||
full.ptr = qse_awk_allocmem (awk, QSE_SIZEOF(*full.ptr) * (capa + 1));
|
full.ptr = qse_awk_allocmem(awk, QSE_SIZEOF(*full.ptr) * (capa + 1));
|
||||||
if (full.ptr)
|
if (full.ptr)
|
||||||
{
|
{
|
||||||
capa = qse_strncpy (&full.ptr[0], name[0].ptr, name[0].len);
|
capa = qse_strncpy (&full.ptr[0], name[0].ptr, name[0].len);
|
||||||
@ -5252,12 +5280,12 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
full.ptr[capa] = QSE_T('\0');
|
full.ptr[capa] = QSE_T('\0');
|
||||||
full.len = capa;
|
full.len = capa;
|
||||||
|
|
||||||
nde = parse_primary_ident_segs (awk, xloc, &full, name, nsegs);
|
nde = parse_primary_ident_segs(awk, xloc, &full, name, nsegs);
|
||||||
if (!nde || nde->type != QSE_AWK_NDE_FNC)
|
if (!nde || nde->type != QSE_AWK_NDE_FNCALL_FNC)
|
||||||
{
|
{
|
||||||
/* the FNC node takes the full name but other
|
/* the FNC node takes the full name but other
|
||||||
* nodes don't. so i need to free it. i know it's ugly. */
|
* nodes don't. so i need to free it. i know it's ugly. */
|
||||||
QSE_AWK_FREE (awk, full.ptr);
|
qse_awk_freemem (awk, full.ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -5267,7 +5295,7 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* i don't need the name segments */
|
/* i don't need the name segments */
|
||||||
while (nsegs > 0) QSE_AWK_FREE (awk, name[--nsegs].ptr);
|
while (nsegs > 0) qse_awk_freemem (awk, name[--nsegs].ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nde;
|
return nde;
|
||||||
@ -5414,7 +5442,7 @@ static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, con
|
|||||||
|
|
||||||
exit_func:
|
exit_func:
|
||||||
qse_awk_clrpt (awk, idx);
|
qse_awk_clrpt (awk, idx);
|
||||||
QSE_AWK_FREE (awk, nde);
|
qse_awk_freemem (awk, nde);
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -5482,17 +5510,17 @@ make_node:
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & FNCALL_FLAG_FCV)
|
if (flags & FNCALL_FLAG_VAR)
|
||||||
{
|
{
|
||||||
call->type = QSE_AWK_NDE_FCV;
|
call->type = QSE_AWK_NDE_FNCALL_VAR;
|
||||||
call->loc = *xloc;
|
call->loc = *xloc;
|
||||||
call->u.fcv.var = (qse_awk_nde_var_t*)name; /* name is a pointer to a variable node */
|
call->u.var.var = (qse_awk_nde_var_t*)name; /* name is a pointer to a variable node */
|
||||||
call->args = head;
|
call->args = head;
|
||||||
call->nargs = nargs;
|
call->nargs = nargs;
|
||||||
}
|
}
|
||||||
else if (fnc)
|
else if (fnc)
|
||||||
{
|
{
|
||||||
call->type = QSE_AWK_NDE_FNC;
|
call->type = QSE_AWK_NDE_FNCALL_FNC;
|
||||||
call->loc = *xloc;
|
call->loc = *xloc;
|
||||||
|
|
||||||
call->u.fnc.info.name.ptr = name->ptr;
|
call->u.fnc.info.name.ptr = name->ptr;
|
||||||
@ -5516,7 +5544,7 @@ make_node:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
call->type = QSE_AWK_NDE_FUN;
|
call->type = QSE_AWK_NDE_FNCALL_FUN;
|
||||||
call->loc = *xloc;
|
call->loc = *xloc;
|
||||||
call->u.fun.name.ptr = name->ptr;
|
call->u.fun.name.ptr = name->ptr;
|
||||||
call->u.fun.name.len = name->len;
|
call->u.fun.name.len = name->len;
|
||||||
@ -5534,7 +5562,7 @@ make_node:
|
|||||||
return (qse_awk_nde_t*)call;
|
return (qse_awk_nde_t*)call;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (call) QSE_AWK_FREE (awk, call);
|
if (call) qse_awk_freemem (awk, call);
|
||||||
if (head) qse_awk_clrpt (awk, head);
|
if (head) qse_awk_clrpt (awk, head);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
@ -224,13 +224,13 @@ static qse_awk_val_t* eval_incpre (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
|||||||
static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||||
static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||||
|
|
||||||
static qse_awk_val_t* eval_fun_ex (
|
static qse_awk_val_t* eval_fncall_fncall_fun_ex (
|
||||||
qse_awk_rtx_t* run, qse_awk_nde_t* nde,
|
qse_awk_rtx_t* run, qse_awk_nde_t* nde,
|
||||||
void(*errhandler)(void*), void* eharg);
|
void(*errhandler)(void*), void* eharg);
|
||||||
|
|
||||||
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
static qse_awk_val_t* eval_fncall_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_fncall_fncall_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_fncall_var (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,
|
||||||
@ -257,6 +257,7 @@ 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);
|
||||||
|
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||||
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* run, qse_awk_nde_t* nde);
|
||||||
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* run, qse_awk_nde_t* nde);
|
||||||
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* run, qse_awk_nde_t* nde);
|
||||||
@ -1630,7 +1631,7 @@ qse_awk_val_t* qse_awk_rtx_callfun (
|
|||||||
|
|
||||||
/* forge a fake node containing a function call */
|
/* forge a fake node containing a function call */
|
||||||
QSE_MEMSET (&call, 0, QSE_SIZEOF(call));
|
QSE_MEMSET (&call, 0, QSE_SIZEOF(call));
|
||||||
call.type = QSE_AWK_NDE_FUN;
|
call.type = QSE_AWK_NDE_FNCALL_FUN;
|
||||||
call.u.fun.name = fun->name;
|
call.u.fun.name = fun->name;
|
||||||
call.nargs = nargs;
|
call.nargs = nargs;
|
||||||
|
|
||||||
@ -3326,14 +3327,15 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
eval_incpre,
|
eval_incpre,
|
||||||
eval_incpst,
|
eval_incpst,
|
||||||
eval_cnd,
|
eval_cnd,
|
||||||
eval_fnc,
|
eval_fncall_fnc,
|
||||||
eval_fun,
|
eval_fncall_fncall_fun,
|
||||||
eval_fcv,
|
eval_fncall_var,
|
||||||
eval_int,
|
eval_int,
|
||||||
eval_flt,
|
eval_flt,
|
||||||
eval_str,
|
eval_str,
|
||||||
eval_mbs,
|
eval_mbs,
|
||||||
eval_rex,
|
eval_rex,
|
||||||
|
eval_fun,
|
||||||
eval_named,
|
eval_named,
|
||||||
eval_gbl,
|
eval_gbl,
|
||||||
eval_lcl,
|
eval_lcl,
|
||||||
@ -3350,10 +3352,9 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
|
|
||||||
qse_awk_val_t* v;
|
qse_awk_val_t* v;
|
||||||
|
|
||||||
QSE_ASSERT (nde->type >= QSE_AWK_NDE_GRP &&
|
QSE_ASSERT (nde->type >= QSE_AWK_NDE_GRP && (nde->type - QSE_AWK_NDE_GRP) < QSE_COUNTOF(__evaluator));
|
||||||
(nde->type - QSE_AWK_NDE_GRP) < QSE_COUNTOF(__evaluator));
|
|
||||||
|
|
||||||
v = __evaluator[nde->type-QSE_AWK_NDE_GRP] (run, nde);
|
v = __evaluator[nde->type-QSE_AWK_NDE_GRP](run, nde);
|
||||||
|
|
||||||
if (v != QSE_NULL && run->exit_level >= EXIT_GLOBAL)
|
if (v != QSE_NULL && run->exit_level >= EXIT_GLOBAL)
|
||||||
{
|
{
|
||||||
@ -5602,7 +5603,7 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
static qse_awk_val_t* eval_fncall_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;
|
||||||
@ -5612,7 +5613,7 @@ static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
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_INLINE 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_fncall_fncall_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_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
|
||||||
qse_awk_fun_t* fun;
|
qse_awk_fun_t* fun;
|
||||||
@ -5639,29 +5640,28 @@ static QSE_INLINE qse_awk_val_t* eval_fun_ex (qse_awk_rtx_t* rtx, qse_awk_nde_t*
|
|||||||
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* rtx, qse_awk_nde_t* nde)
|
static qse_awk_val_t* eval_fncall_fncall_fun (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||||
{
|
{
|
||||||
return eval_fun_ex(rtx, nde, QSE_NULL, QSE_NULL);
|
return eval_fncall_fncall_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)
|
static qse_awk_val_t* eval_fncall_var (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||||
{
|
{
|
||||||
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_val_t* fv, * rv;
|
qse_awk_val_t* fv, * rv;
|
||||||
|
|
||||||
fv = eval_expression(rtx, (qse_awk_nde_t*)call->u.fcv.var);
|
fv = eval_expression(rtx, (qse_awk_nde_t*)call->u.var.var);
|
||||||
if (!fv) return QSE_NULL;
|
if (!fv) return QSE_NULL;
|
||||||
|
|
||||||
qse_awk_rtx_refupval (rtx, fv);
|
qse_awk_rtx_refupval (rtx, fv);
|
||||||
if (QSE_AWK_RTX_GETVALTYPE(rtx, fv) != QSE_AWK_VAL_FUN)
|
if (QSE_AWK_RTX_GETVALTYPE(rtx, fv) != QSE_AWK_VAL_FUN)
|
||||||
{
|
{
|
||||||
/*SETERR_ARGX_LOC (rtx, QSE_AWK_EFUNNF, &call->u.fun.name, &nde->loc);*/
|
SETERR_ARGX_LOC (rtx, QSE_AWK_ENOTFUN, &call->u.var.var->id.name, &nde->loc);
|
||||||
/*printf ("NOT FUNCTION VALUE\n");*/
|
|
||||||
rv = QSE_NULL;
|
rv = QSE_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rv = eval_call(rtx, nde, QSE_NULL, ((qse_awk_val_fun_t*)fv)->fun, QSE_NULL, QSE_NULL );
|
rv = eval_call(rtx, nde, QSE_NULL, ((qse_awk_val_fun_t*)fv)->fun, QSE_NULL, QSE_NULL);
|
||||||
}
|
}
|
||||||
qse_awk_rtx_refdownval (rtx, fv);
|
qse_awk_rtx_refdownval (rtx, fv);
|
||||||
|
|
||||||
@ -6002,19 +6002,18 @@ static qse_size_t push_arg_from_nde (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* c
|
|||||||
v = qse_awk_rtx_makerefval (
|
v = qse_awk_rtx_makerefval (
|
||||||
rtx, p->type-QSE_AWK_NDE_NAMED, ref);
|
rtx, p->type-QSE_AWK_NDE_NAMED, ref);
|
||||||
}
|
}
|
||||||
else if (fnc_arg_spec &&
|
else if (fnc_arg_spec && fnc_arg_spec[nargs] == QSE_T('x'))
|
||||||
fnc_arg_spec[nargs] == QSE_T('x'))
|
|
||||||
{
|
{
|
||||||
/* a regular expression is passed to
|
/* a regular expression is passed to
|
||||||
* the function as it is */
|
* the function as it is */
|
||||||
v = eval_expression0 (rtx, p);
|
v = eval_expression0(rtx, p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v = eval_expression (rtx, p);
|
v = eval_expression(rtx, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v == QSE_NULL)
|
if (!v)
|
||||||
{
|
{
|
||||||
UNWIND_RTX_STACK_ARG (rtx, nargs);
|
UNWIND_RTX_STACK_ARG (rtx, nargs);
|
||||||
return (qse_size_t)-1;
|
return (qse_size_t)-1;
|
||||||
@ -6043,7 +6042,7 @@ static qse_size_t push_arg_from_nde (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* c
|
|||||||
|
|
||||||
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* rtx, 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)
|
||||||
@ -6264,6 +6263,32 @@ static qse_awk_val_t* eval_rex (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||||
|
{
|
||||||
|
qse_awk_val_t* val;
|
||||||
|
qse_awk_fun_t* fun;
|
||||||
|
qse_htb_pair_t* pair;
|
||||||
|
|
||||||
|
fun = ((qse_awk_nde_fun_t*)nde)->ptr;
|
||||||
|
if (!fun)
|
||||||
|
{
|
||||||
|
/* TODO: support bultin functions?, support module functions? */
|
||||||
|
pair = qse_htb_search(rtx->awk->tree.funs, ((qse_awk_nde_fun_t*)nde)->name.ptr, ((qse_awk_nde_fun_t*)nde)->name.len);
|
||||||
|
if (!pair)
|
||||||
|
{
|
||||||
|
SETERR_ARGX_LOC (rtx, QSE_AWK_EFUNNF, &((qse_awk_nde_fun_t*)nde)->name, &nde->loc);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun = (qse_awk_fun_t*)QSE_HTB_VPTR(pair);
|
||||||
|
QSE_ASSERT (fun != QSE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = qse_awk_rtx_makefunval(rtx, fun);
|
||||||
|
if (!val) ADJERR_LOC (rtx, &nde->loc);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
static qse_awk_val_t* eval_named (qse_awk_rtx_t* rtx, 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;
|
||||||
|
@ -497,6 +497,14 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case QSE_AWK_NDE_FUN:
|
||||||
|
{
|
||||||
|
PUT_SRCSTRN (awk,
|
||||||
|
((qse_awk_nde_fun_t*)nde)->name.ptr,
|
||||||
|
((qse_awk_nde_fun_t*)nde)->name.len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_ARG:
|
case QSE_AWK_NDE_ARG:
|
||||||
{
|
{
|
||||||
qse_char_t tmp[QSE_SIZEOF(qse_awk_int_t)*8+2];
|
qse_char_t tmp[QSE_SIZEOF(qse_awk_int_t)*8+2];
|
||||||
@ -710,7 +718,7 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_FNC:
|
case QSE_AWK_NDE_FNCALL_FNC:
|
||||||
{
|
{
|
||||||
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
||||||
PUT_SRCSTRN (awk, px->u.fnc.info.name.ptr, px->u.fnc.info.name.len);
|
PUT_SRCSTRN (awk, px->u.fnc.info.name.ptr, px->u.fnc.info.name.len);
|
||||||
@ -720,7 +728,7 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_FUN:
|
case QSE_AWK_NDE_FNCALL_FUN:
|
||||||
{
|
{
|
||||||
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
||||||
PUT_SRCSTRN (awk, px->u.fun.name.ptr, px->u.fun.name.len);
|
PUT_SRCSTRN (awk, px->u.fun.name.ptr, px->u.fun.name.len);
|
||||||
@ -730,10 +738,10 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_FCV:
|
case QSE_AWK_NDE_FNCALL_VAR:
|
||||||
{
|
{
|
||||||
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
||||||
PRINT_EXPR (awk, (qse_awk_nde_t*)px->u.fcv.var);
|
PRINT_EXPR (awk, (qse_awk_nde_t*)px->u.var.var);
|
||||||
PUT_SRCSTR (awk, QSE_T("("));
|
PUT_SRCSTR (awk, QSE_T("("));
|
||||||
PRINT_EXPR_LIST (awk, px->args);
|
PRINT_EXPR_LIST (awk, px->args);
|
||||||
PUT_SRCSTR (awk, QSE_T(")"));
|
PUT_SRCSTR (awk, QSE_T(")"));
|
||||||
@ -1402,6 +1410,13 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case QSE_AWK_NDE_FUN:
|
||||||
|
{
|
||||||
|
QSE_AWK_FREE (awk, ((qse_awk_nde_fun_t*)p)->name.ptr);
|
||||||
|
QSE_AWK_FREE (awk, p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_NAMED:
|
case QSE_AWK_NDE_NAMED:
|
||||||
case QSE_AWK_NDE_GBL:
|
case QSE_AWK_NDE_GBL:
|
||||||
case QSE_AWK_NDE_LCL:
|
case QSE_AWK_NDE_LCL:
|
||||||
@ -1434,7 +1449,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_FNC:
|
case QSE_AWK_NDE_FNCALL_FNC:
|
||||||
{
|
{
|
||||||
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
||||||
/* QSE_AWK_FREE (awk, px->u.fnc); */
|
/* QSE_AWK_FREE (awk, px->u.fnc); */
|
||||||
@ -1444,7 +1459,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_FUN:
|
case QSE_AWK_NDE_FNCALL_FUN:
|
||||||
{
|
{
|
||||||
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
||||||
QSE_AWK_FREE (awk, px->u.fun.name.ptr);
|
QSE_AWK_FREE (awk, px->u.fun.name.ptr);
|
||||||
@ -1453,10 +1468,10 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_AWK_NDE_FCV:
|
case QSE_AWK_NDE_FNCALL_VAR:
|
||||||
{
|
{
|
||||||
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
||||||
qse_awk_clrpt (awk, px->u.fcv.var);
|
qse_awk_clrpt (awk, (qse_awk_nde_t*)px->u.var.var);
|
||||||
qse_awk_clrpt (awk, px->args);
|
qse_awk_clrpt (awk, px->args);
|
||||||
QSE_AWK_FREE (awk, p);
|
QSE_AWK_FREE (awk, p);
|
||||||
break;
|
break;
|
||||||
|
@ -59,10 +59,11 @@ typedef struct qse_awk_nde_pos_t qse_awk_nde_pos_t;
|
|||||||
|
|
||||||
typedef struct qse_awk_nde_int_t qse_awk_nde_int_t;
|
typedef struct qse_awk_nde_int_t qse_awk_nde_int_t;
|
||||||
typedef struct qse_awk_nde_flt_t qse_awk_nde_flt_t;
|
typedef struct qse_awk_nde_flt_t qse_awk_nde_flt_t;
|
||||||
|
|
||||||
typedef struct qse_awk_nde_str_t qse_awk_nde_str_t;
|
typedef struct qse_awk_nde_str_t qse_awk_nde_str_t;
|
||||||
typedef struct qse_awk_nde_mbs_t qse_awk_nde_mbs_t;
|
typedef struct qse_awk_nde_mbs_t qse_awk_nde_mbs_t;
|
||||||
typedef struct qse_awk_nde_rex_t qse_awk_nde_rex_t;
|
typedef struct qse_awk_nde_rex_t qse_awk_nde_rex_t;
|
||||||
|
typedef struct qse_awk_nde_fun_t qse_awk_nde_fun_t;
|
||||||
|
|
||||||
typedef struct qse_awk_nde_var_t qse_awk_nde_var_t;
|
typedef struct qse_awk_nde_var_t qse_awk_nde_var_t;
|
||||||
typedef struct qse_awk_nde_fncall_t qse_awk_nde_fncall_t;
|
typedef struct qse_awk_nde_fncall_t qse_awk_nde_fncall_t;
|
||||||
typedef struct qse_awk_nde_getline_t qse_awk_nde_getline_t;
|
typedef struct qse_awk_nde_getline_t qse_awk_nde_getline_t;
|
||||||
@ -173,6 +174,14 @@ struct qse_awk_nde_rex_t
|
|||||||
void* code[2]; /* [0]: case sensitive, [1]: case insensitive */
|
void* code[2]; /* [0]: case sensitive, [1]: case insensitive */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* QSE_AWK_NDE_FUN - function as a value */
|
||||||
|
struct qse_awk_nde_fun_t
|
||||||
|
{
|
||||||
|
QSE_AWK_NDE_HDR;
|
||||||
|
qse_cstr_t name; /* function name */
|
||||||
|
qse_awk_fun_t* ptr; /* QSE_NULL or actual pointer */
|
||||||
|
};
|
||||||
|
|
||||||
/* QSE_AWK_NDE_NAMED, QSE_AWK_NDE_GBL,
|
/* QSE_AWK_NDE_NAMED, QSE_AWK_NDE_GBL,
|
||||||
* QSE_AWK_NDE_LCL, QSE_AWK_NDE_ARG
|
* QSE_AWK_NDE_LCL, QSE_AWK_NDE_ARG
|
||||||
* QSE_AWK_NDE_NAMEDIDX, QSE_AWK_NDE_GBLIDX,
|
* QSE_AWK_NDE_NAMEDIDX, QSE_AWK_NDE_GBLIDX,
|
||||||
@ -188,7 +197,7 @@ struct qse_awk_nde_var_t
|
|||||||
qse_awk_nde_t* idx; /* QSE_NULL for non-XXXXIDX */
|
qse_awk_nde_t* idx; /* QSE_NULL for non-XXXXIDX */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* QSE_AWK_NDE_FNC, QSE_AWK_NDE_FUN */
|
/* QSE_AWK_NDE_FNCALL_FNC, QSE_AWK_NDE_FNCALL_FUN, QSE_AWK_NDE_FNCALL_VAR */
|
||||||
struct qse_awk_nde_fncall_t
|
struct qse_awk_nde_fncall_t
|
||||||
{
|
{
|
||||||
QSE_AWK_NDE_HDR;
|
QSE_AWK_NDE_HDR;
|
||||||
@ -210,7 +219,7 @@ struct qse_awk_nde_fncall_t
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_awk_nde_var_t* var;
|
qse_awk_nde_var_t* var;
|
||||||
} fcv;
|
} var;
|
||||||
} u;
|
} u;
|
||||||
qse_awk_nde_t* args;
|
qse_awk_nde_t* args;
|
||||||
qse_size_t nargs;
|
qse_size_t nargs;
|
||||||
|
@ -402,7 +402,7 @@ qse_awk_val_t* qse_awk_rtx_makembsval (qse_awk_rtx_t* rtx, const qse_mchar_t* pt
|
|||||||
qse_awk_val_mbs_t* val = QSE_NULL;
|
qse_awk_val_mbs_t* val = QSE_NULL;
|
||||||
qse_size_t xsz = len * QSE_SIZEOF(*ptr);
|
qse_size_t xsz = len * QSE_SIZEOF(*ptr);
|
||||||
|
|
||||||
val = (qse_awk_val_mbs_t*)QSE_AWK_ALLOC(rtx->awk, QSE_SIZEOF(qse_awk_val_mbs_t) + xsz + QSE_SIZEOF(*ptr));
|
val = (qse_awk_val_mbs_t*)qse_awk_callocmem(rtx->awk, QSE_SIZEOF(qse_awk_val_mbs_t) + xsz + QSE_SIZEOF(*ptr));
|
||||||
if (val == QSE_NULL)
|
if (val == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
@ -437,7 +437,7 @@ qse_awk_val_t* qse_awk_rtx_makerexval (qse_awk_rtx_t* rtx, const qse_cstr_t* str
|
|||||||
* the total size is just large enough for all these.
|
* the total size is just large enough for all these.
|
||||||
*/
|
*/
|
||||||
totsz = QSE_SIZEOF(*val) + (QSE_SIZEOF(*str->ptr) * (str->len + 1));
|
totsz = QSE_SIZEOF(*val) + (QSE_SIZEOF(*str->ptr) * (str->len + 1));
|
||||||
val = (qse_awk_val_rex_t*) QSE_AWK_ALLOC (rtx->awk, totsz);
|
val = (qse_awk_val_rex_t*)qse_awk_callocmem(rtx->awk, totsz);
|
||||||
if (val == QSE_NULL)
|
if (val == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
@ -702,7 +702,7 @@ qse_awk_val_t* qse_awk_rtx_makerefval (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = (qse_awk_val_ref_t*)QSE_AWK_ALLOC(rtx->awk, QSE_SIZEOF(qse_awk_val_ref_t));
|
val = (qse_awk_val_ref_t*)qse_awk_callocmem(rtx->awk, QSE_SIZEOF(*val));
|
||||||
if (!val)
|
if (!val)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
@ -723,7 +723,7 @@ qse_awk_val_t* qse_awk_rtx_makefunval (qse_awk_rtx_t* rtx, const qse_awk_fun_t*
|
|||||||
{
|
{
|
||||||
qse_awk_val_fun_t* val;
|
qse_awk_val_fun_t* val;
|
||||||
|
|
||||||
val = (qse_awk_val_fun_t*)QSE_AWK_ALLOC(rtx->awk, QSE_SIZEOF(qse_awk_val_fun_t));
|
val = (qse_awk_val_fun_t*)qse_awk_callocmem(rtx->awk, QSE_SIZEOF(*val));
|
||||||
if (!val)
|
if (!val)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
@ -731,6 +731,9 @@ qse_awk_val_t* qse_awk_rtx_makefunval (qse_awk_rtx_t* rtx, const qse_awk_fun_t*
|
|||||||
}
|
}
|
||||||
|
|
||||||
val->v_type = QSE_AWK_VAL_FUN;
|
val->v_type = QSE_AWK_VAL_FUN;
|
||||||
|
val->ref = 0;
|
||||||
|
val->stat = 0;
|
||||||
|
val->nstr = 0;
|
||||||
val->fun = (qse_awk_fun_t*)fun;
|
val->fun = (qse_awk_fun_t*)fun;
|
||||||
|
|
||||||
return (qse_awk_val_t*)val;
|
return (qse_awk_val_t*)val;
|
||||||
@ -869,7 +872,7 @@ void qse_awk_rtx_freeval (qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case QSE_AWK_VAL_FUN:
|
case QSE_AWK_VAL_FUN:
|
||||||
/* nothing to do */
|
QSE_AWK_FREE (rtx->awk, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1468,7 +1471,7 @@ static int val_ref_to_str (qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse
|
|||||||
|
|
||||||
int qse_awk_rtx_valtostr (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_rtx_valtostr_out_t* out)
|
int qse_awk_rtx_valtostr (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_rtx_valtostr_out_t* out)
|
||||||
{
|
{
|
||||||
qse_awk_val_type_t vtype = QSE_AWK_RTX_GETVALTYPE (rtx, v);
|
qse_awk_val_type_t vtype = QSE_AWK_RTX_GETVALTYPE(rtx, v);
|
||||||
|
|
||||||
switch (vtype)
|
switch (vtype)
|
||||||
{
|
{
|
||||||
@ -1519,7 +1522,7 @@ int qse_awk_rtx_valtostr (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_rt
|
|||||||
|
|
||||||
case QSE_AWK_VAL_FUN:
|
case QSE_AWK_VAL_FUN:
|
||||||
{
|
{
|
||||||
return qse_awk_rtx_makestrval2(rtx, QSE_T("@@"), 1, ((qse_awk_val_fun_t*)v)->fun->name.ptr, ((qse_awk_val_fun_t*)v)->fun->name.len);
|
return str_to_str(rtx, ((qse_awk_val_fun_t*)v)->fun->name.ptr, ((qse_awk_val_fun_t*)v)->fun->name.len, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1823,7 +1826,7 @@ int qse_awk_rtx_valtonum (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_in
|
|||||||
|
|
||||||
case QSE_AWK_VAL_FUN:
|
case QSE_AWK_VAL_FUN:
|
||||||
{
|
{
|
||||||
/* TODO: */
|
/* unable to convert a function to a number */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2163,7 +2166,7 @@ void qse_awk_dprintval (qse_awk_rtx_t* run, qse_awk_val_t* val)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_AWK_VAL_FUN:
|
case QSE_AWK_VAL_FUN:
|
||||||
qse_errputstrf (QSE_T("@@%.*s"), (int)((qse_awk_val_fun_t*)val)->fun->name.len, ((qse_awk_val_fun_t*)val)->fun->name.ptr);
|
qse_errputstrf (QSE_T("%.*s"), (int)((qse_awk_val_fun_t*)val)->fun->name.len, ((qse_awk_val_fun_t*)val)->fun->name.ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user