added the builtin function isnil and replaced the backquote operator with it

This commit is contained in:
hyung-hwan 2019-04-26 18:04:57 +00:00
parent bc3173d74a
commit abce018b2f
7 changed files with 66 additions and 58 deletions

View File

@ -2349,7 +2349,7 @@ QSE_EXPORT int qse_awk_rtx_setrec (
);
/**
* The qse_awk_rtx_isnilval(0 function determines if a value
* The qse_awk_rtx_isnilval() function determines if a value
* is a nil value.
*/
QSE_EXPORT int qse_awk_rtx_isnilval (

View File

@ -30,6 +30,7 @@ static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static int fnc_fflush (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static int fnc_typename (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static int fnc_isnil (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
#define A_MAX QSE_TYPE_MAX(int)
@ -59,6 +60,7 @@ 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("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},
@ -1497,6 +1499,20 @@ static int fnc_typename (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
return 0;
}
static int fnc_isnil (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
qse_awk_val_t* a0;
qse_awk_val_t* r;
a0 = qse_awk_rtx_getarg(rtx, 0);
r = qse_awk_rtx_makeintval(rtx, QSE_AWK_RTX_GETVALTYPE(rtx, a0) == QSE_AWK_VAL_NIL);
if (r == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
qse_size_t nargs;

View File

@ -78,7 +78,6 @@ enum tok_t
TOK_MA, /* ~ - match */
TOK_NM, /* !~ - not match */
TOK_LNOT, /* ! - logical negation */
TOK_BQUOTE, /* ` - is-defined */
TOK_PLUS,
TOK_PLUSPLUS,
TOK_MINUS,
@ -3909,7 +3908,6 @@ static qse_awk_nde_t* parse_concat (qse_awk_t* awk, const qse_awk_loc_t* xloc)
/* unary operators */
MATCH(awk,TOK_PLUS) || MATCH(awk,TOK_MINUS) ||
MATCH(awk,TOK_LNOT) || MATCH(awk,TOK_BNOT) ||
MATCH(awk,TOK_BQUOTE) ||
/* increment operators */
MATCH(awk,TOK_PLUSPLUS) || MATCH(awk,TOK_MINUSMINUS) ||
((awk->opt.trait & QSE_AWK_TOLERANT) &&
@ -3979,8 +3977,7 @@ static qse_awk_nde_t* parse_unary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
opcode = (MATCH(awk,TOK_PLUS))? QSE_AWK_UNROP_PLUS:
(MATCH(awk,TOK_MINUS))? QSE_AWK_UNROP_MINUS:
(MATCH(awk,TOK_LNOT))? QSE_AWK_UNROP_LNOT:
(MATCH(awk,TOK_BNOT))? QSE_AWK_UNROP_BNOT:
(MATCH(awk,TOK_BQUOTE))? QSE_AWK_UNROP_DEF: -1;
(MATCH(awk,TOK_BNOT))? QSE_AWK_UNROP_BNOT: -1;
/*if (opcode <= -1) return parse_increment (awk);*/
if (opcode <= -1) return parse_exponent (awk, xloc);
@ -4127,8 +4124,7 @@ static qse_awk_nde_t* parse_unary_exp (qse_awk_t* awk, const qse_awk_loc_t* xloc
opcode = (MATCH(awk,TOK_PLUS))? QSE_AWK_UNROP_PLUS:
(MATCH(awk,TOK_MINUS))? QSE_AWK_UNROP_MINUS:
(MATCH(awk,TOK_LNOT))? QSE_AWK_UNROP_LNOT:
(MATCH(awk,TOK_BNOT))? QSE_AWK_UNROP_BNOT:
(MATCH(awk,TOK_BQUOTE))? QSE_AWK_UNROP_DEF: -1;
(MATCH(awk,TOK_BNOT))? QSE_AWK_UNROP_BNOT: -1;
if (opcode <= -1) return parse_increment (awk, xloc);
@ -6127,7 +6123,6 @@ static int get_symbols (qse_awk_t* awk, qse_cint_t c, qse_awk_tok_t* tok)
{ QSE_T("::"), 2, TOK_DBLCOLON, 0 },
{ QSE_T(":"), 1, TOK_COLON, 0 },
{ QSE_T("?"), 1, TOK_QUEST, 0 },
{ QSE_T("`"), 1, TOK_BQUOTE, 0 },
{ QSE_NULL, 0, 0, 0 }
};

View File

@ -5266,8 +5266,7 @@ static qse_awk_val_t* eval_unary (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
exp->opcode == QSE_AWK_UNROP_PLUS ||
exp->opcode == QSE_AWK_UNROP_MINUS ||
exp->opcode == QSE_AWK_UNROP_LNOT ||
exp->opcode == QSE_AWK_UNROP_BNOT ||
exp->opcode == QSE_AWK_UNROP_DEF);
exp->opcode == QSE_AWK_UNROP_BNOT);
QSE_ASSERT (exp->left->next == QSE_NULL);
left = eval_expression (run, exp->left);
@ -5317,12 +5316,6 @@ static qse_awk_val_t* eval_unary (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
res = (n == 0)? qse_awk_rtx_makeintval (run, l):
qse_awk_rtx_makefltval (run, r);
break;
case QSE_AWK_UNROP_DEF:
/* is defined? */
res = qse_awk_rtx_makeintval (
run, ((QSE_AWK_RTX_GETVALTYPE (rtx, left) == QSE_AWK_VAL_NIL)? 0: 1));
break;
}
exit_func:

View File

@ -96,8 +96,7 @@ enum qse_awk_unrop_type_t
QSE_AWK_UNROP_PLUS,
QSE_AWK_UNROP_MINUS,
QSE_AWK_UNROP_LNOT,
QSE_AWK_UNROP_BNOT,
QSE_AWK_UNROP_DEF /* `, is defined */
QSE_AWK_UNROP_BNOT
};
enum qse_awk_incop_type_t

View File

@ -1214,9 +1214,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
qse_awk_nde_if_t* px = (qse_awk_nde_if_t*)p;
qse_awk_clrpt (awk, px->test);
qse_awk_clrpt (awk, px->then_part);
if (px->else_part != QSE_NULL)
qse_awk_clrpt (awk, px->else_part);
if (px->else_part) qse_awk_clrpt (awk, px->else_part);
QSE_AWK_FREE (awk, p);
break;
}
@ -1233,13 +1231,9 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
case QSE_AWK_NDE_FOR:
{
qse_awk_nde_for_t* px = (qse_awk_nde_for_t*)p;
if (px->init != QSE_NULL)
qse_awk_clrpt (awk, px->init);
if (px->test != QSE_NULL)
qse_awk_clrpt (awk, px->test);
if (px->incr != QSE_NULL)
qse_awk_clrpt (awk, px->incr);
if (px->init) qse_awk_clrpt (awk, px->init);
if (px->test) qse_awk_clrpt (awk, px->test);
if (px->incr) qse_awk_clrpt (awk, px->incr);
qse_awk_clrpt (awk, px->body);
QSE_AWK_FREE (awk, p);
break;
@ -1267,10 +1261,8 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
case QSE_AWK_NDE_RETURN:
{
qse_awk_nde_return_t* px =
(qse_awk_nde_return_t*)p;
if (px->val != QSE_NULL)
qse_awk_clrpt (awk, px->val);
qse_awk_nde_return_t* px = (qse_awk_nde_return_t*)p;
if (px->val) qse_awk_clrpt (awk, px->val);
QSE_AWK_FREE (awk, p);
break;
}
@ -1307,12 +1299,9 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
case QSE_AWK_NDE_PRINT:
case QSE_AWK_NDE_PRINTF:
{
qse_awk_nde_print_t* px =
(qse_awk_nde_print_t*)p;
if (px->args != QSE_NULL)
qse_awk_clrpt (awk, px->args);
if (px->out != QSE_NULL)
qse_awk_clrpt (awk, px->out);
qse_awk_nde_print_t* px = (qse_awk_nde_print_t*)p;
if (px->args) qse_awk_clrpt (awk, px->args);
if (px->out) qse_awk_clrpt (awk, px->out);
QSE_AWK_FREE (awk, p);
break;
}
@ -1423,8 +1412,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
qse_awk_nde_var_t* px = (qse_awk_nde_var_t*)p;
QSE_ASSERT (px->idx != QSE_NULL);
qse_awk_clrpt (awk, px->idx);
if (px->id.name.ptr != QSE_NULL)
QSE_AWK_FREE (awk, px->id.name.ptr);
if (px->id.name.ptr) QSE_AWK_FREE (awk, px->id.name.ptr);
QSE_AWK_FREE (awk, p);
break;
}
@ -1457,12 +1445,9 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
case QSE_AWK_NDE_GETLINE:
{
qse_awk_nde_getline_t* px =
(qse_awk_nde_getline_t*)p;
if (px->var != QSE_NULL)
qse_awk_clrpt (awk, px->var);
if (px->in != QSE_NULL)
qse_awk_clrpt (awk, px->in);
qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)p;
if (px->var) qse_awk_clrpt (awk, px->var);
if (px->in) qse_awk_clrpt (awk, px->in);
QSE_AWK_FREE (awk, p);
break;
}

View File

@ -702,9 +702,8 @@ qse_awk_val_t* qse_awk_rtx_makerefval (
}
else
{
val = (qse_awk_val_ref_t*) QSE_AWK_ALLOC (
rtx->awk, QSE_SIZEOF(qse_awk_val_ref_t));
if (val == QSE_NULL)
val = (qse_awk_val_ref_t*)QSE_AWK_ALLOC(rtx->awk, QSE_SIZEOF(qse_awk_val_ref_t));
if (!val)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
return QSE_NULL;
@ -720,14 +719,12 @@ qse_awk_val_t* qse_awk_rtx_makerefval (
return (qse_awk_val_t*)val;
}
qse_awk_val_t* qse_awk_rtx_makefunval (
qse_awk_rtx_t* rtx, const qse_awk_fun_t* fun)
qse_awk_val_t* qse_awk_rtx_makefunval (qse_awk_rtx_t* rtx, const qse_awk_fun_t* fun)
{
qse_awk_val_fun_t* val;
val = (qse_awk_val_fun_t*) QSE_AWK_ALLOC (
rtx->awk, QSE_SIZEOF(qse_awk_val_fun_t));
if (val == QSE_NULL)
val = (qse_awk_val_fun_t*)QSE_AWK_ALLOC(rtx->awk, QSE_SIZEOF(qse_awk_val_fun_t));
if (!val)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
return QSE_NULL;
@ -870,8 +867,12 @@ void qse_awk_rtx_freeval (qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache)
else QSE_AWK_FREE (rtx->awk, val);
break;
}
}
case QSE_AWK_VAL_FUN:
/* nothing to do */
break;
}
}
}
@ -1008,6 +1009,9 @@ int qse_awk_rtx_valtobool (qse_awk_rtx_t* rtx, const qse_awk_val_t* val)
return QSE_HTB_SIZE(((qse_awk_val_map_t*)val)->map) > 0;
case QSE_AWK_VAL_REF:
return val_ref_to_bool (rtx, (qse_awk_val_ref_t*)val);
case QSE_AWK_VAL_FUN:
/* return always true */
return 1;
}
QSE_ASSERTX (
@ -1512,6 +1516,11 @@ int qse_awk_rtx_valtostr (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_rt
{
return val_ref_to_str(rtx, (qse_awk_val_ref_t*)v, out);
}
case QSE_AWK_VAL_FUN:
{
return qse_awk_rtx_makestrval2(rtx, QSE_T("@@"), 1, ((qse_awk_val_fun_t*)v)->fun->name.ptr, ((qse_awk_val_fun_t*)v)->fun->name.len);
}
}
@ -1742,7 +1751,7 @@ static int val_ref_to_num (qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse
/* A reference value is not able to point to another
* refernce value for the way values are represented
* in QSEAWK */
QSE_ASSERT (QSE_AWK_RTX_GETVALTYPE (rtx, *xref) != QSE_AWK_VAL_REF);
QSE_ASSERT (QSE_AWK_RTX_GETVALTYPE(rtx, *xref) != QSE_AWK_VAL_REF);
/* make a recursive call back to the caller */
return qse_awk_rtx_valtonum(rtx, *xref, l, r);
@ -1804,12 +1813,19 @@ int qse_awk_rtx_valtonum (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_in
*l = QSE_HTB_SIZE(((qse_awk_val_map_t*)v)->map);
return 0; /* long */
}
break;
}
case QSE_AWK_VAL_REF:
{
return val_ref_to_num(rtx, (qse_awk_val_ref_t*)v, l, r);
}
case QSE_AWK_VAL_FUN:
{
/* TODO: */
break;
}
}
#ifdef DEBUG_VAL
@ -2131,7 +2147,7 @@ void qse_awk_dprintval (qse_awk_rtx_t* run, qse_awk_val_t* val)
break;
case QSE_AWK_VAL_REX:
qse_errputstrf (QSE_T("REX[%s]"), ((qse_awk_val_rex_t*)val)->ptr);
qse_errputstrf (QSE_T("/%s/"), ((qse_awk_val_rex_t*)val)->ptr);
break;
case QSE_AWK_VAL_MAP:
@ -2139,13 +2155,17 @@ void qse_awk_dprintval (qse_awk_rtx_t* run, qse_awk_val_t* val)
qse_htb_walk (((qse_awk_val_map_t*)val)->map, print_pair, run);
qse_errputstrf (QSE_T("]"));
break;
case QSE_AWK_VAL_REF:
qse_errputstrf (QSE_T("REF[id=%d,val="), ((qse_awk_val_ref_t*)val)->id);
qse_awk_dprintval (run, *((qse_awk_val_ref_t*)val)->adr);
qse_errputstrf (QSE_T("]"));
break;
case QSE_AWK_VAL_FUN:
qse_errputstrf (QSE_T("@@%.*s"), (int)((qse_awk_val_fun_t*)val)->fun->name.len, ((qse_awk_val_fun_t*)val)->fun->name.ptr);
break;
default:
qse_errputstrf (QSE_T("**** INTERNAL ERROR - INVALID VALUE TYPE ****\n"));
}