added experimental code to call function held in a variable
This commit is contained in:
		@ -598,12 +598,27 @@ can't confict with named variables and globals variables.
 | 
			
		||||
 Built-in Functions
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
- close
 | 
			
		||||
- fflush
 | 
			
		||||
- int
 | 
			
		||||
- typename
 | 
			
		||||
- isnil
 | 
			
		||||
- index
 | 
			
		||||
- length
 | 
			
		||||
- substr
 | 
			
		||||
- split
 | 
			
		||||
- tolower
 | 
			
		||||
- toupper
 | 
			
		||||
- gsub
 | 
			
		||||
- sub
 | 
			
		||||
- match
 | 
			
		||||
- sprintf
 | 
			
		||||
- mktime
 | 
			
		||||
- strftime
 | 
			
		||||
- systime
 | 
			
		||||
 | 
			
		||||
TBD.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 Function Calls
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -152,7 +152,7 @@ typedef qse_floc_t qse_awk_loc_t;
 | 
			
		||||
 */
 | 
			
		||||
struct qse_awk_val_t
 | 
			
		||||
{
 | 
			
		||||
	QSE_AWK_VAL_HDR;	
 | 
			
		||||
	QSE_AWK_VAL_HDR;
 | 
			
		||||
};
 | 
			
		||||
typedef struct qse_awk_val_t qse_awk_val_t;
 | 
			
		||||
 | 
			
		||||
@ -369,6 +369,7 @@ enum qse_awk_nde_type_t
 | 
			
		||||
	QSE_AWK_NDE_CND,
 | 
			
		||||
	QSE_AWK_NDE_FNC,
 | 
			
		||||
	QSE_AWK_NDE_FUN,
 | 
			
		||||
	QSE_AWK_NDE_FCV,
 | 
			
		||||
	QSE_AWK_NDE_INT,
 | 
			
		||||
	QSE_AWK_NDE_FLT,
 | 
			
		||||
	QSE_AWK_NDE_STR,
 | 
			
		||||
 | 
			
		||||
@ -59,23 +59,23 @@ static qse_awk_fnc_t sysfnctab[] =
 | 
			
		||||
 | 
			
		||||
	/* type info/conversion */
 | 
			
		||||
	{ {QSE_T("int"),      3}, 0, { {1,     1, QSE_NULL},       fnc_int,              0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("isnil"),    5}, 0, { {1,     1, QSE_NULL},       fnc_isnil,            0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("typename"), 8}, 0, { {1,     1, QSE_NULL},       fnc_typename,         0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("isnil"),    5}, 0, { {1,     1, QSE_NULL},       fnc_isnil,         0 }, QSE_NULL},
 | 
			
		||||
 | 
			
		||||
	/* array sort */
 | 
			
		||||
	{ {QSE_T("asort"),    5}, 0, { {1,     3, QSE_NULL},       fnc_asort,            0 }, QSE_NULL},
 | 
			
		||||
 
 | 
			
		||||
	/* string functions */
 | 
			
		||||
	{ {QSE_T("gsub"),     4}, 0, { {2,     3, QSE_T("xvr")},  qse_awk_fnc_gsub,     0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("index"),    5}, 0, { {2,     3, QSE_NULL},      qse_awk_fnc_index,    0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("substr"),   6}, 0, { {2,     3, QSE_NULL},      qse_awk_fnc_substr,   0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("length"),   6}, 1, { {0,     1, QSE_NULL},      qse_awk_fnc_length,   0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("match"),    5}, 0, { {2,     4, QSE_T("vxvr")}, qse_awk_fnc_match,    0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("split"),    5}, 0, { {2,     3, QSE_T("vrx")},  qse_awk_fnc_split,    0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("sprintf"),  7}, 0, { {1, A_MAX, QSE_NULL},      qse_awk_fnc_sprintf,  0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("sub"),      3}, 0, { {2,     3, QSE_T("xvr")},  qse_awk_fnc_sub,      0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("substr"),   6}, 0, { {2,     3, QSE_NULL},      qse_awk_fnc_substr,   0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("tolower"),  7}, 0, { {1,     1, QSE_NULL},      qse_awk_fnc_tolower,  0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("toupper"),  7}, 0, { {1,     1, QSE_NULL},      qse_awk_fnc_toupper,  0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("gsub"),     4}, 0, { {2,     3, QSE_T("xvr")},  qse_awk_fnc_gsub,     0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("sub"),      3}, 0, { {2,     3, QSE_T("xvr")},  qse_awk_fnc_sub,      0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("match"),    5}, 0, { {2,     4, QSE_T("vxvr")}, qse_awk_fnc_match,    0 }, QSE_NULL},
 | 
			
		||||
	{ {QSE_T("sprintf"),  7}, 0, { {1, A_MAX, QSE_NULL},      qse_awk_fnc_sprintf,  0 }, QSE_NULL},
 | 
			
		||||
 | 
			
		||||
	/* math functions */
 | 
			
		||||
	{ {QSE_T("sin"),      3}, 0, { {A_MAX, 0, QSE_T("math") },   QSE_NULL,         0 }, QSE_NULL},
 | 
			
		||||
 | 
			
		||||
@ -111,6 +111,7 @@ enum tok_t
 | 
			
		||||
	TOK_COLON,
 | 
			
		||||
	TOK_DBLCOLON,
 | 
			
		||||
	TOK_QUEST,
 | 
			
		||||
	TOK_DBLAT,
 | 
			
		||||
 | 
			
		||||
	/* ==  begin reserved words == */
 | 
			
		||||
	/* === extended reserved words === */
 | 
			
		||||
@ -219,9 +220,11 @@ static qse_awk_nde_t* parse_unary_exp (qse_awk_t* awk, const qse_awk_loc_t* xloc
 | 
			
		||||
static qse_awk_nde_t* parse_increment (qse_awk_t* awk, const qse_awk_loc_t* xloc);
 | 
			
		||||
static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc);
 | 
			
		||||
static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, const qse_awk_loc_t* xloc);
 | 
			
		||||
 | 
			
		||||
static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc);
 | 
			
		||||
static qse_awk_nde_t* parse_fncall (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg);
 | 
			
		||||
 | 
			
		||||
#define FNCALL_FLAG_NOARG (1 << 0) /* no argument */
 | 
			
		||||
#define FNCALL_FLAG_FCV   (1 << 1)
 | 
			
		||||
static qse_awk_nde_t* parse_fncall (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int flags);
 | 
			
		||||
 | 
			
		||||
static qse_awk_nde_t* parse_primary_ident_segs (qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* full, const qse_cstr_t segs[], int nsegs);
 | 
			
		||||
 | 
			
		||||
@ -568,32 +571,24 @@ static int parse (qse_awk_t* awk)
 | 
			
		||||
 | 
			
		||||
	if (!(awk->opt.trait & QSE_AWK_IMPLICIT))
 | 
			
		||||
	{
 | 
			
		||||
		/* ensure that all functions called are defined 
 | 
			
		||||
		 * in the EXPLICIT-only mode */
 | 
			
		||||
		/* ensure that all functions called are defined in the EXPLICIT-only mode.
 | 
			
		||||
		 * o	therwise, the error detection will get delay until run-time. */
 | 
			
		||||
 | 
			
		||||
		qse_htb_pair_t* p;
 | 
			
		||||
		qse_size_t buckno;
 | 
			
		||||
 | 
			
		||||
		p = qse_htb_getfirstpair (awk->parse.funs, &buckno);
 | 
			
		||||
		p = qse_htb_getfirstpair(awk->parse.funs, &buckno);
 | 
			
		||||
		while (p != QSE_NULL)
 | 
			
		||||
		{
 | 
			
		||||
			if (qse_htb_search (awk->tree.funs, 
 | 
			
		||||
				QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
 | 
			
		||||
			if (qse_htb_search (awk->tree.funs, QSE_HTB_KPTR(p), QSE_HTB_KLEN(p)) == QSE_NULL)
 | 
			
		||||
			{
 | 
			
		||||
				
 | 
			
		||||
				qse_awk_nde_t* nde;
 | 
			
		||||
 | 
			
		||||
				/* see parse_fncall() for what is
 | 
			
		||||
				 * stored into awk->tree.funs */
 | 
			
		||||
				nde = (qse_awk_nde_t*)QSE_HTB_VPTR(p);
 | 
			
		||||
 | 
			
		||||
				SETERR_ARG_LOC (
 | 
			
		||||
					awk, 
 | 
			
		||||
					QSE_AWK_EFUNNF, 
 | 
			
		||||
					QSE_HTB_KPTR(p),
 | 
			
		||||
					QSE_HTB_KLEN(p),
 | 
			
		||||
					&nde->loc
 | 
			
		||||
				);
 | 
			
		||||
				SETERR_ARG_LOC (awk, QSE_AWK_EFUNNF, QSE_HTB_KPTR(p), QSE_HTB_KLEN(p), &nde->loc);
 | 
			
		||||
 | 
			
		||||
				goto oops;
 | 
			
		||||
			}
 | 
			
		||||
@ -4276,9 +4271,7 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name)
 | 
			
		||||
	/* check if it is an awk function being processed currently */
 | 
			
		||||
	if (awk->tree.cur_fun.ptr)
 | 
			
		||||
	{
 | 
			
		||||
		if (qse_strxncmp (
 | 
			
		||||
			awk->tree.cur_fun.ptr, awk->tree.cur_fun.len,
 | 
			
		||||
			name->ptr, name->len) == 0)
 | 
			
		||||
		if (qse_strxncmp (awk->tree.cur_fun.ptr, awk->tree.cur_fun.len, name->ptr, name->len) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			/* the current function begin parsed */
 | 
			
		||||
			return FNTYPE_FUN;
 | 
			
		||||
@ -4286,14 +4279,14 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check the funtion name in the function table */
 | 
			
		||||
	if (qse_htb_search (awk->tree.funs, name->ptr, name->len) != QSE_NULL)
 | 
			
		||||
	if (qse_htb_search(awk->tree.funs, name->ptr, name->len) != QSE_NULL)
 | 
			
		||||
	{
 | 
			
		||||
		/* one of the functions defined previously */
 | 
			
		||||
		return FNTYPE_FUN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check if it is a function not resolved so far */
 | 
			
		||||
	if (qse_htb_search (awk->parse.funs, name->ptr, name->len) != QSE_NULL) 
 | 
			
		||||
	if (qse_htb_search(awk->parse.funs, name->ptr, name->len) != QSE_NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		/* one of the function calls not resolved so far. */ 
 | 
			
		||||
		return FNTYPE_FUN;
 | 
			
		||||
@ -4304,13 +4297,13 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name)
 | 
			
		||||
 | 
			
		||||
static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_cstr_t* name)
 | 
			
		||||
{
 | 
			
		||||
	if (qse_awk_findfnc (awk, name) != QSE_NULL) 
 | 
			
		||||
	if (qse_awk_findfnc(awk, name) != QSE_NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		/* implicit function */
 | 
			
		||||
		return FNTYPE_FNC;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return isfunname (awk, name);
 | 
			
		||||
	return isfunname(awk, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4680,7 +4673,7 @@ static qse_awk_nde_t* parse_primary_getline  (qse_awk_t* awk, const qse_awk_loc_
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (isfnname (awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
 | 
			
		||||
			if (isfnname(awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ploc = awk->tok.loc;
 | 
			
		||||
@ -4851,7 +4844,7 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (isfnname (awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
 | 
			
		||||
				if (isfnname(awk, QSE_STR_XSTR(awk->tok.name)) != FNTYPE_UNKNOWN) goto novar;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ploc = awk->tok.loc;
 | 
			
		||||
@ -4894,31 +4887,39 @@ oops:
 | 
			
		||||
	return QSE_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_nde_t* parse_variable (
 | 
			
		||||
	qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_awk_nde_type_t type,
 | 
			
		||||
	const qse_cstr_t* name, qse_size_t idxa)
 | 
			
		||||
static qse_awk_nde_t* parse_variable (qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_awk_nde_type_t type, const qse_cstr_t* name, qse_size_t idxa)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_var_t* nde;
 | 
			
		||||
	int fcv = 0;
 | 
			
		||||
 | 
			
		||||
	if (!(awk->opt.trait & QSE_AWK_BLANKCONCAT))
 | 
			
		||||
/*
 | 
			
		||||
	if (MATCH(awk,TOK_LPAREN) && 
 | 
			
		||||
	    (!(awk->opt.trait & QSE_AWK_BLANKCONCAT) || 
 | 
			
		||||
		(awk->tok.loc.line == xloc->line && 
 | 
			
		||||
		 awk->tok.loc.colm == xloc->colm + name->len)))
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
	if (MATCH(awk,TOK_LPAREN))
 | 
			
		||||
	{
 | 
			
		||||
		/* if concatenation by blanks is not allowed, the explicit 
 | 
			
		||||
		 * concatenation operator(%%) must be used. so it is obvious 
 | 
			
		||||
		 * that it is a function call, which is illegal for a variable. 
 | 
			
		||||
		 * if implicit, "var_xxx (1)" may be concatenation of
 | 
			
		||||
		 * the value of var_xxx and 1.
 | 
			
		||||
		 */
 | 
			
		||||
		if (MATCH(awk,TOK_LPAREN))
 | 
			
		||||
		if (awk->tok.loc.line == xloc->line && awk->tok.loc.colm == xloc->colm + name->len)
 | 
			
		||||
		{
 | 
			
		||||
			fcv = 1;
 | 
			
		||||
		}
 | 
			
		||||
		else if (!(awk->opt.trait & QSE_AWK_BLANKCONCAT))
 | 
			
		||||
		{
 | 
			
		||||
			/* if concatenation by blanks is not allowed, the explicit 
 | 
			
		||||
			 * concatenation operator(%%) must be used. so it is obvious 
 | 
			
		||||
			 * that it is a function call, which is illegal for a variable. 
 | 
			
		||||
			 * if implicit, "var_xxx (1)" may be concatenation of
 | 
			
		||||
			 * the value of var_xxx and 1.
 | 
			
		||||
			 */
 | 
			
		||||
			/* a variable is not a function */
 | 
			
		||||
			SETERR_ARG_LOC (
 | 
			
		||||
				awk, QSE_AWK_EFUNNAM,
 | 
			
		||||
				name->ptr, name->len, xloc);
 | 
			
		||||
			SETERR_ARG_LOC (awk, QSE_AWK_EFUNNAM, name->ptr, name->len, xloc);
 | 
			
		||||
			return QSE_NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nde = (qse_awk_nde_var_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*nde));
 | 
			
		||||
	nde = (qse_awk_nde_var_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
 | 
			
		||||
	if (nde == QSE_NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		ADJERR_LOC (awk, xloc);
 | 
			
		||||
@ -4933,11 +4934,11 @@ static qse_awk_nde_t* parse_variable (
 | 
			
		||||
	nde->id.idxa = idxa;
 | 
			
		||||
	nde->idx = QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	return (qse_awk_nde_t*)nde;
 | 
			
		||||
	if (!fcv) return (qse_awk_nde_t*)nde;
 | 
			
		||||
	return parse_fncall(awk, (const qse_cstr_t*)nde, QSE_NULL, xloc, FNCALL_FLAG_FCV);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dup_ident_and_get_next (
 | 
			
		||||
	qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_cstr_t* name, int max)
 | 
			
		||||
static int dup_ident_and_get_next (qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_cstr_t* name, int max)
 | 
			
		||||
{
 | 
			
		||||
	int nsegs = 0;
 | 
			
		||||
 | 
			
		||||
@ -4990,15 +4991,14 @@ oops:
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_nde_t* parse_primary_ident_noseg (
 | 
			
		||||
	qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* name)
 | 
			
		||||
static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* name)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_fnc_t* fnc;
 | 
			
		||||
	qse_size_t idxa;
 | 
			
		||||
	qse_awk_nde_t* nde = QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	/* check if name is an intrinsic function name */
 | 
			
		||||
	fnc = qse_awk_findfnc (awk, name);
 | 
			
		||||
	fnc = qse_awk_findfnc(awk, name);
 | 
			
		||||
	if (fnc)
 | 
			
		||||
	{
 | 
			
		||||
		if (MATCH(awk,TOK_LPAREN) || fnc->dfl0)
 | 
			
		||||
@ -5024,40 +5024,39 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
 | 
			
		||||
 | 
			
		||||
			/* fnc->dfl0 means that the function can be called without ().
 | 
			
		||||
			 * i.e. length */
 | 
			
		||||
			nde = parse_fncall (awk, name, fnc, xloc, ((!MATCH(awk,TOK_LPAREN) && fnc->dfl0)? 1: 0));
 | 
			
		||||
			nde = parse_fncall(awk, name, fnc, xloc, ((!MATCH(awk,TOK_LPAREN) && fnc->dfl0)? FNCALL_FLAG_NOARG: 0));
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* an intrinsic function should be in the form 
 | 
			
		||||
		 	 * of the function call */
 | 
			
		||||
			/* an intrinsic function should be in the form of the function call */
 | 
			
		||||
			SETERR_TOK (awk, QSE_AWK_ELPAREN);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	/* now we know that name is a normal identifier. */
 | 
			
		||||
	else if (MATCH(awk,TOK_LBRACK)) 
 | 
			
		||||
	{
 | 
			
		||||
		nde = parse_hashidx (awk, name, xloc);
 | 
			
		||||
		nde = parse_hashidx(awk, name, xloc);
 | 
			
		||||
	}
 | 
			
		||||
	else if ((idxa = qse_arr_rsearch (awk->parse.lcls, QSE_ARR_SIZE(awk->parse.lcls), name->ptr, name->len)) != QSE_ARR_NIL)
 | 
			
		||||
	else if ((idxa = qse_arr_rsearch(awk->parse.lcls, QSE_ARR_SIZE(awk->parse.lcls), name->ptr, name->len)) != QSE_ARR_NIL)
 | 
			
		||||
	{
 | 
			
		||||
		/* local variable */
 | 
			
		||||
		nde = parse_variable (awk, xloc, QSE_AWK_NDE_LCL, name, idxa);
 | 
			
		||||
		nde = parse_variable(awk, xloc, QSE_AWK_NDE_LCL, name, idxa);
 | 
			
		||||
	}
 | 
			
		||||
	else if ((idxa = qse_arr_search (awk->parse.params, 0, name->ptr, name->len)) != QSE_ARR_NIL)
 | 
			
		||||
	else if ((idxa = qse_arr_search(awk->parse.params, 0, name->ptr, name->len)) != QSE_ARR_NIL)
 | 
			
		||||
	{
 | 
			
		||||
		/* parameter */
 | 
			
		||||
		nde = parse_variable (awk, xloc, QSE_AWK_NDE_ARG, name, idxa);
 | 
			
		||||
		nde = parse_variable(awk, xloc, QSE_AWK_NDE_ARG, name, idxa);
 | 
			
		||||
	}
 | 
			
		||||
	else if ((idxa = get_global (awk, name)) != QSE_ARR_NIL)
 | 
			
		||||
	else if ((idxa = get_global(awk, name)) != QSE_ARR_NIL)
 | 
			
		||||
	{
 | 
			
		||||
		/* global variable */
 | 
			
		||||
		nde = parse_variable (awk, xloc, QSE_AWK_NDE_GBL, name, idxa);
 | 
			
		||||
		nde = parse_variable(awk, xloc, QSE_AWK_NDE_GBL, name, idxa);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		int fntype;
 | 
			
		||||
 | 
			
		||||
		fntype = isfunname (awk, name);
 | 
			
		||||
		fntype = isfunname(awk, name);
 | 
			
		||||
 | 
			
		||||
		if (fntype)
 | 
			
		||||
		{
 | 
			
		||||
@ -5066,18 +5065,13 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
 | 
			
		||||
			if (MATCH(awk,TOK_LPAREN))
 | 
			
		||||
			{
 | 
			
		||||
				/* must be a function name */
 | 
			
		||||
				QSE_ASSERT (qse_htb_search (
 | 
			
		||||
					awk->parse.named, name->ptr, name->len) == QSE_NULL);
 | 
			
		||||
 | 
			
		||||
				nde = parse_fncall (awk, name, QSE_NULL, xloc, 0);
 | 
			
		||||
				QSE_ASSERT (qse_htb_search(awk->parse.named, name->ptr, name->len) == QSE_NULL);
 | 
			
		||||
				nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* function name appeared without () */
 | 
			
		||||
				SETERR_ARG_LOC (
 | 
			
		||||
					awk, QSE_AWK_EFUNRED, 
 | 
			
		||||
					name->ptr, name->len, xloc
 | 
			
		||||
				);
 | 
			
		||||
				SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (awk->opt.trait & QSE_AWK_IMPLICIT) 
 | 
			
		||||
@ -5098,18 +5092,14 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
 | 
			
		||||
			{
 | 
			
		||||
				/* it is a function call to an undefined function yet */
 | 
			
		||||
 | 
			
		||||
				if (qse_htb_search (
 | 
			
		||||
					awk->parse.named, name->ptr, name->len) != QSE_NULL)
 | 
			
		||||
				if (qse_htb_search(awk->parse.named, name->ptr, name->len) != QSE_NULL)
 | 
			
		||||
				{
 | 
			
		||||
					/* the function call conflicts with a named variable */
 | 
			
		||||
					SETERR_ARG_LOC (
 | 
			
		||||
						awk, QSE_AWK_EVARRED,
 | 
			
		||||
						name->ptr, name->len, xloc
 | 
			
		||||
					);
 | 
			
		||||
					SETERR_ARG_LOC (awk, QSE_AWK_EVARRED, name->ptr, name->len, xloc);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					nde = parse_fncall (awk, name, QSE_NULL, xloc, 0);
 | 
			
		||||
					nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
@ -5120,15 +5110,13 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
 | 
			
		||||
				 * while the name is not resolved to anything, we treat the space
 | 
			
		||||
				 * as concatention by blanks. so we handle the name as a named 
 | 
			
		||||
				 * variable. */
 | 
			
		||||
				tmp = (qse_awk_nde_var_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*tmp));
 | 
			
		||||
				tmp = (qse_awk_nde_var_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*tmp));
 | 
			
		||||
				if (tmp == QSE_NULL) ADJERR_LOC (awk, xloc);
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					/* collect unique instances of a named variable 
 | 
			
		||||
					 * for reference */
 | 
			
		||||
					if (qse_htb_upsert (
 | 
			
		||||
						awk->parse.named, 
 | 
			
		||||
						name->ptr, name->len, QSE_NULL, 0) == QSE_NULL)
 | 
			
		||||
					if (qse_htb_upsert (awk->parse.named, name->ptr, name->len, QSE_NULL, 0) == QSE_NULL)
 | 
			
		||||
					{
 | 
			
		||||
						SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
 | 
			
		||||
						QSE_AWK_FREE (awk, tmp);
 | 
			
		||||
@ -5152,8 +5140,8 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
 | 
			
		||||
			if (MATCH(awk,TOK_LPAREN))
 | 
			
		||||
			{
 | 
			
		||||
				/* it is a function call as the name is followed 
 | 
			
		||||
				 * by ( and implicit variables are disabled. */
 | 
			
		||||
				nde = parse_fncall (awk, name, QSE_NULL, xloc, 0);
 | 
			
		||||
				 * by ( with/without spaces and implicit variables are disabled. */
 | 
			
		||||
				nde = parse_fncall(awk, name, QSE_NULL, xloc, 0);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
@ -5166,9 +5154,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
 | 
			
		||||
	return nde;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_nde_t* parse_primary_ident_segs (
 | 
			
		||||
	qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* full, 
 | 
			
		||||
	const qse_cstr_t segs[], int nsegs)
 | 
			
		||||
static qse_awk_nde_t* parse_primary_ident_segs (qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_cstr_t* full, const qse_cstr_t segs[], int nsegs)
 | 
			
		||||
{
 | 
			
		||||
	/* parse xxx::yyy */
 | 
			
		||||
 | 
			
		||||
@ -5178,7 +5164,7 @@ static qse_awk_nde_t* parse_primary_ident_segs (
 | 
			
		||||
	qse_awk_fnc_t fnc;
 | 
			
		||||
 | 
			
		||||
	CLRERR (awk);
 | 
			
		||||
	mod = query_module (awk, segs, nsegs, &sym);
 | 
			
		||||
	mod = query_module(awk, segs, nsegs, &sym);
 | 
			
		||||
	if (mod == QSE_NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (ISNOERR(awk)) SETERR_LOC (awk, QSE_AWK_ENOSUP, xloc);
 | 
			
		||||
@ -5202,7 +5188,6 @@ static qse_awk_nde_t* parse_primary_ident_segs (
 | 
			
		||||
					fnc.name.len = full->len;
 | 
			
		||||
					fnc.spec = sym.u.fnc;
 | 
			
		||||
					fnc.mod = mod;
 | 
			
		||||
	
 | 
			
		||||
					nde = parse_fncall (awk, full, &fnc, xloc, 0);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
@ -5288,8 +5273,7 @@ static qse_awk_nde_t* parse_primary_ident (
 | 
			
		||||
	return nde;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_nde_t* parse_hashidx (
 | 
			
		||||
	qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc)
 | 
			
		||||
static qse_awk_nde_t* parse_hashidx (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_t* idx, * tmp, * last;
 | 
			
		||||
	qse_awk_nde_var_t* nde;
 | 
			
		||||
@ -5346,7 +5330,7 @@ static qse_awk_nde_t* parse_hashidx (
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nde = (qse_awk_nde_var_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*nde));
 | 
			
		||||
	nde = (qse_awk_nde_var_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*nde));
 | 
			
		||||
	if (nde == QSE_NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		qse_awk_clrpt (awk, idx);
 | 
			
		||||
@ -5355,11 +5339,7 @@ static qse_awk_nde_t* parse_hashidx (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* search the local variable list */
 | 
			
		||||
	idxa = qse_arr_rsearch (
 | 
			
		||||
		awk->parse.lcls, 
 | 
			
		||||
		QSE_ARR_SIZE(awk->parse.lcls),
 | 
			
		||||
		name->ptr, name->len
 | 
			
		||||
	);
 | 
			
		||||
	idxa = qse_arr_rsearch(awk->parse.lcls, QSE_ARR_SIZE(awk->parse.lcls), name->ptr, name->len);
 | 
			
		||||
	if (idxa != QSE_ARR_NIL)
 | 
			
		||||
	{
 | 
			
		||||
		nde->type = QSE_AWK_NDE_LCLIDX;
 | 
			
		||||
@ -5374,7 +5354,7 @@ static qse_awk_nde_t* parse_hashidx (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* search the parameter name list */
 | 
			
		||||
	idxa = qse_arr_search (awk->parse.params, 0, name->ptr, name->len);
 | 
			
		||||
	idxa = qse_arr_search(awk->parse.params, 0, name->ptr, name->len);
 | 
			
		||||
	if (idxa != QSE_ARR_NIL)
 | 
			
		||||
	{
 | 
			
		||||
		nde->type = QSE_AWK_NDE_ARGIDX;
 | 
			
		||||
@ -5405,17 +5385,15 @@ static qse_awk_nde_t* parse_hashidx (
 | 
			
		||||
 | 
			
		||||
	if (awk->opt.trait & QSE_AWK_IMPLICIT) 
 | 
			
		||||
	{
 | 
			
		||||
		int fnname = isfnname (awk, name);
 | 
			
		||||
		int fnname = isfnname(awk, name);
 | 
			
		||||
		switch (fnname)
 | 
			
		||||
		{
 | 
			
		||||
			case FNTYPE_FNC:
 | 
			
		||||
				SETERR_ARG_LOC (
 | 
			
		||||
					awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
 | 
			
		||||
				SETERR_ARG_LOC (awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
 | 
			
		||||
				goto exit_func;
 | 
			
		||||
 | 
			
		||||
			case FNTYPE_FUN:
 | 
			
		||||
				SETERR_ARG_LOC (
 | 
			
		||||
					awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
 | 
			
		||||
				SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
 | 
			
		||||
				goto exit_func;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -5441,9 +5419,7 @@ exit_func:
 | 
			
		||||
	return QSE_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_nde_t* parse_fncall (
 | 
			
		||||
	qse_awk_t* awk, const qse_cstr_t* name, 
 | 
			
		||||
	qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg)
 | 
			
		||||
static qse_awk_nde_t* parse_fncall (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int flags)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_t* head, * curr, * nde;
 | 
			
		||||
	qse_awk_nde_fncall_t* call;
 | 
			
		||||
@ -5454,7 +5430,7 @@ static qse_awk_nde_t* parse_fncall (
 | 
			
		||||
	call = QSE_NULL;
 | 
			
		||||
	nargs = 0;
 | 
			
		||||
 | 
			
		||||
	if (noarg) goto make_node;
 | 
			
		||||
	if (flags & FNCALL_FLAG_NOARG) goto make_node;
 | 
			
		||||
	if (get_token(awk) <= -1) goto oops;
 | 
			
		||||
 | 
			
		||||
	if (MATCH(awk,TOK_RPAREN)) 
 | 
			
		||||
@ -5465,14 +5441,13 @@ static qse_awk_nde_t* parse_fncall (
 | 
			
		||||
	else 
 | 
			
		||||
	{
 | 
			
		||||
		/* parse function parameters */
 | 
			
		||||
 | 
			
		||||
		while (1) 
 | 
			
		||||
		{
 | 
			
		||||
			eloc = awk->tok.loc;
 | 
			
		||||
			nde = parse_expr_withdc (awk, &eloc);
 | 
			
		||||
			if (nde == QSE_NULL) goto oops;
 | 
			
		||||
	
 | 
			
		||||
			if (head == QSE_NULL) head = nde;
 | 
			
		||||
			nde = parse_expr_withdc(awk, &eloc);
 | 
			
		||||
			if (!nde) goto oops;
 | 
			
		||||
 | 
			
		||||
			if (!head) head = nde;
 | 
			
		||||
			else curr->next = nde;
 | 
			
		||||
			curr = nde;
 | 
			
		||||
 | 
			
		||||
@ -5500,14 +5475,22 @@ static qse_awk_nde_t* parse_fncall (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
make_node:
 | 
			
		||||
	call = (qse_awk_nde_fncall_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*call));
 | 
			
		||||
	if (call == QSE_NULL) 
 | 
			
		||||
	call = (qse_awk_nde_fncall_t*)qse_awk_callocmem(awk, QSE_SIZEOF(*call));
 | 
			
		||||
	if (!call) 
 | 
			
		||||
	{
 | 
			
		||||
		ADJERR_LOC (awk, xloc);
 | 
			
		||||
		goto oops;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (fnc)
 | 
			
		||||
	if (flags & FNCALL_FLAG_FCV)
 | 
			
		||||
	{
 | 
			
		||||
		call->type = QSE_AWK_NDE_FCV;
 | 
			
		||||
		call->loc = *xloc;
 | 
			
		||||
		call->u.fcv.var = (qse_awk_nde_var_t*)name; /* name is a pointer to a variable node */
 | 
			
		||||
		call->args = head;
 | 
			
		||||
		call->nargs = nargs;
 | 
			
		||||
	}
 | 
			
		||||
	else if (fnc)
 | 
			
		||||
	{
 | 
			
		||||
		call->type = QSE_AWK_NDE_FNC;
 | 
			
		||||
		call->loc = *xloc;
 | 
			
		||||
@ -5540,10 +5523,8 @@ make_node:
 | 
			
		||||
		call->args = head;
 | 
			
		||||
		call->nargs = nargs;
 | 
			
		||||
 | 
			
		||||
		/* store a non-builtin function call into the awk->parse.funs 
 | 
			
		||||
		 * table */
 | 
			
		||||
		if (qse_htb_upsert (
 | 
			
		||||
			awk->parse.funs, name->ptr, name->len, call, 0) == QSE_NULL)
 | 
			
		||||
		/* store a non-builtin function call into the awk->parse.funs table */
 | 
			
		||||
		if (!qse_htb_upsert(awk->parse.funs, name->ptr, name->len, call, 0))
 | 
			
		||||
		{
 | 
			
		||||
			SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
 | 
			
		||||
			goto oops;
 | 
			
		||||
@ -6233,29 +6214,41 @@ retry:
 | 
			
		||||
		ADD_TOKEN_CHAR (awk, tok, c);
 | 
			
		||||
		GET_CHAR_TO (awk, c);
 | 
			
		||||
 | 
			
		||||
		if (c != QSE_T('_') && !QSE_AWK_ISALPHA(awk, c))
 | 
			
		||||
		/*
 | 
			
		||||
		if (c == QSE_T('@'))
 | 
			
		||||
		{
 | 
			
		||||
			SET_TOKEN_TYPE (awk, tok, TOK_DBLAT);
 | 
			
		||||
			GET_CHAR (awk);
 | 
			
		||||
		}*/
 | 
			
		||||
		/* other special extended operators here 
 | 
			
		||||
		else if (c == QSE_T('*'))
 | 
			
		||||
		{
 | 
			
		||||
		}*/
 | 
			
		||||
		/*else*/ if (c != QSE_T('_') && !QSE_AWK_ISALPHA(awk, c))
 | 
			
		||||
		{
 | 
			
		||||
			/* this extended keyword is empty, 
 | 
			
		||||
			 * not followed by a valid word */
 | 
			
		||||
			SETERR_LOC (awk, QSE_AWK_EXKWEM, &(awk)->tok.loc);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* expect normal identifier starting with an alphabet */
 | 
			
		||||
		do 
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			ADD_TOKEN_CHAR (awk, tok, c);
 | 
			
		||||
			GET_CHAR_TO (awk, c);
 | 
			
		||||
		} 
 | 
			
		||||
		while (c == QSE_T('_') || QSE_AWK_ISALPHA(awk, c) || QSE_AWK_ISDIGIT(awk, c));
 | 
			
		||||
			/* expect normal identifier starting with an alphabet */
 | 
			
		||||
			do 
 | 
			
		||||
			{
 | 
			
		||||
				ADD_TOKEN_CHAR (awk, tok, c);
 | 
			
		||||
				GET_CHAR_TO (awk, c);
 | 
			
		||||
			} 
 | 
			
		||||
			while (c == QSE_T('_') || QSE_AWK_ISALPHA(awk, c) || QSE_AWK_ISDIGIT(awk, c));
 | 
			
		||||
 | 
			
		||||
		type = classify_ident(awk, QSE_STR_XSTR(tok->name));
 | 
			
		||||
		if (type == TOK_IDENT)
 | 
			
		||||
		{
 | 
			
		||||
			SETERR_TOK (awk, QSE_AWK_EXKWNR);
 | 
			
		||||
			return -1;
 | 
			
		||||
			type = classify_ident(awk, QSE_STR_XSTR(tok->name));
 | 
			
		||||
			if (type == TOK_IDENT)
 | 
			
		||||
			{
 | 
			
		||||
				SETERR_TOK (awk, QSE_AWK_EXKWNR);
 | 
			
		||||
				return -1;
 | 
			
		||||
			}
 | 
			
		||||
			SET_TOKEN_TYPE (awk, tok, type);
 | 
			
		||||
		}
 | 
			
		||||
		SET_TOKEN_TYPE (awk, tok, type);
 | 
			
		||||
	}
 | 
			
		||||
	else if (c == QSE_T('B'))
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -230,6 +230,7 @@ static qse_awk_val_t* eval_fun_ex (
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
static qse_awk_val_t* eval_fcv (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* __eval_call (
 | 
			
		||||
	qse_awk_rtx_t* run,
 | 
			
		||||
@ -252,7 +253,7 @@ static qse_awk_val_t** get_reference_indexed (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val);
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_int (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
static qse_awk_val_t* eval_real (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
static qse_awk_val_t* eval_flt (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
static qse_awk_val_t* eval_str (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
static qse_awk_val_t* eval_mbs (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
 | 
			
		||||
@ -3327,8 +3328,9 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
		eval_cnd,
 | 
			
		||||
		eval_fnc,
 | 
			
		||||
		eval_fun,
 | 
			
		||||
		eval_fcv,
 | 
			
		||||
		eval_int,
 | 
			
		||||
		eval_real,
 | 
			
		||||
		eval_flt,
 | 
			
		||||
		eval_str,
 | 
			
		||||
		eval_mbs,
 | 
			
		||||
		eval_rex,
 | 
			
		||||
@ -3482,8 +3484,7 @@ static qse_awk_val_t* eval_assignment (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* do_assignment (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_nde_t* var, qse_awk_val_t* val)
 | 
			
		||||
static qse_awk_val_t* do_assignment (qse_awk_rtx_t* rtx, qse_awk_nde_t* var, qse_awk_val_t* val)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* ret;
 | 
			
		||||
	qse_awk_errnum_t errnum;
 | 
			
		||||
@ -3535,8 +3536,7 @@ exit_on_error:
 | 
			
		||||
	return QSE_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* do_assignment_nonidx (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_var_t* var, qse_awk_val_t* val)
 | 
			
		||||
static qse_awk_val_t* do_assignment_nonidx (qse_awk_rtx_t* run, qse_awk_nde_var_t* var, qse_awk_val_t* val)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_type_t vtype;
 | 
			
		||||
 | 
			
		||||
@ -3662,8 +3662,7 @@ static qse_awk_val_t* do_assignment_nonidx (
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* do_assignment_idx (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var, qse_awk_val_t* val)
 | 
			
		||||
static qse_awk_val_t* do_assignment_idx (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var, qse_awk_val_t* val)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_map_t* map;
 | 
			
		||||
	qse_awk_val_type_t mvtype;
 | 
			
		||||
@ -3814,8 +3813,7 @@ retry:
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* do_assignment_pos (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_nde_pos_t* pos, qse_awk_val_t* val)
 | 
			
		||||
static qse_awk_val_t* do_assignment_pos (qse_awk_rtx_t* rtx, qse_awk_nde_pos_t* pos, qse_awk_val_t* val)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* v;
 | 
			
		||||
	qse_awk_val_type_t vtype;
 | 
			
		||||
@ -4027,8 +4025,7 @@ static qse_awk_val_t* eval_binop_lor (
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_land (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_land (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
	qse_awk_val_t* res = QSE_NULL;
 | 
			
		||||
@ -4079,8 +4076,7 @@ static qse_awk_val_t* eval_binop_land (
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_in (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_in (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* rv;
 | 
			
		||||
	qse_awk_val_type_t rvtype;
 | 
			
		||||
@ -4710,68 +4706,59 @@ static int teq_val (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* righ
 | 
			
		||||
	return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_teq (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_teq (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	return teq_val (rtx, left, right)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_tne (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_tne (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	return teq_val (rtx, left, right)? QSE_AWK_VAL_ZERO: QSE_AWK_VAL_ONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_eq (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_eq (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n = __cmp_val(rtx, left, right);
 | 
			
		||||
	if (n == CMP_ERROR) return QSE_NULL;
 | 
			
		||||
	return (n == 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_ne (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_ne (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n = __cmp_val(rtx, left, right);
 | 
			
		||||
	if (n == CMP_ERROR) return QSE_NULL;
 | 
			
		||||
	return (n != 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_gt (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_gt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n = __cmp_val(rtx, left, right);
 | 
			
		||||
	if (n == CMP_ERROR) return QSE_NULL;
 | 
			
		||||
	return (n > 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_ge (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_ge (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n = __cmp_val(rtx, left, right);
 | 
			
		||||
	if (n == CMP_ERROR) return QSE_NULL;
 | 
			
		||||
	return (n >= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_lt (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_lt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n = __cmp_val(rtx, left, right);
 | 
			
		||||
	if (n == CMP_ERROR) return QSE_NULL;
 | 
			
		||||
	return (n < 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_le (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_le (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n = __cmp_val(rtx, left, right);
 | 
			
		||||
	if (n == CMP_ERROR) return QSE_NULL;
 | 
			
		||||
	return (n <= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_lshift (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_lshift (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
 | 
			
		||||
@ -4785,8 +4772,7 @@ static qse_awk_val_t* eval_binop_lshift (
 | 
			
		||||
	return qse_awk_rtx_makeintval(rtx, l1 << l2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_rshift (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_rshift (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
 | 
			
		||||
@ -4800,8 +4786,7 @@ static qse_awk_val_t* eval_binop_rshift (
 | 
			
		||||
	return qse_awk_rtx_makeintval (rtx, l1 >> l2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_plus (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_plus (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n1, n2, n3;
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
@ -4831,8 +4816,7 @@ static qse_awk_val_t* eval_binop_plus (
 | 
			
		||||
	                  qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1+(qse_awk_flt_t)r2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_minus (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_minus (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n1, n2, n3;
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
@ -4855,8 +4839,7 @@ static qse_awk_val_t* eval_binop_minus (
 | 
			
		||||
	                  qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1-(qse_awk_flt_t)r2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_mul (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_mul (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n1, n2, n3;
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
@ -4879,8 +4862,7 @@ static qse_awk_val_t* eval_binop_mul (
 | 
			
		||||
	                  qse_awk_rtx_makefltval(rtx,(qse_awk_flt_t)r1*(qse_awk_flt_t)r2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_div (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_div (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n1, n2, n3;
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
@ -4937,8 +4919,7 @@ static qse_awk_val_t* eval_binop_div (
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_idiv (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_idiv (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n1, n2, n3;
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
@ -4986,8 +4967,7 @@ static qse_awk_val_t* eval_binop_idiv (
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_mod (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_mod (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n1, n2, n3;
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
@ -5044,8 +5024,7 @@ static qse_awk_val_t* eval_binop_mod (
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_exp (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_exp (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
 | 
			
		||||
{
 | 
			
		||||
	int n1, n2, n3;
 | 
			
		||||
	qse_awk_int_t l1, l2;
 | 
			
		||||
@ -5190,8 +5169,7 @@ static qse_awk_val_t* eval_binop_match0 (
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_ma (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_ma (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* lv, * rv, * res;
 | 
			
		||||
 | 
			
		||||
@ -5220,8 +5198,7 @@ static qse_awk_val_t* eval_binop_ma (
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_binop_nm (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
static qse_awk_val_t* eval_binop_nm (qse_awk_rtx_t* run, qse_awk_nde_t* left, qse_awk_nde_t* right)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* lv, * rv, * res;
 | 
			
		||||
 | 
			
		||||
@ -5618,12 +5595,8 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
 | 
			
		||||
	qse_awk_rtx_refupval (run, tv);
 | 
			
		||||
 | 
			
		||||
	QSE_ASSERT (
 | 
			
		||||
		cnd->left->next == QSE_NULL && 
 | 
			
		||||
		cnd->right->next == QSE_NULL);
 | 
			
		||||
	v = (qse_awk_rtx_valtobool (run, tv))?
 | 
			
		||||
		eval_expression (run, cnd->left):
 | 
			
		||||
		eval_expression (run, cnd->right);
 | 
			
		||||
	QSE_ASSERT (cnd->left->next == QSE_NULL && cnd->right->next == QSE_NULL);
 | 
			
		||||
	v = (qse_awk_rtx_valtobool (run, tv))? eval_expression(run, cnd->left): eval_expression(run, cnd->right);
 | 
			
		||||
 | 
			
		||||
	qse_awk_rtx_refdownval (run, tv);
 | 
			
		||||
	return v;
 | 
			
		||||
@ -5632,34 +5605,23 @@ static qse_awk_val_t* eval_cnd (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	/* intrinsic function */
 | 
			
		||||
 | 
			
		||||
	qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
 | 
			
		||||
 | 
			
		||||
	/* the parser must make sure taht the number of arguments 
 | 
			
		||||
	 * is proper */ 
 | 
			
		||||
	QSE_ASSERT (call->nargs >= call->u.fnc.spec.arg.min && 
 | 
			
		||||
	            call->nargs <= call->u.fnc.spec.arg.max); 
 | 
			
		||||
 | 
			
		||||
	return eval_call (
 | 
			
		||||
		run, nde, call->u.fnc.spec.arg.spec,
 | 
			
		||||
		QSE_NULL, QSE_NULL, QSE_NULL);
 | 
			
		||||
	QSE_ASSERT (call->nargs >= call->u.fnc.spec.arg.min && call->nargs <= call->u.fnc.spec.arg.max); 
 | 
			
		||||
	return eval_call(run, nde, call->u.fnc.spec.arg.spec, QSE_NULL, QSE_NULL, QSE_NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_fun_ex (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_nde_t* nde,
 | 
			
		||||
	void(*errhandler)(void*), void* eharg)
 | 
			
		||||
static QSE_INLINE qse_awk_val_t* eval_fun_ex (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, void(*errhandler)(void*), void* eharg)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
 | 
			
		||||
	qse_awk_fun_t* fun;
 | 
			
		||||
	qse_htb_pair_t* pair;
 | 
			
		||||
 | 
			
		||||
	pair = qse_htb_search (rtx->awk->tree.funs,
 | 
			
		||||
		call->u.fun.name.ptr, call->u.fun.name.len);
 | 
			
		||||
	pair = qse_htb_search(rtx->awk->tree.funs, call->u.fun.name.ptr, call->u.fun.name.len);
 | 
			
		||||
	if (pair == QSE_NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		SETERR_ARGX_LOC (
 | 
			
		||||
			rtx, QSE_AWK_EFUNNF,
 | 
			
		||||
			&call->u.fun.name, &nde->loc);
 | 
			
		||||
		SETERR_ARGX_LOC (rtx, QSE_AWK_EFUNNF, &call->u.fun.name, &nde->loc);
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -5674,18 +5636,42 @@ static qse_awk_val_t* eval_fun_ex (
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return eval_call (rtx, nde, QSE_NULL, fun, errhandler, eharg);
 | 
			
		||||
	return eval_call(rtx, nde, QSE_NULL, fun, errhandler, eharg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_fun (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	return eval_fun_ex (run, nde, QSE_NULL, QSE_NULL);
 | 
			
		||||
	return eval_fun_ex(rtx, nde, QSE_NULL, QSE_NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_fcv (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_fncall_t* call = (qse_awk_nde_fncall_t*)nde;
 | 
			
		||||
	qse_awk_val_t* fv, * rv;
 | 
			
		||||
 | 
			
		||||
	fv = eval_expression(rtx, (qse_awk_nde_t*)call->u.fcv.var);
 | 
			
		||||
	if (!fv) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	qse_awk_rtx_refupval (rtx, fv);
 | 
			
		||||
	if (QSE_AWK_RTX_GETVALTYPE(rtx, fv) != QSE_AWK_VAL_FUN)
 | 
			
		||||
	{
 | 
			
		||||
		/*SETERR_ARGX_LOC (rtx, QSE_AWK_EFUNNF, &call->u.fun.name, &nde->loc);*/
 | 
			
		||||
/*printf ("NOT FUNCTION VALUE\n");*/
 | 
			
		||||
		rv = QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		rv = eval_call(rtx, nde, QSE_NULL, ((qse_awk_val_fun_t*)fv)->fun, QSE_NULL, QSE_NULL	);
 | 
			
		||||
	}
 | 
			
		||||
	qse_awk_rtx_refdownval (rtx, fv);
 | 
			
		||||
 | 
			
		||||
	return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* run->stack_base has not been set for this  
 | 
			
		||||
 * stack frame. so the RTX_STACK_ARG macro cannot be used as in 
 | 
			
		||||
 * qse_awk_rtx_refdownval (run, RTX_STACK_ARG(run,nargs));*/ 
 | 
			
		||||
#define UNWIND_RTX_RTX_STACK_ARG(rtx,nargs) \
 | 
			
		||||
#define UNWIND_RTX_STACK_ARG(rtx,nargs) \
 | 
			
		||||
	do { \
 | 
			
		||||
		while ((nargs) > 0) \
 | 
			
		||||
		{ \
 | 
			
		||||
@ -5695,7 +5681,7 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
		} \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define UNWIND_RTX_RTX_STACK_BASE(rtx) \
 | 
			
		||||
#define UNWIND_RTX_STACK_BASE(rtx) \
 | 
			
		||||
	do { \
 | 
			
		||||
		__raw_pop (rtx); /* nargs */ \
 | 
			
		||||
		__raw_pop (rtx); /* return */ \
 | 
			
		||||
@ -5705,8 +5691,8 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
 | 
			
		||||
#define UNWIND_RTX_STACK(rtx,nargs) \
 | 
			
		||||
	do { \
 | 
			
		||||
		UNWIND_RTX_RTX_STACK_ARG(rtx,nargs); \
 | 
			
		||||
		UNWIND_RTX_RTX_STACK_BASE(rtx); \
 | 
			
		||||
		UNWIND_RTX_STACK_ARG(rtx,nargs); \
 | 
			
		||||
		UNWIND_RTX_STACK_BASE(rtx); \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* __eval_call (
 | 
			
		||||
@ -5810,7 +5796,7 @@ static qse_awk_val_t* __eval_call (
 | 
			
		||||
	nargs = argpusher (run, call, apdata);
 | 
			
		||||
	if (nargs == (qse_size_t)-1)
 | 
			
		||||
	{
 | 
			
		||||
		UNWIND_RTX_RTX_STACK_BASE (run);
 | 
			
		||||
		UNWIND_RTX_STACK_BASE (run);
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -5957,8 +5943,7 @@ static qse_awk_val_t* __eval_call (
 | 
			
		||||
	return (n == -1)? QSE_NULL: v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_size_t push_arg_from_vals (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
 | 
			
		||||
static qse_size_t push_arg_from_vals (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
 | 
			
		||||
{
 | 
			
		||||
	struct pafv* pafv = (struct pafv*)data;
 | 
			
		||||
	qse_size_t nargs = 0;
 | 
			
		||||
@ -5975,7 +5960,7 @@ static qse_size_t push_arg_from_vals (
 | 
			
		||||
			qse_awk_rtx_refupval (rtx, pafv->args[nargs]);
 | 
			
		||||
			qse_awk_rtx_refdownval (rtx, pafv->args[nargs]);
 | 
			
		||||
 | 
			
		||||
			UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
			UNWIND_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
			SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
 | 
			
		||||
			return (qse_size_t)-1;
 | 
			
		||||
		}
 | 
			
		||||
@ -5986,8 +5971,7 @@ static qse_size_t push_arg_from_vals (
 | 
			
		||||
	return nargs; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_size_t push_arg_from_nde (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
 | 
			
		||||
static qse_size_t push_arg_from_nde (qse_awk_rtx_t* rtx, qse_awk_nde_fncall_t* call, void* data)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_t* p;
 | 
			
		||||
	qse_awk_val_t* v;
 | 
			
		||||
@ -6009,7 +5993,7 @@ static qse_size_t push_arg_from_nde (
 | 
			
		||||
			      
 | 
			
		||||
			if (get_reference (rtx, p, &ref) == -1)
 | 
			
		||||
			{
 | 
			
		||||
				UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
				UNWIND_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
				return (qse_size_t)-1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -6032,7 +6016,7 @@ static qse_size_t push_arg_from_nde (
 | 
			
		||||
 | 
			
		||||
		if (v == QSE_NULL)
 | 
			
		||||
		{
 | 
			
		||||
			UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
			UNWIND_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
			return (qse_size_t)-1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -6046,7 +6030,7 @@ static qse_size_t push_arg_from_nde (
 | 
			
		||||
			qse_awk_rtx_refupval (rtx, v);
 | 
			
		||||
			qse_awk_rtx_refdownval (rtx, v);
 | 
			
		||||
 | 
			
		||||
			UNWIND_RTX_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
			UNWIND_RTX_STACK_ARG (rtx, nargs);
 | 
			
		||||
			SETERR_LOC (rtx, QSE_AWK_ENOMEM, &call->loc);
 | 
			
		||||
			return (qse_size_t)-1;
 | 
			
		||||
		}
 | 
			
		||||
@ -6057,19 +6041,12 @@ static qse_size_t push_arg_from_nde (
 | 
			
		||||
	return nargs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_call (
 | 
			
		||||
	qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, 
 | 
			
		||||
	const qse_char_t* fnc_arg_spec, qse_awk_fun_t* fun, 
 | 
			
		||||
	void(*errhandler)(void*), void* eharg)
 | 
			
		||||
static qse_awk_val_t* eval_call (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, const qse_char_t* fnc_arg_spec, qse_awk_fun_t* fun, void(*errhandler)(void*), void* eharg)
 | 
			
		||||
{
 | 
			
		||||
	return __eval_call (
 | 
			
		||||
		rtx, nde, fnc_arg_spec, fun, 
 | 
			
		||||
		push_arg_from_nde, (void*)fnc_arg_spec,
 | 
			
		||||
		errhandler, eharg);
 | 
			
		||||
	return __eval_call (rtx, nde, fnc_arg_spec, fun, push_arg_from_nde, (void*)fnc_arg_spec, errhandler, eharg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int get_reference (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_t* nde, qse_awk_val_t*** ref)
 | 
			
		||||
static int get_reference (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, qse_awk_val_t*** ref)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_var_t* tgt = (qse_awk_nde_var_t*)nde;
 | 
			
		||||
	qse_awk_val_t** tmp;
 | 
			
		||||
@ -6082,19 +6059,16 @@ static int get_reference (
 | 
			
		||||
		{
 | 
			
		||||
			qse_htb_pair_t* pair;
 | 
			
		||||
 | 
			
		||||
			pair = qse_htb_search (
 | 
			
		||||
				run->named, tgt->id.name.ptr, tgt->id.name.len);
 | 
			
		||||
			pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
 | 
			
		||||
			if (pair == QSE_NULL)
 | 
			
		||||
			{
 | 
			
		||||
				/* it is bad that the named variable has to be
 | 
			
		||||
				 * created in the function named "__get_refernce".
 | 
			
		||||
				 * would there be any better ways to avoid this? */
 | 
			
		||||
				pair = qse_htb_upsert (
 | 
			
		||||
					run->named, tgt->id.name.ptr,
 | 
			
		||||
					tgt->id.name.len, qse_awk_val_nil, 0);
 | 
			
		||||
				pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
 | 
			
		||||
				if (pair == QSE_NULL) 
 | 
			
		||||
				{
 | 
			
		||||
					SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
					SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
					return -1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@ -6104,60 +6078,53 @@ static int get_reference (
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		case QSE_AWK_NDE_GBL:
 | 
			
		||||
			/* *ref = (qse_awk_val_t**)&RTX_STACK_GBL(run,tgt->id.idxa); */
 | 
			
		||||
			/* *ref = (qse_awk_val_t**)&RTX_STACK_GBL(rtx,tgt->id.idxa); */
 | 
			
		||||
			*ref = (qse_awk_val_t**)((qse_size_t)tgt->id.idxa);
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		case QSE_AWK_NDE_LCL:
 | 
			
		||||
			*ref = (qse_awk_val_t**)&RTX_STACK_LCL(run,tgt->id.idxa);
 | 
			
		||||
			*ref = (qse_awk_val_t**)&RTX_STACK_LCL(rtx,tgt->id.idxa);
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		case QSE_AWK_NDE_ARG:
 | 
			
		||||
			*ref = (qse_awk_val_t**)&RTX_STACK_ARG(run,tgt->id.idxa);
 | 
			
		||||
			*ref = (qse_awk_val_t**)&RTX_STACK_ARG(rtx,tgt->id.idxa);
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		case QSE_AWK_NDE_NAMEDIDX:
 | 
			
		||||
		{
 | 
			
		||||
			qse_htb_pair_t* pair;
 | 
			
		||||
 | 
			
		||||
			pair = qse_htb_search (
 | 
			
		||||
				run->named, tgt->id.name.ptr, tgt->id.name.len);
 | 
			
		||||
			pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
 | 
			
		||||
			if (pair == QSE_NULL)
 | 
			
		||||
			{
 | 
			
		||||
				pair = qse_htb_upsert (
 | 
			
		||||
					run->named, tgt->id.name.ptr,
 | 
			
		||||
					tgt->id.name.len, qse_awk_val_nil, 0);
 | 
			
		||||
				pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
 | 
			
		||||
				if (pair == QSE_NULL) 
 | 
			
		||||
				{
 | 
			
		||||
					SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
					SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
					return -1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			tmp = get_reference_indexed (
 | 
			
		||||
				run, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
 | 
			
		||||
			tmp = get_reference_indexed(rtx, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
 | 
			
		||||
			if (tmp == QSE_NULL) return -1;
 | 
			
		||||
			*ref = tmp;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		case QSE_AWK_NDE_GBLIDX:
 | 
			
		||||
			tmp = get_reference_indexed (run, tgt, 
 | 
			
		||||
				(qse_awk_val_t**)&RTX_STACK_GBL(run,tgt->id.idxa));
 | 
			
		||||
			tmp = get_reference_indexed (rtx, tgt, (qse_awk_val_t**)&RTX_STACK_GBL(rtx,tgt->id.idxa));
 | 
			
		||||
			if (tmp == QSE_NULL) return -1;
 | 
			
		||||
			*ref = tmp;
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		case QSE_AWK_NDE_LCLIDX:
 | 
			
		||||
			tmp = get_reference_indexed (run, tgt, 
 | 
			
		||||
				(qse_awk_val_t**)&RTX_STACK_LCL(run,tgt->id.idxa));
 | 
			
		||||
			tmp = get_reference_indexed (rtx, tgt, (qse_awk_val_t**)&RTX_STACK_LCL(rtx,tgt->id.idxa));
 | 
			
		||||
			if (tmp == QSE_NULL) return -1;
 | 
			
		||||
			*ref = tmp;
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		case QSE_AWK_NDE_ARGIDX:
 | 
			
		||||
			tmp = get_reference_indexed (run, tgt, 
 | 
			
		||||
				(qse_awk_val_t**)&RTX_STACK_ARG(run,tgt->id.idxa));
 | 
			
		||||
			tmp = get_reference_indexed(rtx, tgt, (qse_awk_val_t**)&RTX_STACK_ARG(rtx,tgt->id.idxa));
 | 
			
		||||
			if (tmp == QSE_NULL) return -1;
 | 
			
		||||
			*ref = tmp;
 | 
			
		||||
			return 0;
 | 
			
		||||
@ -6170,22 +6137,22 @@ static int get_reference (
 | 
			
		||||
	
 | 
			
		||||
			/* the position number is returned for the positional 
 | 
			
		||||
			 * variable unlike other reference types. */
 | 
			
		||||
			v = eval_expression (run, ((qse_awk_nde_pos_t*)nde)->val);
 | 
			
		||||
			v = eval_expression(rtx, ((qse_awk_nde_pos_t*)nde)->val);
 | 
			
		||||
			if (v == QSE_NULL) return -1;
 | 
			
		||||
	
 | 
			
		||||
			qse_awk_rtx_refupval (run, v);
 | 
			
		||||
			n = qse_awk_rtx_valtoint (run, v, &lv);
 | 
			
		||||
			qse_awk_rtx_refdownval (run, v);
 | 
			
		||||
			qse_awk_rtx_refupval (rtx, v);
 | 
			
		||||
			n = qse_awk_rtx_valtoint(rtx, v, &lv);
 | 
			
		||||
			qse_awk_rtx_refdownval (rtx, v);
 | 
			
		||||
	
 | 
			
		||||
			if (n <= -1) 
 | 
			
		||||
			{
 | 
			
		||||
				SETERR_LOC (run, QSE_AWK_EPOSIDX, &nde->loc);
 | 
			
		||||
				SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &nde->loc);
 | 
			
		||||
				return -1;
 | 
			
		||||
			}
 | 
			
		||||
	
 | 
			
		||||
			if (!IS_VALID_POSIDX(lv)) 
 | 
			
		||||
			{
 | 
			
		||||
				SETERR_LOC (run, QSE_AWK_EPOSIDX, &nde->loc);
 | 
			
		||||
				SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &nde->loc);
 | 
			
		||||
				return -1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -6194,13 +6161,12 @@ static int get_reference (
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			SETERR_LOC (run, QSE_AWK_ENOTREF, &nde->loc);
 | 
			
		||||
			SETERR_LOC (rtx, QSE_AWK_ENOTREF, &nde->loc);
 | 
			
		||||
			return -1;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t** get_reference_indexed (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
 | 
			
		||||
static qse_awk_val_t** get_reference_indexed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
 | 
			
		||||
{
 | 
			
		||||
	qse_htb_pair_t* pair;
 | 
			
		||||
	qse_char_t* str;
 | 
			
		||||
@ -6210,144 +6176,117 @@ static qse_awk_val_t** get_reference_indexed (
 | 
			
		||||
 | 
			
		||||
	QSE_ASSERT (val != QSE_NULL);
 | 
			
		||||
 | 
			
		||||
	vtype = QSE_AWK_RTX_GETVALTYPE (rtx, *val);
 | 
			
		||||
	vtype = QSE_AWK_RTX_GETVALTYPE(rtx, *val);
 | 
			
		||||
	if (vtype == QSE_AWK_VAL_NIL)
 | 
			
		||||
	{
 | 
			
		||||
		qse_awk_val_t* tmp;
 | 
			
		||||
 | 
			
		||||
		tmp = qse_awk_rtx_makemapval (run);
 | 
			
		||||
		tmp = qse_awk_rtx_makemapval (rtx);
 | 
			
		||||
		if (tmp == QSE_NULL)
 | 
			
		||||
		{
 | 
			
		||||
			ADJERR_LOC (run, &nde->loc);
 | 
			
		||||
			ADJERR_LOC (rtx, &nde->loc);
 | 
			
		||||
			return QSE_NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		qse_awk_rtx_refdownval (run, *val);
 | 
			
		||||
		qse_awk_rtx_refdownval (rtx, *val);
 | 
			
		||||
		*val = tmp;
 | 
			
		||||
		qse_awk_rtx_refupval (run, (qse_awk_val_t*)*val);
 | 
			
		||||
		qse_awk_rtx_refupval (rtx, (qse_awk_val_t*)*val);
 | 
			
		||||
	}
 | 
			
		||||
	else if (vtype != QSE_AWK_VAL_MAP) 
 | 
			
		||||
	{
 | 
			
		||||
		SETERR_LOC (run, QSE_AWK_ENOTMAP, &nde->loc);
 | 
			
		||||
		SETERR_LOC (rtx, QSE_AWK_ENOTMAP, &nde->loc);
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QSE_ASSERT (nde->idx != QSE_NULL);
 | 
			
		||||
 | 
			
		||||
	len = QSE_COUNTOF(idxbuf);
 | 
			
		||||
	str = idxnde_to_str (run, nde->idx, idxbuf, &len);
 | 
			
		||||
	str = idxnde_to_str (rtx, nde->idx, idxbuf, &len);
 | 
			
		||||
	if (str == QSE_NULL) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	pair = qse_htb_search ((*(qse_awk_val_map_t**)val)->map, str, len);
 | 
			
		||||
	pair = qse_htb_search((*(qse_awk_val_map_t**)val)->map, str, len);
 | 
			
		||||
	if (pair == QSE_NULL)
 | 
			
		||||
	{
 | 
			
		||||
		pair = qse_htb_upsert (
 | 
			
		||||
			(*(qse_awk_val_map_t**)val)->map, 
 | 
			
		||||
			str, len, qse_awk_val_nil, 0);
 | 
			
		||||
		pair = qse_htb_upsert((*(qse_awk_val_map_t**)val)->map, str, len, qse_awk_val_nil, 0);
 | 
			
		||||
		if (pair == QSE_NULL)
 | 
			
		||||
		{
 | 
			
		||||
			if (str != idxbuf) QSE_AWK_FREE (run->awk, str);
 | 
			
		||||
			SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
			if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
 | 
			
		||||
			SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
			return QSE_NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		qse_awk_rtx_refupval (run, QSE_HTB_VPTR(pair));
 | 
			
		||||
		qse_awk_rtx_refupval (rtx, QSE_HTB_VPTR(pair));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (str != idxbuf) QSE_AWK_FREE (run->awk, str);
 | 
			
		||||
	if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
 | 
			
		||||
	return (qse_awk_val_t**)&QSE_HTB_VPTR(pair);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_int (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_int (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* val;
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makeintval (run, ((qse_awk_nde_int_t*)nde)->val);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
 | 
			
		||||
	val = qse_awk_rtx_makeintval(rtx, ((qse_awk_nde_int_t*)nde)->val);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
 | 
			
		||||
	else if (QSE_AWK_VTR_IS_POINTER(val)) ((qse_awk_val_int_t*)val)->nde = nde;
 | 
			
		||||
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_real (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_flt (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* val;
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makefltval (run, ((qse_awk_nde_flt_t*)nde)->val);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
 | 
			
		||||
	val = qse_awk_rtx_makefltval(rtx, ((qse_awk_nde_flt_t*)nde)->val);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
 | 
			
		||||
	else ((qse_awk_val_flt_t*)val)->nde = nde;
 | 
			
		||||
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_str (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_str (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* val;
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makestrval (run,
 | 
			
		||||
		((qse_awk_nde_str_t*)nde)->ptr,
 | 
			
		||||
		((qse_awk_nde_str_t*)nde)->len);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makestrval(rtx, ((qse_awk_nde_str_t*)nde)->ptr, ((qse_awk_nde_str_t*)nde)->len);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_mbs (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_mbs (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* val;
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makembsval (run,
 | 
			
		||||
		((qse_awk_nde_mbs_t*)nde)->ptr,
 | 
			
		||||
		((qse_awk_nde_mbs_t*)nde)->len);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makembsval(rtx, ((qse_awk_nde_mbs_t*)nde)->ptr, ((qse_awk_nde_mbs_t*)nde)->len);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_rex (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_val_t* val;
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makerexval (run,
 | 
			
		||||
		&((qse_awk_nde_rex_t*)nde)->str,
 | 
			
		||||
		((qse_awk_nde_rex_t*)nde)->code
 | 
			
		||||
	);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (run, &nde->loc);
 | 
			
		||||
 | 
			
		||||
	val = qse_awk_rtx_makerexval(rtx, &((qse_awk_nde_rex_t*)nde)->str, ((qse_awk_nde_rex_t*)nde)->code);
 | 
			
		||||
	if (val == QSE_NULL) ADJERR_LOC (rtx, &nde->loc);
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_named (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_named (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_htb_pair_t* pair;
 | 
			
		||||
		       
 | 
			
		||||
	pair = qse_htb_search (
 | 
			
		||||
		run->named, 
 | 
			
		||||
		((qse_awk_nde_var_t*)nde)->id.name.ptr, 
 | 
			
		||||
		((qse_awk_nde_var_t*)nde)->id.name.len
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	pair = qse_htb_search (rtx->named, ((qse_awk_nde_var_t*)nde)->id.name.ptr, ((qse_awk_nde_var_t*)nde)->id.name.len);
 | 
			
		||||
	return (pair == QSE_NULL)? qse_awk_val_nil: QSE_HTB_VPTR(pair);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_gbl (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_gbl (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	return RTX_STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa);
 | 
			
		||||
	return RTX_STACK_GBL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_lcl (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_lcl (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	return RTX_STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa);
 | 
			
		||||
	return RTX_STACK_LCL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_arg (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_arg (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	return RTX_STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa);
 | 
			
		||||
	return RTX_STACK_ARG(rtx,((qse_awk_nde_var_t*)nde)->id.idxa);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_indexed (
 | 
			
		||||
	qse_awk_rtx_t* run, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
 | 
			
		||||
static qse_awk_val_t* eval_indexed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* nde, qse_awk_val_t** val)
 | 
			
		||||
{
 | 
			
		||||
	qse_htb_pair_t* pair;
 | 
			
		||||
	qse_char_t* str;
 | 
			
		||||
@ -6357,79 +6296,74 @@ static qse_awk_val_t* eval_indexed (
 | 
			
		||||
 | 
			
		||||
	QSE_ASSERT (val != QSE_NULL);
 | 
			
		||||
 | 
			
		||||
	vtype = QSE_AWK_RTX_GETVALTYPE (run, *val);
 | 
			
		||||
	vtype = QSE_AWK_RTX_GETVALTYPE(rtx, *val);
 | 
			
		||||
	if (vtype == QSE_AWK_VAL_NIL)
 | 
			
		||||
	{
 | 
			
		||||
		qse_awk_val_t* tmp;
 | 
			
		||||
 | 
			
		||||
		tmp = qse_awk_rtx_makemapval (run);
 | 
			
		||||
		tmp = qse_awk_rtx_makemapval(rtx);
 | 
			
		||||
		if (tmp == QSE_NULL)
 | 
			
		||||
		{
 | 
			
		||||
			ADJERR_LOC (run, &nde->loc);
 | 
			
		||||
			ADJERR_LOC (rtx, &nde->loc);
 | 
			
		||||
			return QSE_NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		qse_awk_rtx_refdownval (run, *val);
 | 
			
		||||
		qse_awk_rtx_refdownval (rtx, *val);
 | 
			
		||||
		*val = tmp;
 | 
			
		||||
		qse_awk_rtx_refupval (run, (qse_awk_val_t*)*val);
 | 
			
		||||
		qse_awk_rtx_refupval (rtx, (qse_awk_val_t*)*val);
 | 
			
		||||
	}
 | 
			
		||||
	else if (vtype != QSE_AWK_VAL_MAP) 
 | 
			
		||||
	{
 | 
			
		||||
		SETERR_LOC (run, QSE_AWK_ENOTMAP, &nde->loc);
 | 
			
		||||
		SETERR_LOC (rtx, QSE_AWK_ENOTMAP, &nde->loc);
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QSE_ASSERT (nde->idx != QSE_NULL);
 | 
			
		||||
 | 
			
		||||
	len = QSE_COUNTOF(idxbuf);
 | 
			
		||||
	str = idxnde_to_str (run, nde->idx, idxbuf, &len);
 | 
			
		||||
	str = idxnde_to_str(rtx, nde->idx, idxbuf, &len);
 | 
			
		||||
	if (str == QSE_NULL) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	pair = qse_htb_search ((*(qse_awk_val_map_t**)val)->map, str, len);
 | 
			
		||||
	if (str != idxbuf) QSE_AWK_FREE (run->awk, str);
 | 
			
		||||
	pair = qse_htb_search((*(qse_awk_val_map_t**)val)->map, str, len);
 | 
			
		||||
	if (str != idxbuf) QSE_AWK_FREE (rtx->awk, str);
 | 
			
		||||
 | 
			
		||||
	return (pair == QSE_NULL)? qse_awk_val_nil: 
 | 
			
		||||
	                           (qse_awk_val_t*)QSE_HTB_VPTR(pair);
 | 
			
		||||
	return (pair == QSE_NULL)? qse_awk_val_nil: (qse_awk_val_t*)QSE_HTB_VPTR(pair);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_namedidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_namedidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	qse_awk_nde_var_t* tgt = (qse_awk_nde_var_t*)nde;
 | 
			
		||||
	qse_htb_pair_t* pair;
 | 
			
		||||
 | 
			
		||||
	pair = qse_htb_search (run->named, tgt->id.name.ptr, tgt->id.name.len);
 | 
			
		||||
	pair = qse_htb_search(rtx->named, tgt->id.name.ptr, tgt->id.name.len);
 | 
			
		||||
	if (pair == QSE_NULL)
 | 
			
		||||
	{
 | 
			
		||||
		pair = qse_htb_upsert (run->named, 
 | 
			
		||||
			tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
 | 
			
		||||
		pair = qse_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, qse_awk_val_nil, 0);
 | 
			
		||||
		if (pair == QSE_NULL) 
 | 
			
		||||
		{
 | 
			
		||||
			SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
			SETERR_LOC (rtx, QSE_AWK_ENOMEM, &nde->loc);
 | 
			
		||||
			return QSE_NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		qse_awk_rtx_refupval (run, QSE_HTB_VPTR(pair)); 
 | 
			
		||||
		qse_awk_rtx_refupval (rtx, QSE_HTB_VPTR(pair)); 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return eval_indexed (run, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
 | 
			
		||||
	return eval_indexed (rtx, tgt, (qse_awk_val_t**)&QSE_HTB_VPTR(pair));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_gblidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_gblidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	return eval_indexed (run, (qse_awk_nde_var_t*)nde, 
 | 
			
		||||
		(qse_awk_val_t**)&RTX_STACK_GBL(run,((qse_awk_nde_var_t*)nde)->id.idxa));
 | 
			
		||||
	return eval_indexed(rtx, (qse_awk_nde_var_t*)nde, (qse_awk_val_t**)&RTX_STACK_GBL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_lclidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_lclidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	return eval_indexed (run, (qse_awk_nde_var_t*)nde, 
 | 
			
		||||
		(qse_awk_val_t**)&RTX_STACK_LCL(run,((qse_awk_nde_var_t*)nde)->id.idxa));
 | 
			
		||||
	return eval_indexed(rtx, (qse_awk_nde_var_t*)nde, (qse_awk_val_t**)&RTX_STACK_LCL(rtx,((qse_awk_nde_var_t*)nde)->id.idxa));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_argidx (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
static qse_awk_val_t* eval_argidx (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
 | 
			
		||||
{
 | 
			
		||||
	return eval_indexed (run, (qse_awk_nde_var_t*)nde,
 | 
			
		||||
		(qse_awk_val_t**)&RTX_STACK_ARG(run,((qse_awk_nde_var_t*)nde)->id.idxa));
 | 
			
		||||
	return eval_indexed(rtx, (qse_awk_nde_var_t*)nde, (qse_awk_val_t**)&RTX_STACK_ARG(rtx,((qse_awk_nde_var_t*)nde)->id.idxa));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_awk_val_t* eval_pos (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
 | 
			
		||||
 | 
			
		||||
@ -730,6 +730,16 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case QSE_AWK_NDE_FCV:
 | 
			
		||||
		{
 | 
			
		||||
			qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)nde;
 | 
			
		||||
			PRINT_EXPR (awk, (qse_awk_nde_t*)px->u.fcv.var);
 | 
			
		||||
			PUT_SRCSTR (awk, QSE_T("("));
 | 
			
		||||
			PRINT_EXPR_LIST (awk, px->args);
 | 
			
		||||
			PUT_SRCSTR (awk, QSE_T(")"));
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case QSE_AWK_NDE_GETLINE:
 | 
			
		||||
		{
 | 
			
		||||
			qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)nde;
 | 
			
		||||
@ -1443,6 +1453,15 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			case QSE_AWK_NDE_FCV:
 | 
			
		||||
			{
 | 
			
		||||
				qse_awk_nde_fncall_t* px = (qse_awk_nde_fncall_t*)p;
 | 
			
		||||
				qse_awk_clrpt (awk, px->u.fcv.var);
 | 
			
		||||
				qse_awk_clrpt (awk, px->args);
 | 
			
		||||
				QSE_AWK_FREE (awk, p);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			case QSE_AWK_NDE_GETLINE:
 | 
			
		||||
			{
 | 
			
		||||
				qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)p;
 | 
			
		||||
 | 
			
		||||
@ -206,6 +206,11 @@ struct qse_awk_nde_fncall_t
 | 
			
		||||
			qse_awk_fnc_info_t info;
 | 
			
		||||
			qse_awk_fnc_spec_t spec;
 | 
			
		||||
		} fnc;
 | 
			
		||||
 | 
			
		||||
		struct
 | 
			
		||||
		{
 | 
			
		||||
			qse_awk_nde_var_t* var;
 | 
			
		||||
		} fcv;
 | 
			
		||||
	} u;
 | 
			
		||||
	qse_awk_nde_t* args;
 | 
			
		||||
	qse_size_t nargs;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user