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_INCPST,
|
||||
QSE_AWK_NDE_CND,
|
||||
QSE_AWK_NDE_FNC,
|
||||
QSE_AWK_NDE_FUN,
|
||||
QSE_AWK_NDE_FCV,
|
||||
QSE_AWK_NDE_FNCALL_FNC,
|
||||
QSE_AWK_NDE_FNCALL_FUN,
|
||||
QSE_AWK_NDE_FNCALL_VAR,
|
||||
QSE_AWK_NDE_INT,
|
||||
QSE_AWK_NDE_FLT,
|
||||
QSE_AWK_NDE_STR,
|
||||
QSE_AWK_NDE_MBS,
|
||||
QSE_AWK_NDE_REX,
|
||||
QSE_AWK_NDE_FUN,
|
||||
|
||||
/* keep this order for the following items otherwise, you may have
|
||||
* 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_EARGTM, /**< too many arguments */
|
||||
QSE_AWK_EFUNNF, /**< function '${0}' not found */
|
||||
QSE_AWK_ENOTFUN, /**< non-function value in '%{0}' */
|
||||
QSE_AWK_ENOTDEL, /**< '${0}' not deletable */
|
||||
QSE_AWK_ENOTMAP, /**< value 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_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_LCLS 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 many arguments"),
|
||||
QSE_T("function '${0}' not found"),
|
||||
QSE_T("non-function value in '${0}'"),
|
||||
QSE_T("'${0}' not deletable"),
|
||||
QSE_T("value 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_IN,
|
||||
TOK_EXP,
|
||||
TOK_CONCAT,
|
||||
TOK_CONCAT, /* %% */
|
||||
|
||||
TOK_LPAREN,
|
||||
TOK_RPAREN,
|
||||
@ -111,7 +111,7 @@ enum tok_t
|
||||
TOK_COLON,
|
||||
TOK_DBLCOLON,
|
||||
TOK_QUEST,
|
||||
TOK_DBLAT,
|
||||
/*TOK_DBLAT,*/
|
||||
|
||||
/* == begin 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);
|
||||
|
||||
#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_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() */
|
||||
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)
|
||||
{
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
||||
ADJERR_LOC (awk, &awk->tok.loc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
/* get the next token */
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
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 */
|
||||
SETERR_TOK (awk, QSE_AWK_ELPAREN);
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
/* get the next token */
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
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 */
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
return QSE_NULL;
|
||||
}
|
||||
}
|
||||
@ -1169,7 +1169,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
|
||||
if (!MATCH(awk,TOK_IDENT))
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
SETERR_TOK (awk, QSE_AWK_EBADPAR);
|
||||
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_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);
|
||||
SETERR_ARG_LOC (
|
||||
awk, QSE_AWK_EDUPPAR,
|
||||
@ -1203,18 +1203,15 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
/* push the parameter to the parameter list */
|
||||
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);
|
||||
SETERR_LOC (awk, QSE_AWK_EPARTM, &awk->tok.loc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
if (qse_arr_insert (
|
||||
awk->parse.params,
|
||||
QSE_ARR_SIZE(awk->parse.params),
|
||||
pa, pal) == QSE_ARR_NIL)
|
||||
if (qse_arr_insert(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);
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
||||
return QSE_NULL;
|
||||
@ -1222,7 +1219,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
|
||||
if (get_token (awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -1231,7 +1228,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
|
||||
if (!MATCH(awk,TOK_COMMA))
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
SETERR_TOK (awk, QSE_AWK_ECOMMA);
|
||||
return QSE_NULL;
|
||||
@ -1241,7 +1238,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
{
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -1251,7 +1248,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -1265,7 +1262,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
{
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
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 */
|
||||
if (!MATCH(awk,TOK_LBRACE))
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
|
||||
SETERR_TOK (awk, QSE_AWK_ELBRACE);
|
||||
return QSE_NULL;
|
||||
}
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -1302,7 +1298,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
|
||||
if (body == QSE_NULL)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_arr_clear (awk->parse.params);
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -1316,7 +1312,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
fun = (qse_awk_fun_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*fun));
|
||||
if (fun == QSE_NULL)
|
||||
{
|
||||
QSE_AWK_FREE (awk, name.ptr);
|
||||
qse_awk_freemem (awk, name.ptr);
|
||||
qse_awk_clrpt (awk, body);
|
||||
ADJERR_LOC (awk, &awk->tok.loc);
|
||||
return QSE_NULL;
|
||||
@ -1333,9 +1329,9 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
/* if qse_htb_insert() fails for other reasons than memory
|
||||
* shortage, there should be implementaion errors as duplicate
|
||||
* 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_FREE (awk, fun);
|
||||
qse_awk_freemem (awk, fun);
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->tok.loc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -1344,7 +1340,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
|
||||
* of the pair */
|
||||
fun->name.ptr = QSE_HTB_KPTR(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 */
|
||||
qse_htb_delete (awk->parse.funs, fun->name.ptr, name.len);
|
||||
@ -1419,12 +1415,11 @@ static qse_awk_chain_t* parse_action_block (
|
||||
if (nde == QSE_NULL) return QSE_NULL;
|
||||
}
|
||||
|
||||
chain = (qse_awk_chain_t*)
|
||||
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_chain_t));
|
||||
chain = (qse_awk_chain_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*chain));
|
||||
if (chain == QSE_NULL)
|
||||
{
|
||||
qse_awk_clrpt (awk, nde);
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &xloc);
|
||||
ADJERR_LOC (awk, &xloc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
@ -3052,8 +3047,7 @@ static qse_awk_nde_t* parse_statement_nb (
|
||||
return nde;
|
||||
}
|
||||
|
||||
static qse_awk_nde_t* parse_statement (
|
||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
static qse_awk_nde_t* parse_statement (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
{
|
||||
qse_awk_nde_t* nde;
|
||||
|
||||
@ -3066,11 +3060,10 @@ static qse_awk_nde_t* parse_statement (
|
||||
if (MATCH(awk,TOK_SEMICOLON))
|
||||
{
|
||||
/* null statement */
|
||||
nde = (qse_awk_nde_t*)
|
||||
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_t));
|
||||
if (nde == QSE_NULL)
|
||||
nde = (qse_awk_nde_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
|
||||
if (!nde)
|
||||
{
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||
ADJERR_LOC (awk, xloc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
@ -3080,7 +3073,7 @@ static qse_awk_nde_t* parse_statement (
|
||||
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREE (awk, nde);
|
||||
qse_awk_freemem (awk, nde);
|
||||
return QSE_NULL;
|
||||
}
|
||||
}
|
||||
@ -3150,8 +3143,7 @@ static int assign_to_opcode (qse_awk_t* awk)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static qse_awk_nde_t* parse_expr_basic (
|
||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
static qse_awk_nde_t* parse_expr_basic (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
{
|
||||
qse_awk_nde_t* nde, * n1, * n2;
|
||||
|
||||
@ -3201,14 +3193,13 @@ static qse_awk_nde_t* parse_expr_basic (
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
cnd = (qse_awk_nde_cnd_t*) QSE_AWK_ALLOC (
|
||||
awk, QSE_SIZEOF(qse_awk_nde_cnd_t));
|
||||
cnd = (qse_awk_nde_cnd_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*cnd));
|
||||
if (cnd == QSE_NULL)
|
||||
{
|
||||
qse_awk_clrpt (awk, nde);
|
||||
qse_awk_clrpt (awk, n1);
|
||||
qse_awk_clrpt (awk, n2);
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||
ADJERR_LOC (awk, xloc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
@ -3225,8 +3216,7 @@ static qse_awk_nde_t* parse_expr_basic (
|
||||
return nde;
|
||||
}
|
||||
|
||||
static qse_awk_nde_t* parse_expr (
|
||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
static qse_awk_nde_t* parse_expr (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
{
|
||||
qse_awk_nde_t* x, * y;
|
||||
qse_awk_nde_ass_t* nde;
|
||||
@ -3258,7 +3248,6 @@ static qse_awk_nde_t* parse_expr (
|
||||
|
||||
{
|
||||
qse_awk_loc_t eloc;
|
||||
|
||||
eloc = awk->tok.loc;
|
||||
y = parse_expr_withdc (awk, &eloc);
|
||||
}
|
||||
@ -3268,14 +3257,12 @@ static qse_awk_nde_t* parse_expr (
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
nde = (qse_awk_nde_ass_t*)
|
||||
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_ass_t));
|
||||
nde = (qse_awk_nde_ass_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
|
||||
if (nde == QSE_NULL)
|
||||
{
|
||||
qse_awk_clrpt (awk, x);
|
||||
qse_awk_clrpt (awk, y);
|
||||
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||
ADJERR_LOC (awk, xloc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
@ -3289,8 +3276,7 @@ static qse_awk_nde_t* parse_expr (
|
||||
return (qse_awk_nde_t*)nde;
|
||||
}
|
||||
|
||||
static qse_awk_nde_t* parse_expr_withdc (
|
||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
static qse_awk_nde_t* parse_expr_withdc (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
{
|
||||
qse_awk_nde_t* nde;
|
||||
|
||||
@ -4306,7 +4292,6 @@ static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_cstr_t* name)
|
||||
return isfunname(awk, name);
|
||||
}
|
||||
|
||||
|
||||
static qse_awk_nde_t* parse_primary_int (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||
{
|
||||
qse_awk_nde_int_t* nde;
|
||||
@ -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;
|
||||
}
|
||||
else if (MATCH(awk,TOK_LOR) &&
|
||||
(awk->opt.trait & QSE_AWK_RWPIPE))
|
||||
else if (MATCH(awk,TOK_LOR) && (awk->opt.trait & QSE_AWK_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 (preget_token(awk) <= -1) goto oops;
|
||||
|
||||
if (awk->ntok.type != TOK_GETLINE) break;
|
||||
|
||||
/* 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 */
|
||||
if (get_token(awk) <= -1) goto oops;
|
||||
@ -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)
|
||||
{
|
||||
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) &&
|
||||
(!(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;
|
||||
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
|
||||
* 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->idx = QSE_NULL;
|
||||
|
||||
if (!fcv) return (qse_awk_nde_t*)nde;
|
||||
return parse_fncall(awk, (const qse_cstr_t*)nde, QSE_NULL, xloc, FNCALL_FLAG_FCV);
|
||||
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||
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)
|
||||
@ -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);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||
ADJERR_LOC (awk, xloc);
|
||||
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;
|
||||
|
||||
oops:
|
||||
while (nsegs > 0) QSE_AWK_FREE (awk, name[--nsegs].ptr);
|
||||
while (nsegs > 0) qse_awk_freemem (awk, name[--nsegs].ptr);
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
/* 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);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
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
|
||||
* is not allowed.
|
||||
*/
|
||||
int is_fncall_var = 0;
|
||||
|
||||
if (MATCH(awk,TOK_LPAREN) &&
|
||||
(!(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)))
|
||||
{
|
||||
/* it is a function call to an undefined function yet */
|
||||
|
||||
if (qse_htb_search(awk->parse.named, name->ptr, name->len) != QSE_NULL)
|
||||
{
|
||||
/* 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);
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
|
||||
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
|
||||
named_var:
|
||||
#endif
|
||||
|
||||
/* if there is a space between the name and the left parenthesis
|
||||
* while the name is not resolved to anything, we treat the space
|
||||
* as concatention by blanks. so we handle the name as a named
|
||||
@ -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.idxa = (qse_size_t)-1;
|
||||
tmp->idx = QSE_NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
qse_awk_nde_t* nde = QSE_NULL;
|
||||
qse_cstr_t name[2]; /* TODO: support more than 2 segments??? */
|
||||
@ -5231,7 +5259,7 @@ static qse_awk_nde_t* parse_primary_ident (
|
||||
if (nsegs <= 1)
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -5253,11 +5281,11 @@ static qse_awk_nde_t* parse_primary_ident (
|
||||
full.len = capa;
|
||||
|
||||
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
|
||||
* 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
|
||||
@ -5267,7 +5295,7 @@ static qse_awk_nde_t* parse_primary_ident (
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@ -5414,7 +5442,7 @@ static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, con
|
||||
|
||||
exit_func:
|
||||
qse_awk_clrpt (awk, idx);
|
||||
QSE_AWK_FREE (awk, nde);
|
||||
qse_awk_freemem (awk, nde);
|
||||
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -5482,17 +5510,17 @@ make_node:
|
||||
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->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->nargs = nargs;
|
||||
}
|
||||
else if (fnc)
|
||||
{
|
||||
call->type = QSE_AWK_NDE_FNC;
|
||||
call->type = QSE_AWK_NDE_FNCALL_FNC;
|
||||
call->loc = *xloc;
|
||||
|
||||
call->u.fnc.info.name.ptr = name->ptr;
|
||||
@ -5516,7 +5544,7 @@ make_node:
|
||||
}
|
||||
else
|
||||
{
|
||||
call->type = QSE_AWK_NDE_FUN;
|
||||
call->type = QSE_AWK_NDE_FNCALL_FUN;
|
||||
call->loc = *xloc;
|
||||
call->u.fun.name.ptr = name->ptr;
|
||||
call->u.fun.name.len = name->len;
|
||||
@ -5534,7 +5562,7 @@ make_node:
|
||||
return (qse_awk_nde_t*)call;
|
||||
|
||||
oops:
|
||||
if (call) QSE_AWK_FREE (awk, call);
|
||||
if (call) qse_awk_freemem (awk, call);
|
||||
if (head) qse_awk_clrpt (awk, head);
|
||||
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_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,
|
||||
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_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_fnc (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_fncall_var (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
|
||||
|
||||
static qse_awk_val_t* __eval_call (
|
||||
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_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_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_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);
|
||||
@ -1630,7 +1631,7 @@ qse_awk_val_t* qse_awk_rtx_callfun (
|
||||
|
||||
/* forge a fake node containing a function 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.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_incpst,
|
||||
eval_cnd,
|
||||
eval_fnc,
|
||||
eval_fun,
|
||||
eval_fcv,
|
||||
eval_fncall_fnc,
|
||||
eval_fncall_fncall_fun,
|
||||
eval_fncall_var,
|
||||
eval_int,
|
||||
eval_flt,
|
||||
eval_str,
|
||||
eval_mbs,
|
||||
eval_rex,
|
||||
eval_fun,
|
||||
eval_named,
|
||||
eval_gbl,
|
||||
eval_lcl,
|
||||
@ -3350,8 +3352,7 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||
|
||||
qse_awk_val_t* v;
|
||||
|
||||
QSE_ASSERT (nde->type >= QSE_AWK_NDE_GRP &&
|
||||
(nde->type - QSE_AWK_NDE_GRP) < QSE_COUNTOF(__evaluator));
|
||||
QSE_ASSERT (nde->type >= QSE_AWK_NDE_GRP && (nde->type - QSE_AWK_NDE_GRP) < QSE_COUNTOF(__evaluator));
|
||||
|
||||
v = __evaluator[nde->type-QSE_AWK_NDE_GRP](run, nde);
|
||||
|
||||
@ -5602,7 +5603,7 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
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_fun_t* fun;
|
||||
@ -5639,24 +5640,23 @@ 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);
|
||||
}
|
||||
|
||||
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_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;
|
||||
|
||||
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");*/
|
||||
SETERR_ARGX_LOC (rtx, QSE_AWK_ENOTFUN, &call->u.var.var->id.name, &nde->loc);
|
||||
rv = QSE_NULL;
|
||||
}
|
||||
else
|
||||
@ -6002,8 +6002,7 @@ static qse_size_t push_arg_from_nde (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* c
|
||||
v = qse_awk_rtx_makerefval (
|
||||
rtx, p->type-QSE_AWK_NDE_NAMED, ref);
|
||||
}
|
||||
else if (fnc_arg_spec &&
|
||||
fnc_arg_spec[nargs] == QSE_T('x'))
|
||||
else if (fnc_arg_spec && fnc_arg_spec[nargs] == QSE_T('x'))
|
||||
{
|
||||
/* a regular expression is passed to
|
||||
* the function as it is */
|
||||
@ -6014,7 +6013,7 @@ static qse_size_t push_arg_from_nde (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* c
|
||||
v = eval_expression(rtx, p);
|
||||
}
|
||||
|
||||
if (v == QSE_NULL)
|
||||
if (!v)
|
||||
{
|
||||
UNWIND_RTX_STACK_ARG (rtx, nargs);
|
||||
return (qse_size_t)-1;
|
||||
@ -6264,6 +6263,32 @@ static qse_awk_val_t* eval_rex (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||
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)
|
||||
{
|
||||
qse_htb_pair_t* pair;
|
||||
|
@ -497,6 +497,14 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
||||
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:
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_FNC:
|
||||
case QSE_AWK_NDE_FNCALL_FNC:
|
||||
{
|
||||
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);
|
||||
@ -720,7 +728,7 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_FUN:
|
||||
case QSE_AWK_NDE_FNCALL_FUN:
|
||||
{
|
||||
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);
|
||||
@ -730,10 +738,10 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_AWK_NDE_FCV:
|
||||
case QSE_AWK_NDE_FNCALL_VAR:
|
||||
{
|
||||
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("("));
|
||||
PRINT_EXPR_LIST (awk, px->args);
|
||||
PUT_SRCSTR (awk, QSE_T(")"));
|
||||
@ -1402,6 +1410,13 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
||||
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_GBL:
|
||||
case QSE_AWK_NDE_LCL:
|
||||
@ -1434,7 +1449,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
||||
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_FREE (awk, px->u.fnc); */
|
||||
@ -1444,7 +1459,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
||||
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_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;
|
||||
}
|
||||
|
||||
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_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_FREE (awk, p);
|
||||
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_flt_t qse_awk_nde_flt_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_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_fncall_t qse_awk_nde_fncall_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 */
|
||||
};
|
||||
|
||||
/* 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_LCL, QSE_AWK_NDE_ARG
|
||||
* 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_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
|
||||
{
|
||||
QSE_AWK_NDE_HDR;
|
||||
@ -210,7 +219,7 @@ struct qse_awk_nde_fncall_t
|
||||
struct
|
||||
{
|
||||
qse_awk_nde_var_t* var;
|
||||
} fcv;
|
||||
} var;
|
||||
} u;
|
||||
qse_awk_nde_t* args;
|
||||
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_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)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||
@ -702,7 +702,7 @@ qse_awk_val_t* qse_awk_rtx_makerefval (
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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->ref = 0;
|
||||
val->stat = 0;
|
||||
val->nstr = 0;
|
||||
val->fun = (qse_awk_fun_t*)fun;
|
||||
|
||||
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:
|
||||
/* nothing to do */
|
||||
QSE_AWK_FREE (rtx->awk, val);
|
||||
break;
|
||||
|
||||
}
|
||||
@ -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:
|
||||
{
|
||||
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:
|
||||
{
|
||||
/* TODO: */
|
||||
/* unable to convert a function to a number */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2163,7 +2166,7 @@ void qse_awk_dprintval (qse_awk_rtx_t* run, qse_awk_val_t* val)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user