enhanced parse_primary_ident() in lib/awk/parse.c
also fixed a memory leak in the function changed name of some data types
This commit is contained in:
parent
6364077743
commit
ed207769ff
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.h 480 2011-05-25 14:00:19Z hyunghwan.chung $
|
* $Id: awk.h 485 2011-05-29 15:15:52Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -1050,6 +1050,7 @@ enum qse_awk_val_type_t
|
|||||||
|
|
||||||
QSE_AWK_VAL_REX = 4, /**< regular expression */
|
QSE_AWK_VAL_REX = 4, /**< regular expression */
|
||||||
QSE_AWK_VAL_MAP = 5, /**< map */
|
QSE_AWK_VAL_MAP = 5, /**< map */
|
||||||
|
|
||||||
QSE_AWK_VAL_REF = 6 /**< reference to other types */
|
QSE_AWK_VAL_REF = 6 /**< reference to other types */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: parse.c 475 2011-05-23 17:02:35Z hyunghwan.chung $
|
* $Id: parse.c 485 2011-05-29 15:15:52Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -554,18 +554,21 @@ static int parse (qse_awk_t* awk)
|
|||||||
if (qse_htb_search (awk->tree.funs,
|
if (qse_htb_search (awk->tree.funs,
|
||||||
QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
|
QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* call;
|
|
||||||
|
qse_awk_nde_t* nde;
|
||||||
|
|
||||||
/* see parse_fncall() for what is
|
/* see parse_fncall() for what is
|
||||||
* stored into awk->tree.funs */
|
* stored into awk->tree.funs */
|
||||||
call = (qse_awk_nde_call_t*)QSE_HTB_VPTR(p);
|
nde = (qse_awk_nde_t*)QSE_HTB_VPTR(p);
|
||||||
|
|
||||||
SETERR_ARG_LOC (
|
SETERR_ARG_LOC (
|
||||||
awk,
|
awk,
|
||||||
QSE_AWK_EFUNNF,
|
QSE_AWK_EFUNNF,
|
||||||
QSE_HTB_KPTR(p),
|
QSE_HTB_KPTR(p),
|
||||||
QSE_HTB_KLEN(p),
|
QSE_HTB_KLEN(p),
|
||||||
&call->loc
|
&nde->loc
|
||||||
);
|
);
|
||||||
|
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4365,15 +4368,13 @@ static qse_awk_nde_t* parse_primary (
|
|||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isfnname (qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
|
#define FNTYPE_UNKNOWN 0
|
||||||
{
|
#define FNTYPE_FNC 1
|
||||||
if (qse_awk_getfnc (awk, name, len) != QSE_NULL)
|
#define FNTYPE_FUN 2
|
||||||
{
|
|
||||||
/* implicit function */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if it is an awk function */
|
static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
|
||||||
|
{
|
||||||
|
/* check if it is an awk function being processed currently */
|
||||||
if (awk->tree.cur_fun.ptr != QSE_NULL)
|
if (awk->tree.cur_fun.ptr != QSE_NULL)
|
||||||
{
|
{
|
||||||
if (qse_strxncmp (
|
if (qse_strxncmp (
|
||||||
@ -4381,28 +4382,87 @@ static int isfnname (qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
|
|||||||
name, len) == 0)
|
name, len) == 0)
|
||||||
{
|
{
|
||||||
/* the current function begin parsed */
|
/* the current function begin parsed */
|
||||||
return 2;
|
return FNTYPE_FUN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check the funtion name in the function table */
|
||||||
if (qse_htb_search (awk->tree.funs, name, len) != QSE_NULL)
|
if (qse_htb_search (awk->tree.funs, name, len) != QSE_NULL)
|
||||||
{
|
{
|
||||||
/* one of the functions defined previously */
|
/* one of the functions defined previously */
|
||||||
return 2;
|
return FNTYPE_FUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if it is a function not resolved so far */
|
||||||
if (qse_htb_search (awk->parse.funs, name, len) != QSE_NULL)
|
if (qse_htb_search (awk->parse.funs, name, len) != QSE_NULL)
|
||||||
{
|
{
|
||||||
/* one of the function calls not resolved so far. */
|
/* one of the function calls not resolved so far. */
|
||||||
return 2;
|
return FNTYPE_FUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return FNTYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
|
||||||
|
{
|
||||||
|
if (qse_awk_getfnc (awk, name, len) != QSE_NULL)
|
||||||
|
{
|
||||||
|
/* implicit function */
|
||||||
|
return FNTYPE_FNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isfunname (awk, name, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static qse_awk_nde_t* parse_variable (
|
||||||
|
qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_awk_nde_type_t type,
|
||||||
|
qse_char_t* nameptr, qse_size_t namelen, qse_size_t idxa)
|
||||||
|
{
|
||||||
|
qse_awk_nde_var_t* nde;
|
||||||
|
|
||||||
|
if ((awk->option & QSE_AWK_EXPLICIT) &&
|
||||||
|
!(awk->option & QSE_AWK_IMPLICIT))
|
||||||
|
{
|
||||||
|
/* if explicit only, the concatenation operator(.)
|
||||||
|
* must be used. so it is obvious that it is a function
|
||||||
|
* call, which is illegal for a variable.
|
||||||
|
* if implicit, "var_xxx (1)" may be concatenation of
|
||||||
|
* the value of var_xxx and 1.
|
||||||
|
*/
|
||||||
|
if (MATCH(awk,TOK_LPAREN))
|
||||||
|
{
|
||||||
|
/* a variable is not a function */
|
||||||
|
SETERR_ARG_LOC (
|
||||||
|
awk, QSE_AWK_EFUNNAM,
|
||||||
|
nameptr, namelen, xloc);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC (
|
||||||
|
awk, QSE_SIZEOF(qse_awk_nde_var_t));
|
||||||
|
if (nde == QSE_NULL)
|
||||||
|
{
|
||||||
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nde->type = type;
|
||||||
|
nde->loc = *xloc;
|
||||||
|
nde->next = QSE_NULL;
|
||||||
|
/*nde->id.name.ptr = QSE_NULL;*/
|
||||||
|
nde->id.name.ptr = nameptr;
|
||||||
|
nde->id.name.len = namelen;
|
||||||
|
nde->id.idxa = idxa;
|
||||||
|
nde->idx = QSE_NULL;
|
||||||
|
|
||||||
|
return (qse_awk_nde_t*)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_char_t* namedup;
|
qse_char_t* namedup;
|
||||||
qse_size_t namelen;
|
qse_size_t namelen;
|
||||||
qse_awk_fnc_t* fnc;
|
qse_awk_fnc_t* fnc;
|
||||||
@ -4430,9 +4490,11 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
fnc = qse_awk_getfnc (awk, namedup, namelen);
|
fnc = qse_awk_getfnc (awk, namedup, namelen);
|
||||||
if (fnc != QSE_NULL)
|
if (fnc != QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* nde;
|
if (MATCH(awk,TOK_LPAREN))
|
||||||
|
{
|
||||||
if (!MATCH(awk,TOK_LPAREN))
|
nde = parse_fncall (awk, namedup, namelen, fnc, xloc, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (fnc->dfl0)
|
if (fnc->dfl0)
|
||||||
{
|
{
|
||||||
@ -4440,241 +4502,107 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
* when () is missing. i.e. length */
|
* when () is missing. i.e. length */
|
||||||
nde = parse_fncall (
|
nde = parse_fncall (
|
||||||
awk, namedup, namelen, fnc, xloc, 1);
|
awk, namedup, namelen, fnc, xloc, 1);
|
||||||
if (nde == QSE_NULL)
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
return (qse_awk_nde_t*)nde;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* an intrinsic function should be in the form
|
/* an intrinsic function should be in the form
|
||||||
* of the function call */
|
* of the function call */
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
SETERR_TOK (awk, QSE_AWK_ELPAREN);
|
SETERR_TOK (awk, QSE_AWK_ELPAREN);
|
||||||
return QSE_NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nde = parse_fncall (awk, namedup, namelen, fnc, xloc, 0);
|
|
||||||
if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup);
|
|
||||||
return (qse_awk_nde_t*)nde;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* now we know that namedup is a normal identifier. */
|
/* now we know that namedup is a normal identifier. */
|
||||||
if (MATCH(awk,TOK_LBRACK))
|
else if (MATCH(awk,TOK_LBRACK))
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* nde;
|
|
||||||
nde = parse_hashidx (awk, namedup, namelen, xloc);
|
nde = parse_hashidx (awk, namedup, namelen, xloc);
|
||||||
if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup);
|
|
||||||
return (qse_awk_nde_t*)nde;
|
|
||||||
}
|
}
|
||||||
else if ((idxa = qse_lda_rsearch (awk->parse.lcls, QSE_LDA_SIZE(awk->parse.lcls), namedup, namelen)) != QSE_LDA_NIL)
|
else if ((idxa = qse_lda_rsearch (awk->parse.lcls, QSE_LDA_SIZE(awk->parse.lcls), namedup, namelen)) != QSE_LDA_NIL)
|
||||||
{
|
{
|
||||||
/* local variable */
|
/* local variable */
|
||||||
|
nde = parse_variable (
|
||||||
qse_awk_nde_var_t* nde;
|
awk, xloc, QSE_AWK_NDE_LCL,
|
||||||
|
namedup, namelen, idxa);
|
||||||
if ((awk->option & QSE_AWK_EXPLICIT) &&
|
|
||||||
!(awk->option & QSE_AWK_IMPLICIT))
|
|
||||||
{
|
|
||||||
/* if explicit only, the concatenation operator(.)
|
|
||||||
* must be used. so it is obvious that it is a function
|
|
||||||
* call, which is illegal for a local variable.
|
|
||||||
* if implicit, "local_var (1)" may be concatenation of
|
|
||||||
* the value of local_var and 1.
|
|
||||||
*/
|
|
||||||
if (MATCH(awk,TOK_LPAREN))
|
|
||||||
{
|
|
||||||
/* a local variable is not a function */
|
|
||||||
SETERR_ARG_LOC (
|
|
||||||
awk, QSE_AWK_EFUNNAM,
|
|
||||||
namedup, namelen, xloc);
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC (
|
|
||||||
awk, QSE_SIZEOF(qse_awk_nde_var_t));
|
|
||||||
if (nde == QSE_NULL)
|
|
||||||
{
|
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nde->type = QSE_AWK_NDE_LCL;
|
|
||||||
nde->loc = *xloc;
|
|
||||||
nde->next = QSE_NULL;
|
|
||||||
/*nde->id.name.ptr = QSE_NULL;*/
|
|
||||||
nde->id.name.ptr = namedup;
|
|
||||||
nde->id.name.len = namelen;
|
|
||||||
nde->id.idxa = idxa;
|
|
||||||
nde->idx = QSE_NULL;
|
|
||||||
|
|
||||||
return (qse_awk_nde_t*)nde;
|
|
||||||
}
|
}
|
||||||
else if ((idxa = qse_lda_search (awk->parse.params, 0, namedup, namelen)) != QSE_LDA_NIL)
|
else if ((idxa = qse_lda_search (awk->parse.params, 0, namedup, namelen)) != QSE_LDA_NIL)
|
||||||
{
|
{
|
||||||
/* parameter */
|
/* parameter */
|
||||||
|
nde = parse_variable (
|
||||||
qse_awk_nde_var_t* nde;
|
awk, xloc, QSE_AWK_NDE_ARG,
|
||||||
|
namedup, namelen, idxa);
|
||||||
if ((awk->option & QSE_AWK_EXPLICIT) &&
|
|
||||||
!(awk->option & QSE_AWK_IMPLICIT))
|
|
||||||
{
|
|
||||||
if (MATCH(awk,TOK_LPAREN))
|
|
||||||
{
|
|
||||||
/* a parameter is not a function */
|
|
||||||
SETERR_ARG_LOC (
|
|
||||||
awk, QSE_AWK_EFUNNAM,
|
|
||||||
namedup, namelen, xloc);
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC (
|
|
||||||
awk, QSE_SIZEOF(qse_awk_nde_var_t));
|
|
||||||
if (nde == QSE_NULL)
|
|
||||||
{
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nde->type = QSE_AWK_NDE_ARG;
|
|
||||||
nde->loc = *xloc;
|
|
||||||
nde->next = QSE_NULL;
|
|
||||||
/*nde->id.name = QSE_NULL;*/
|
|
||||||
nde->id.name.ptr = namedup;
|
|
||||||
nde->id.name.len = namelen;
|
|
||||||
nde->id.idxa = idxa;
|
|
||||||
nde->idx = QSE_NULL;
|
|
||||||
|
|
||||||
return (qse_awk_nde_t*)nde;
|
|
||||||
}
|
}
|
||||||
else if ((idxa = get_global (awk, namedup, namelen)) != QSE_LDA_NIL)
|
else if ((idxa = get_global (awk, namedup, namelen)) != QSE_LDA_NIL)
|
||||||
{
|
{
|
||||||
/* global variable */
|
/* global variable */
|
||||||
|
nde = parse_variable (
|
||||||
qse_awk_nde_var_t* nde;
|
awk, xloc, QSE_AWK_NDE_GBL,
|
||||||
|
namedup, namelen, idxa);
|
||||||
if ((awk->option & QSE_AWK_EXPLICIT) &&
|
}
|
||||||
!(awk->option & QSE_AWK_IMPLICIT))
|
else
|
||||||
{
|
{
|
||||||
|
int fntype = isfunname (awk, namedup, namelen);
|
||||||
|
|
||||||
|
if (fntype)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (fntype == FNTYPE_FUN);
|
||||||
|
|
||||||
if (MATCH(awk,TOK_LPAREN))
|
if (MATCH(awk,TOK_LPAREN))
|
||||||
{
|
{
|
||||||
/* a global variable is not a function */
|
|
||||||
SETERR_ARG_LOC (
|
|
||||||
awk, QSE_AWK_EFUNNAM,
|
|
||||||
namedup, namelen, xloc);
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC (
|
|
||||||
awk, QSE_SIZEOF(qse_awk_nde_var_t));
|
|
||||||
if (nde == QSE_NULL)
|
|
||||||
{
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nde->type = QSE_AWK_NDE_GBL;
|
|
||||||
nde->loc = *xloc;
|
|
||||||
nde->next = QSE_NULL;
|
|
||||||
/*nde->id.name = QSE_NULL;*/
|
|
||||||
nde->id.name.ptr = namedup;
|
|
||||||
nde->id.name.len = namelen;
|
|
||||||
nde->id.idxa = idxa;
|
|
||||||
nde->idx = QSE_NULL;
|
|
||||||
|
|
||||||
return (qse_awk_nde_t*)nde;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int fnname = isfnname (awk, namedup, namelen);
|
|
||||||
|
|
||||||
if (fnname)
|
|
||||||
{
|
|
||||||
qse_awk_nde_t* nde;
|
|
||||||
|
|
||||||
if (!MATCH(awk,TOK_LPAREN))
|
|
||||||
{
|
|
||||||
/* function named appeared without () */
|
|
||||||
if (fnname == 1)
|
|
||||||
{
|
|
||||||
SETERR_ARG_LOC (
|
|
||||||
awk, QSE_AWK_EFNCRED,
|
|
||||||
namedup, namelen, xloc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SETERR_ARG_LOC (
|
|
||||||
awk, QSE_AWK_EFUNRED,
|
|
||||||
namedup, namelen, xloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* must be a function name */
|
/* must be a function name */
|
||||||
QSE_ASSERT (qse_htb_search (
|
QSE_ASSERT (qse_htb_search (
|
||||||
awk->parse.named, namedup, namelen) == QSE_NULL);
|
awk->parse.named, namedup, namelen) == QSE_NULL);
|
||||||
|
|
||||||
nde = parse_fncall (
|
nde = parse_fncall (
|
||||||
awk, namedup, namelen, QSE_NULL, xloc, 0);
|
awk, namedup, namelen, QSE_NULL, xloc, 0);
|
||||||
if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup);
|
}
|
||||||
return (qse_awk_nde_t*)nde;
|
else
|
||||||
|
{
|
||||||
|
/* function name appeared without () or ` */
|
||||||
|
SETERR_ARG_LOC (
|
||||||
|
awk, QSE_AWK_EFUNRED,
|
||||||
|
namedup, namelen, xloc
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (awk->option & QSE_AWK_IMPLICIT)
|
else if (awk->option & QSE_AWK_IMPLICIT)
|
||||||
{
|
{
|
||||||
|
/* if the name is followed by ( or ` without no spaces
|
||||||
|
* in the implicit mode, the name is considered a function
|
||||||
|
* name though it has not been seen/resolved */
|
||||||
|
|
||||||
if (MATCH(awk,TOK_LPAREN) &&
|
if (MATCH(awk,TOK_LPAREN) &&
|
||||||
awk->tok.loc.line == xloc->line &&
|
awk->tok.loc.line == xloc->line &&
|
||||||
awk->tok.loc.colm == xloc->colm + namelen)
|
awk->tok.loc.colm == xloc->colm + namelen)
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* nde;
|
|
||||||
|
|
||||||
/* a function call to a yet undefined function */
|
/* a function call to a yet undefined function */
|
||||||
if (qse_htb_search (awk->parse.named,
|
|
||||||
namedup, namelen) != QSE_NULL)
|
if (qse_htb_search (
|
||||||
|
awk->parse.named, namedup, namelen) != QSE_NULL)
|
||||||
{
|
{
|
||||||
/* a function call conflicts with a named variable */
|
/* a function call conflicts with a named variable */
|
||||||
SETERR_ARG_LOC (
|
SETERR_ARG_LOC (
|
||||||
awk, QSE_AWK_EVARRED,
|
awk, QSE_AWK_EVARRED,
|
||||||
namedup, namelen, xloc);
|
namedup, namelen, xloc
|
||||||
QSE_AWK_FREE (awk, namedup);
|
);
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nde = parse_fncall (
|
|
||||||
awk, namedup, namelen, QSE_NULL, xloc, 0);
|
|
||||||
if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup);
|
|
||||||
return (qse_awk_nde_t*)nde;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_awk_nde_var_t* nde;
|
nde = parse_fncall (
|
||||||
|
awk, namedup, namelen, QSE_NULL, xloc, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qse_awk_nde_var_t* tmp;
|
||||||
|
|
||||||
/* named variable */
|
/* named variable */
|
||||||
nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC (
|
tmp = (qse_awk_nde_var_t*) QSE_AWK_ALLOC (
|
||||||
awk, QSE_SIZEOF(qse_awk_nde_var_t));
|
awk, QSE_SIZEOF(qse_awk_nde_var_t));
|
||||||
if (nde == QSE_NULL)
|
if (tmp == QSE_NULL)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
return QSE_NULL;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
nde->type = QSE_AWK_NDE_NAMED;
|
{
|
||||||
nde->loc = *xloc;
|
|
||||||
nde->next = QSE_NULL;
|
|
||||||
nde->id.name.ptr = namedup;
|
|
||||||
nde->id.name.len = namelen;
|
|
||||||
nde->id.idxa = (qse_size_t)-1;
|
|
||||||
nde->idx = QSE_NULL;
|
|
||||||
|
|
||||||
/* collect unique instances of a named variable
|
/* collect unique instances of a named variable
|
||||||
* for reference */
|
* for reference */
|
||||||
if (qse_htb_upsert (
|
if (qse_htb_upsert (
|
||||||
@ -4682,11 +4610,21 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
namedup, namelen, QSE_NULL, 0) == QSE_NULL)
|
namedup, namelen, QSE_NULL, 0) == QSE_NULL)
|
||||||
{
|
{
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
QSE_AWK_FREE (awk, nde);
|
QSE_AWK_FREE (awk, tmp);
|
||||||
return QSE_NULL;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp->type = QSE_AWK_NDE_NAMED;
|
||||||
|
tmp->loc = *xloc;
|
||||||
|
tmp->next = QSE_NULL;
|
||||||
|
tmp->id.name.ptr = namedup;
|
||||||
|
tmp->id.name.len = namelen;
|
||||||
|
tmp->id.idxa = (qse_size_t)-1;
|
||||||
|
tmp->idx = QSE_NULL;
|
||||||
|
|
||||||
return (qse_awk_nde_t*)nde;
|
nde = (qse_awk_nde_t*)tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4695,19 +4633,21 @@ static qse_awk_nde_t* parse_primary_ident (
|
|||||||
{
|
{
|
||||||
/* it is a function call as the name is followed
|
/* it is a function call as the name is followed
|
||||||
* by ( and implicit variables are disabled. */
|
* by ( and implicit variables are disabled. */
|
||||||
qse_awk_nde_t* nde;
|
|
||||||
nde = parse_fncall (
|
nde = parse_fncall (
|
||||||
awk, namedup, namelen, QSE_NULL, xloc, 0);
|
awk, namedup, namelen, QSE_NULL, xloc, 0);
|
||||||
if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup);
|
}
|
||||||
return (qse_awk_nde_t*)nde;
|
else
|
||||||
|
{
|
||||||
|
/* undefined variable */
|
||||||
|
SETERR_ARG_LOC (
|
||||||
|
awk, QSE_AWK_EUNDEF, namedup, namelen, xloc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* undefined variable */
|
if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup);
|
||||||
SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, namedup, namelen, xloc);
|
return nde;
|
||||||
QSE_AWK_FREE (awk, namedup);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_hashidx (
|
static qse_awk_nde_t* parse_hashidx (
|
||||||
@ -4832,14 +4772,14 @@ static qse_awk_nde_t* parse_hashidx (
|
|||||||
if (awk->option & QSE_AWK_IMPLICIT)
|
if (awk->option & QSE_AWK_IMPLICIT)
|
||||||
{
|
{
|
||||||
int fnname = isfnname (awk, name, namelen);
|
int fnname = isfnname (awk, name, namelen);
|
||||||
if (fnname == 1)
|
switch (fnname)
|
||||||
{
|
{
|
||||||
|
case FNTYPE_FNC:
|
||||||
SETERR_ARG_LOC (
|
SETERR_ARG_LOC (
|
||||||
awk, QSE_AWK_EFNCRED, name, namelen, xloc);
|
awk, QSE_AWK_EFNCRED, name, namelen, xloc);
|
||||||
goto exit_func;
|
goto exit_func;
|
||||||
}
|
|
||||||
else if (fnname == 2)
|
case FNTYPE_FUN:
|
||||||
{
|
|
||||||
SETERR_ARG_LOC (
|
SETERR_ARG_LOC (
|
||||||
awk, QSE_AWK_EFUNRED, name, namelen, xloc);
|
awk, QSE_AWK_EFUNRED, name, namelen, xloc);
|
||||||
goto exit_func;
|
goto exit_func;
|
||||||
@ -4873,7 +4813,7 @@ static qse_awk_nde_t* parse_fncall (
|
|||||||
qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg)
|
qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg)
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* head, * curr, * nde;
|
qse_awk_nde_t* head, * curr, * nde;
|
||||||
qse_awk_nde_call_t* call;
|
qse_awk_nde_fncall_t* call;
|
||||||
qse_size_t nargs;
|
qse_size_t nargs;
|
||||||
|
|
||||||
head = curr = QSE_NULL;
|
head = curr = QSE_NULL;
|
||||||
@ -4943,8 +4883,8 @@ static qse_awk_nde_t* parse_fncall (
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_node:
|
make_node:
|
||||||
call = (qse_awk_nde_call_t*)
|
call = (qse_awk_nde_fncall_t*)
|
||||||
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_call_t));
|
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_fncall_t));
|
||||||
if (call == QSE_NULL)
|
if (call == QSE_NULL)
|
||||||
{
|
{
|
||||||
if (head != QSE_NULL) qse_awk_clrpt (awk, head);
|
if (head != QSE_NULL) qse_awk_clrpt (awk, head);
|
||||||
@ -4958,22 +4898,13 @@ make_node:
|
|||||||
call->loc = *xloc;
|
call->loc = *xloc;
|
||||||
call->next = QSE_NULL;
|
call->next = QSE_NULL;
|
||||||
|
|
||||||
/*call->what.fnc = fnc; */
|
/*call->u.fnc = fnc; */
|
||||||
call->what.fnc.name.ptr = name;
|
call->u.fnc.name.ptr = name;
|
||||||
call->what.fnc.name.len = namelen;
|
call->u.fnc.name.len = namelen;
|
||||||
|
call->u.fnc.arg.min = fnc->arg.min;
|
||||||
/* NOTE: oname is the original as in the fnc table.
|
call->u.fnc.arg.max = fnc->arg.max;
|
||||||
* it would not duplicated here and not freed in
|
call->u.fnc.arg.spec = fnc->arg.spec;
|
||||||
* qse_awk_clrpt either. so qse_awk_delfnc between
|
call->u.fnc.handler = fnc->handler;
|
||||||
* qse_awk_parse and qse_awk_run may cause the program
|
|
||||||
* to fail. */
|
|
||||||
call->what.fnc.oname.ptr = fnc->name.ptr;
|
|
||||||
call->what.fnc.oname.len = fnc->name.len;
|
|
||||||
|
|
||||||
call->what.fnc.arg.min = fnc->arg.min;
|
|
||||||
call->what.fnc.arg.max = fnc->arg.max;
|
|
||||||
call->what.fnc.arg.spec = fnc->arg.spec;
|
|
||||||
call->what.fnc.handler = fnc->handler;
|
|
||||||
|
|
||||||
call->args = head;
|
call->args = head;
|
||||||
call->nargs = nargs;
|
call->nargs = nargs;
|
||||||
@ -4983,8 +4914,8 @@ make_node:
|
|||||||
call->type = QSE_AWK_NDE_FUN;
|
call->type = QSE_AWK_NDE_FUN;
|
||||||
call->loc = *xloc;
|
call->loc = *xloc;
|
||||||
call->next = QSE_NULL;
|
call->next = QSE_NULL;
|
||||||
call->what.fun.name.ptr = name;
|
call->u.fun.name.ptr = name;
|
||||||
call->what.fun.name.len = namelen;
|
call->u.fun.name.len = namelen;
|
||||||
call->args = head;
|
call->args = head;
|
||||||
call->nargs = nargs;
|
call->nargs = nargs;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: run.c 480 2011-05-25 14:00:19Z hyunghwan.chung $
|
* $Id: run.c 485 2011-05-29 15:15:52Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -95,7 +95,7 @@ struct pafv
|
|||||||
#define ADJERR_LOC(rtx,l) do { (rtx)->errinf.loc = *(l); } while (0)
|
#define ADJERR_LOC(rtx,l) do { (rtx)->errinf.loc = *(l); } while (0)
|
||||||
|
|
||||||
static qse_size_t push_arg_from_vals (
|
static qse_size_t push_arg_from_vals (
|
||||||
qse_awk_rtx_t* rtx, qse_awk_nde_call_t* call, void* data);
|
qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data);
|
||||||
|
|
||||||
static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio);
|
static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio);
|
||||||
static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals);
|
static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals);
|
||||||
@ -212,7 +212,7 @@ static qse_awk_val_t* __eval_call (
|
|||||||
qse_awk_nde_t* nde,
|
qse_awk_nde_t* nde,
|
||||||
const qse_char_t* fnc_arg_spec,
|
const qse_char_t* fnc_arg_spec,
|
||||||
qse_awk_fun_t* fun,
|
qse_awk_fun_t* fun,
|
||||||
qse_size_t(*argpusher)(qse_awk_rtx_t*,qse_awk_nde_call_t*,void*),
|
qse_size_t(*argpusher)(qse_awk_rtx_t*,qse_awk_nde_fncall_t*,void*),
|
||||||
void* apdata,
|
void* apdata,
|
||||||
void(*errhandler)(void*),
|
void(*errhandler)(void*),
|
||||||
void* eharg);
|
void* eharg);
|
||||||
@ -1542,7 +1542,7 @@ qse_awk_val_t* qse_awk_rtx_callfun (
|
|||||||
struct capture_retval_data_t crdata;
|
struct capture_retval_data_t crdata;
|
||||||
qse_awk_val_t* v;
|
qse_awk_val_t* v;
|
||||||
struct pafv pafv/*= { args, nargs }*/;
|
struct pafv pafv/*= { args, nargs }*/;
|
||||||
qse_awk_nde_call_t call;
|
qse_awk_nde_fncall_t call;
|
||||||
|
|
||||||
QSE_ASSERT (fun != QSE_NULL);
|
QSE_ASSERT (fun != QSE_NULL);
|
||||||
|
|
||||||
@ -1561,7 +1561,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_FUN;
|
||||||
call.what.fun.name = fun->name;
|
call.u.fun.name = fun->name;
|
||||||
call.nargs = nargs;
|
call.nargs = nargs;
|
||||||
|
|
||||||
/* check if the number of arguments given is more than expected */
|
/* check if the number of arguments given is more than expected */
|
||||||
@ -2561,15 +2561,8 @@ static int delete_indexed (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
|
static int run_delete_named (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var)
|
||||||
{
|
{
|
||||||
qse_awk_nde_var_t* var;
|
|
||||||
|
|
||||||
var = (qse_awk_nde_var_t*) nde->var;
|
|
||||||
|
|
||||||
if (var->type == QSE_AWK_NDE_NAMED ||
|
|
||||||
var->type == QSE_AWK_NDE_NAMEDIDX)
|
|
||||||
{
|
|
||||||
qse_htb_pair_t* pair;
|
qse_htb_pair_t* pair;
|
||||||
|
|
||||||
QSE_ASSERTX (
|
QSE_ASSERTX (
|
||||||
@ -2590,7 +2583,7 @@ static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
|
|||||||
if (tmp == QSE_NULL)
|
if (tmp == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* adjust error line */
|
/* adjust error line */
|
||||||
ADJERR_LOC (rtx, &nde->loc);
|
ADJERR_LOC (rtx, &var->loc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2637,14 +2630,12 @@ static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
|
|||||||
qse_htb_clear (map);
|
qse_htb_clear (map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (var->type == QSE_AWK_NDE_GBL ||
|
return 0;
|
||||||
var->type == QSE_AWK_NDE_LCL ||
|
}
|
||||||
var->type == QSE_AWK_NDE_ARG ||
|
|
||||||
var->type == QSE_AWK_NDE_GBLIDX ||
|
static int run_delete_nonnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var)
|
||||||
var->type == QSE_AWK_NDE_LCLIDX ||
|
{
|
||||||
var->type == QSE_AWK_NDE_ARGIDX)
|
|
||||||
{
|
|
||||||
qse_awk_val_t* val;
|
qse_awk_val_t* val;
|
||||||
|
|
||||||
if (var->type == QSE_AWK_NDE_GBL ||
|
if (var->type == QSE_AWK_NDE_GBL ||
|
||||||
@ -2667,7 +2658,7 @@ static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
|
|||||||
tmp = qse_awk_rtx_makemapval (rtx);
|
tmp = qse_awk_rtx_makemapval (rtx);
|
||||||
if (tmp == QSE_NULL)
|
if (tmp == QSE_NULL)
|
||||||
{
|
{
|
||||||
ADJERR_LOC (rtx, &nde->loc);
|
ADJERR_LOC (rtx, &var->loc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2724,18 +2715,38 @@ static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
|
|||||||
qse_htb_clear (map);
|
qse_htb_clear (map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
|
||||||
|
{
|
||||||
|
qse_awk_nde_var_t* var;
|
||||||
|
|
||||||
|
var = (qse_awk_nde_var_t*) nde->var;
|
||||||
|
|
||||||
|
switch (var->type)
|
||||||
{
|
{
|
||||||
|
case QSE_AWK_NDE_NAMED:
|
||||||
|
case QSE_AWK_NDE_NAMEDIDX:
|
||||||
|
return run_delete_named (rtx, var);
|
||||||
|
|
||||||
|
case QSE_AWK_NDE_GBL:
|
||||||
|
case QSE_AWK_NDE_LCL:
|
||||||
|
case QSE_AWK_NDE_ARG:
|
||||||
|
case QSE_AWK_NDE_GBLIDX:
|
||||||
|
case QSE_AWK_NDE_LCLIDX:
|
||||||
|
case QSE_AWK_NDE_ARGIDX:
|
||||||
|
return run_delete_nonnamed (rtx, var);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QSE_ASSERTX (
|
QSE_ASSERTX (
|
||||||
!"should never happen - wrong target for delete",
|
!"should never happen - wrong target for delete",
|
||||||
"the delete statement cannot be called with other nodes than the variables such as a named variable, a named indexed variable, etc");
|
"the delete statement cannot be called with other nodes than the variables such as a named variable, a named indexed variable, etc");
|
||||||
|
|
||||||
SETERR_LOC (rtx, QSE_AWK_ERDELETE, &var->loc);
|
SETERR_LOC (rtx, QSE_AWK_ERDELETE, &var->loc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_reset (qse_awk_rtx_t* rtx, qse_awk_nde_reset_t* nde)
|
static int run_reset (qse_awk_rtx_t* rtx, qse_awk_nde_reset_t* nde)
|
||||||
@ -3376,16 +3387,21 @@ static qse_awk_val_t* do_assignment_scalar (
|
|||||||
qse_awk_rtx_t* run, qse_awk_nde_var_t* var, qse_awk_val_t* val)
|
qse_awk_rtx_t* run, qse_awk_nde_var_t* var, qse_awk_val_t* val)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (
|
QSE_ASSERT (
|
||||||
(var->type == QSE_AWK_NDE_NAMED ||
|
var->type == QSE_AWK_NDE_NAMED ||
|
||||||
var->type == QSE_AWK_NDE_GBL ||
|
var->type == QSE_AWK_NDE_GBL ||
|
||||||
var->type == QSE_AWK_NDE_LCL ||
|
var->type == QSE_AWK_NDE_LCL ||
|
||||||
var->type == QSE_AWK_NDE_ARG) && var->idx == QSE_NULL);
|
var->type == QSE_AWK_NDE_ARG
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_ASSERT (var->idx == QSE_NULL);
|
||||||
|
|
||||||
QSE_ASSERT (
|
QSE_ASSERT (
|
||||||
(run->awk->option & QSE_AWK_MAPTOVAR) ||
|
(run->awk->option & QSE_AWK_MAPTOVAR) ||
|
||||||
val->type != QSE_AWK_VAL_MAP);
|
val->type != QSE_AWK_VAL_MAP);
|
||||||
|
|
||||||
if (var->type == QSE_AWK_NDE_NAMED)
|
switch (var->type)
|
||||||
|
{
|
||||||
|
case QSE_AWK_NDE_NAMED:
|
||||||
{
|
{
|
||||||
qse_htb_pair_t* pair;
|
qse_htb_pair_t* pair;
|
||||||
|
|
||||||
@ -3410,16 +3426,20 @@ static qse_awk_val_t* do_assignment_scalar (
|
|||||||
}
|
}
|
||||||
|
|
||||||
qse_awk_rtx_refupval (run, val);
|
qse_awk_rtx_refupval (run, val);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (var->type == QSE_AWK_NDE_GBL)
|
|
||||||
|
case QSE_AWK_NDE_GBL:
|
||||||
{
|
{
|
||||||
if (set_global (run, var->id.idxa, var, val) == -1)
|
if (set_global (run, var->id.idxa, var, val) == -1)
|
||||||
{
|
{
|
||||||
ADJERR_LOC (run, &var->loc);
|
ADJERR_LOC (run, &var->loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (var->type == QSE_AWK_NDE_LCL)
|
|
||||||
|
case QSE_AWK_NDE_LCL:
|
||||||
{
|
{
|
||||||
qse_awk_val_t* old = STACK_LCL(run,var->id.idxa);
|
qse_awk_val_t* old = STACK_LCL(run,var->id.idxa);
|
||||||
if (old->type == QSE_AWK_VAL_MAP)
|
if (old->type == QSE_AWK_VAL_MAP)
|
||||||
@ -3435,8 +3455,10 @@ static qse_awk_val_t* do_assignment_scalar (
|
|||||||
qse_awk_rtx_refdownval (run, old);
|
qse_awk_rtx_refdownval (run, old);
|
||||||
STACK_LCL(run,var->id.idxa) = val;
|
STACK_LCL(run,var->id.idxa) = val;
|
||||||
qse_awk_rtx_refupval (run, val);
|
qse_awk_rtx_refupval (run, val);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else /* if (var->type == QSE_AWK_NDE_ARG) */
|
|
||||||
|
case QSE_AWK_NDE_ARG:
|
||||||
{
|
{
|
||||||
qse_awk_val_t* old = STACK_ARG(run,var->id.idxa);
|
qse_awk_val_t* old = STACK_ARG(run,var->id.idxa);
|
||||||
if (old->type == QSE_AWK_VAL_MAP)
|
if (old->type == QSE_AWK_VAL_MAP)
|
||||||
@ -3452,6 +3474,9 @@ static qse_awk_val_t* do_assignment_scalar (
|
|||||||
qse_awk_rtx_refdownval (run, old);
|
qse_awk_rtx_refdownval (run, old);
|
||||||
STACK_ARG(run,var->id.idxa) = val;
|
STACK_ARG(run,var->id.idxa) = val;
|
||||||
qse_awk_rtx_refupval (run, val);
|
qse_awk_rtx_refupval (run, val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
@ -5412,23 +5437,23 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
|
|
||||||
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* call = (qse_awk_nde_call_t*)nde;
|
qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
|
||||||
|
|
||||||
/* intrinsic function */
|
/* intrinsic function */
|
||||||
if (call->nargs < call->what.fnc.arg.min)
|
if (call->nargs < call->u.fnc.arg.min)
|
||||||
{
|
{
|
||||||
SETERR_LOC (run, QSE_AWK_EARGTF, &nde->loc);
|
SETERR_LOC (run, QSE_AWK_EARGTF, &nde->loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->nargs > call->what.fnc.arg.max)
|
if (call->nargs > call->u.fnc.arg.max)
|
||||||
{
|
{
|
||||||
SETERR_LOC (run, QSE_AWK_EARGTM, &nde->loc);
|
SETERR_LOC (run, QSE_AWK_EARGTM, &nde->loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return eval_call (
|
return eval_call (
|
||||||
run, nde, call->what.fnc.arg.spec,
|
run, nde, call->u.fnc.arg.spec,
|
||||||
QSE_NULL, QSE_NULL, QSE_NULL);
|
QSE_NULL, QSE_NULL, QSE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5436,17 +5461,17 @@ static qse_awk_val_t* eval_fun_ex (
|
|||||||
qse_awk_rtx_t* rtx, qse_awk_nde_t* nde,
|
qse_awk_rtx_t* rtx, qse_awk_nde_t* nde,
|
||||||
void(*errhandler)(void*), void* eharg)
|
void(*errhandler)(void*), void* eharg)
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* call = (qse_awk_nde_call_t*)nde;
|
qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
|
||||||
qse_awk_fun_t* fun;
|
qse_awk_fun_t* fun;
|
||||||
qse_htb_pair_t* pair;
|
qse_htb_pair_t* pair;
|
||||||
|
|
||||||
pair = qse_htb_search (rtx->awk->tree.funs,
|
pair = qse_htb_search (rtx->awk->tree.funs,
|
||||||
call->what.fun.name.ptr, call->what.fun.name.len);
|
call->u.fun.name.ptr, call->u.fun.name.len);
|
||||||
if (pair == QSE_NULL)
|
if (pair == QSE_NULL)
|
||||||
{
|
{
|
||||||
SETERR_ARGX_LOC (
|
SETERR_ARGX_LOC (
|
||||||
rtx, QSE_AWK_EFUNNF,
|
rtx, QSE_AWK_EFUNNF,
|
||||||
xstr_to_cstr(&call->what.fun.name), &nde->loc);
|
xstr_to_cstr(&call->u.fun.name), &nde->loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5501,12 +5526,12 @@ static qse_awk_val_t* __eval_call (
|
|||||||
qse_awk_nde_t* nde,
|
qse_awk_nde_t* nde,
|
||||||
const qse_char_t* fnc_arg_spec,
|
const qse_char_t* fnc_arg_spec,
|
||||||
qse_awk_fun_t* fun,
|
qse_awk_fun_t* fun,
|
||||||
qse_size_t(*argpusher)(qse_awk_rtx_t*,qse_awk_nde_call_t*,void*),
|
qse_size_t(*argpusher)(qse_awk_rtx_t*,qse_awk_nde_fncall_t*,void*),
|
||||||
void* apdata,
|
void* apdata,
|
||||||
void(*errhandler)(void*),
|
void(*errhandler)(void*),
|
||||||
void* eharg)
|
void* eharg)
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* call = (qse_awk_nde_call_t*)nde;
|
qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
|
||||||
qse_size_t saved_stack_top;
|
qse_size_t saved_stack_top;
|
||||||
qse_size_t nargs, i;
|
qse_size_t nargs, i;
|
||||||
qse_awk_val_t* v;
|
qse_awk_val_t* v;
|
||||||
@ -5640,19 +5665,16 @@ static qse_awk_val_t* __eval_call (
|
|||||||
|
|
||||||
/* intrinsic function */
|
/* intrinsic function */
|
||||||
QSE_ASSERT (
|
QSE_ASSERT (
|
||||||
call->nargs >= call->what.fnc.arg.min &&
|
call->nargs >= call->u.fnc.arg.min &&
|
||||||
call->nargs <= call->what.fnc.arg.max);
|
call->nargs <= call->u.fnc.arg.max);
|
||||||
|
|
||||||
if (call->what.fnc.handler != QSE_NULL)
|
if (call->u.fnc.handler != QSE_NULL)
|
||||||
{
|
{
|
||||||
run->errinf.num = QSE_AWK_ENOERR;
|
run->errinf.num = QSE_AWK_ENOERR;
|
||||||
|
|
||||||
/* NOTE: oname is used when the handler is invoked.
|
n = call->u.fnc.handler (
|
||||||
* name might be differnt from oname if
|
|
||||||
* qse_awk_setword has been used */
|
|
||||||
n = call->what.fnc.handler (
|
|
||||||
run,
|
run,
|
||||||
xstr_to_cstr(&call->what.fnc.oname)
|
xstr_to_cstr(&call->u.fnc.name)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
@ -5663,7 +5685,7 @@ static qse_awk_val_t* __eval_call (
|
|||||||
* fix it */
|
* fix it */
|
||||||
SETERR_ARGX_LOC (
|
SETERR_ARGX_LOC (
|
||||||
run, QSE_AWK_EFNCIMPL,
|
run, QSE_AWK_EFNCIMPL,
|
||||||
xstr_to_cstr(&call->what.fnc.oname),
|
xstr_to_cstr(&call->u.fnc.name),
|
||||||
&nde->loc
|
&nde->loc
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -5751,7 +5773,7 @@ static qse_awk_val_t* __eval_call (
|
|||||||
}
|
}
|
||||||
|
|
||||||
static qse_size_t push_arg_from_vals (
|
static qse_size_t push_arg_from_vals (
|
||||||
qse_awk_rtx_t* rtx, qse_awk_nde_call_t* call, void* data)
|
qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
|
||||||
{
|
{
|
||||||
struct pafv* pafv = (struct pafv*)data;
|
struct pafv* pafv = (struct pafv*)data;
|
||||||
qse_size_t nargs = 0;
|
qse_size_t nargs = 0;
|
||||||
@ -5780,7 +5802,7 @@ static qse_size_t push_arg_from_vals (
|
|||||||
}
|
}
|
||||||
|
|
||||||
static qse_size_t push_arg_from_nde (
|
static qse_size_t push_arg_from_nde (
|
||||||
qse_awk_rtx_t* rtx, qse_awk_nde_call_t* call, void* data)
|
qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* p;
|
qse_awk_nde_t* p;
|
||||||
qse_awk_val_t* v;
|
qse_awk_val_t* v;
|
||||||
@ -6120,9 +6142,11 @@ static qse_awk_val_t* eval_named (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
{
|
{
|
||||||
qse_htb_pair_t* pair;
|
qse_htb_pair_t* pair;
|
||||||
|
|
||||||
pair = qse_htb_search (run->named,
|
pair = qse_htb_search (
|
||||||
|
run->named,
|
||||||
((qse_awk_nde_var_t*)nde)->id.name.ptr,
|
((qse_awk_nde_var_t*)nde)->id.name.ptr,
|
||||||
((qse_awk_nde_var_t*)nde)->id.name.len);
|
((qse_awk_nde_var_t*)nde)->id.name.len
|
||||||
|
);
|
||||||
|
|
||||||
return (pair == QSE_NULL)? qse_awk_val_nil: QSE_HTB_VPTR(pair);
|
return (pair == QSE_NULL)? qse_awk_val_nil: QSE_HTB_VPTR(pair);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: tree.c 474 2011-05-23 16:52:37Z hyunghwan.chung $
|
* $Id: tree.c 485 2011-05-29 15:15:52Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -540,9 +540,9 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
|||||||
|
|
||||||
case QSE_AWK_NDE_FNC:
|
case QSE_AWK_NDE_FNC:
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* px = (qse_awk_nde_call_t*)nde;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
||||||
PUT_SRCSTRX (awk,
|
PUT_SRCSTRX (awk,
|
||||||
px->what.fnc.name.ptr, px->what.fnc.name.len);
|
px->u.fnc.name.ptr, px->u.fnc.name.len);
|
||||||
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(")"));
|
||||||
@ -551,9 +551,9 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
|||||||
|
|
||||||
case QSE_AWK_NDE_FUN:
|
case QSE_AWK_NDE_FUN:
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* px = (qse_awk_nde_call_t*)nde;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
|
||||||
PUT_SRCSTRX (awk,
|
PUT_SRCSTRX (awk,
|
||||||
px->what.fun.name.ptr, px->what.fun.name.len);
|
px->u.fun.name.ptr, px->u.fun.name.len);
|
||||||
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(")"));
|
||||||
@ -1276,9 +1276,9 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
|||||||
|
|
||||||
case QSE_AWK_NDE_FNC:
|
case QSE_AWK_NDE_FNC:
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* px = (qse_awk_nde_call_t*)p;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
||||||
/* QSE_AWK_FREE (awk, px->what.fnc); */
|
/* QSE_AWK_FREE (awk, px->u.fnc); */
|
||||||
QSE_AWK_FREE (awk, px->what.fnc.name.ptr);
|
QSE_AWK_FREE (awk, px->u.fnc.name.ptr);
|
||||||
qse_awk_clrpt (awk, px->args);
|
qse_awk_clrpt (awk, px->args);
|
||||||
QSE_AWK_FREE (awk, p);
|
QSE_AWK_FREE (awk, p);
|
||||||
break;
|
break;
|
||||||
@ -1286,8 +1286,8 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
|
|||||||
|
|
||||||
case QSE_AWK_NDE_FUN:
|
case QSE_AWK_NDE_FUN:
|
||||||
{
|
{
|
||||||
qse_awk_nde_call_t* px = (qse_awk_nde_call_t*)p;
|
qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
|
||||||
QSE_AWK_FREE (awk, px->what.fun.name.ptr);
|
QSE_AWK_FREE (awk, px->u.fun.name.ptr);
|
||||||
qse_awk_clrpt (awk, px->args);
|
qse_awk_clrpt (awk, px->args);
|
||||||
QSE_AWK_FREE (awk, p);
|
QSE_AWK_FREE (awk, p);
|
||||||
break;
|
break;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: tree.h 473 2011-05-23 03:38:03Z hyunghwan.chung $
|
* $Id: tree.h 485 2011-05-29 15:15:52Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -57,7 +57,7 @@ typedef struct qse_awk_nde_real_t qse_awk_nde_real_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_rex_t qse_awk_nde_rex_t;
|
typedef struct qse_awk_nde_rex_t qse_awk_nde_rex_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_call_t qse_awk_nde_call_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;
|
||||||
|
|
||||||
typedef struct qse_awk_nde_if_t qse_awk_nde_if_t;
|
typedef struct qse_awk_nde_if_t qse_awk_nde_if_t;
|
||||||
@ -175,7 +175,7 @@ struct qse_awk_nde_var_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* QSE_AWK_NDE_FNC, QSE_AWK_NDE_FUN */
|
/* QSE_AWK_NDE_FNC, QSE_AWK_NDE_FUN */
|
||||||
struct qse_awk_nde_call_t
|
struct qse_awk_nde_fncall_t
|
||||||
{
|
{
|
||||||
QSE_AWK_NDE_HDR;
|
QSE_AWK_NDE_HDR;
|
||||||
union
|
union
|
||||||
@ -191,10 +191,6 @@ struct qse_awk_nde_call_t
|
|||||||
{
|
{
|
||||||
qse_xstr_t name;
|
qse_xstr_t name;
|
||||||
|
|
||||||
/* original name. if qse_awk_setword has been
|
|
||||||
* invoked, oname can be different from name */
|
|
||||||
qse_xstr_t oname;
|
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_size_t min;
|
qse_size_t min;
|
||||||
@ -204,7 +200,7 @@ struct qse_awk_nde_call_t
|
|||||||
|
|
||||||
qse_awk_fnc_fun_t handler;
|
qse_awk_fnc_fun_t handler;
|
||||||
} fnc;
|
} fnc;
|
||||||
} what;
|
} u;
|
||||||
qse_awk_nde_t* args;
|
qse_awk_nde_t* args;
|
||||||
qse_size_t nargs;
|
qse_size_t nargs;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user