redefined qse_awk_mmgr(), qse_awk_getcmgr(), qse_setcmgr() by exposing the mmgr/cmgr fields via qse_awk_alt_t.

implemented comparison operations for the fun value.
changed behavior of some comparison operations that would otherwise result in a runtime error
This commit is contained in:
hyung-hwan 2019-04-30 07:23:34 +00:00
parent 3368c91834
commit b3d63c259b
10 changed files with 424 additions and 205 deletions

View File

@ -219,14 +219,13 @@ static qse_htb_walk_t print_awk_value (
return QSE_HTB_WALK_FORWARD;
}
static qse_htb_walk_t set_global (
qse_htb_t* map, qse_htb_pair_t* pair, void* arg)
static qse_htb_walk_t set_global (qse_htb_t* map, qse_htb_pair_t* pair, void* arg)
{
qse_awk_val_t* v;
qse_awk_rtx_t* rtx = (qse_awk_rtx_t*)arg;
struct gvmv_t* gvmv = (struct gvmv_t*)QSE_HTB_VPTR(pair);
v = qse_awk_rtx_makenstrvalwithxstr (rtx, &gvmv->str);
v = qse_awk_rtx_makenstrvalwithxstr(rtx, &gvmv->str);
if (v == QSE_NULL) return QSE_HTB_WALK_STOP;
qse_awk_rtx_refupval (rtx, v);

View File

@ -91,6 +91,17 @@ typedef qse_flt_t qse_awk_flt_t;
*/
typedef struct qse_awk_t qse_awk_t;
#define QSE_AWK_HDR \
qse_mmgr_t* mmgr; \
qse_cmgr_t* cmgr
typedef struct qse_awk_alt_t qse_awk_alt_t;
struct qse_awk_alt_t
{
/* ensure that qse_awk_alt_t matches the beginning part of qse_awk_t */
QSE_AWK_HDR;
};
/** \struct qse_awk_rtx_t
* The #qse_awk_rtx_t type defines a runtime context. A runtime context
* maintains runtime state for a running script. You can create multiple
@ -1401,7 +1412,7 @@ typedef enum qse_awk_gbl_id_t qse_awk_gbl_id_t;
*/
enum qse_awk_val_type_t
{
/* the values between QSE_AWK_VAL_NIL and QSE_AWK_VAL_MAP inclusive
/* the values between QSE_AWK_VAL_NIL and QSE_AWK_VAL_FUN inclusive
* must be synchronized with an internal table of the __cmp_val
* function in run.c and the __val_type_name in val.c */
QSE_AWK_VAL_NIL = 0, /**< nil */
@ -1409,11 +1420,11 @@ enum qse_awk_val_type_t
QSE_AWK_VAL_FLT = 2, /**< floating-pointer number */
QSE_AWK_VAL_STR = 3, /**< string */
QSE_AWK_VAL_MBS = 4, /**< byte array */
QSE_AWK_VAL_MAP = 5, /**< map */
QSE_AWK_VAL_FUN = 5, /**< function pointer */
QSE_AWK_VAL_MAP = 6, /**< map */
QSE_AWK_VAL_REX = 6, /**< regular expression */
QSE_AWK_VAL_REF = 7, /**< reference to other types */
QSE_AWK_VAL_FUN = 8
QSE_AWK_VAL_REX = 7, /**< regular expression */
QSE_AWK_VAL_REF = 8 /**< reference to other types */
};
typedef enum qse_awk_val_type_t qse_awk_val_type_t;
@ -1525,9 +1536,15 @@ QSE_EXPORT void qse_awk_close (
* The qse_awk_getmmgr() function gets the memory manager used in
* qse_awk_open().
*/
QSE_EXPORT qse_mmgr_t* qse_awk_getmmgr (
qse_awk_t* awk
);
#if defined(MOO_HAVE_INLINE)
static MOO_INLINE qse_mmgr_t* qse_awk_getmmgr (qse_awk_t* awk) { return awk->mmgr; }
static MOO_INLINE qse_cmgr_t* qse_awk_getcmgr (qse_awk_t* awk) { return awk->cmgr; }
static MOO_INLINE void qse_setcmgr (qse_awk_t* awk, qse_awk_cmgr_t* cmgr) { awk->cmgr = cmgr; }
#else
# define qse_awk_getmmgr(awk) (((qse_awk_alt_t*)(awk))->mmgr)
# define qse_awk_getcmgr(awk) (((qse_awk_alt_t*)(awk))->cmgr)
# define qse_awk_setcmgr(awk,mgr) (((qse_awk_alt_t*)(awk))->cmgr = (mgr))
#endif
/**
* The qse_awk_getxtn() function gets the poniter to the beginning

View File

@ -166,8 +166,8 @@ struct qse_awk_tok_t
struct qse_awk_t
{
qse_mmgr_t* mmgr;
qse_cmgr_t* cmgr;
/* exposed fields via qse_awk_alt_t */
QSE_AWK_HDR;
/* primitive functions */
qse_awk_prm_t prm;

View File

@ -348,9 +348,9 @@ void qse_awk_clear (qse_awk_t* awk)
awk->parse.depth.expr = 0;
awk->parse.depth.incl = 0;
/* clear parse trees */
/* clear parse trees */
/*awk->tree.ngbls_base = 0;
awk->tree.ngbls = 0; */
awk->tree.ngbls = 0; */
awk->tree.ngbls = awk->tree.ngbls_base;
awk->tree.cur_fun.ptr = QSE_NULL;
@ -362,7 +362,7 @@ void qse_awk_clear (qse_awk_t* awk)
/*QSE_ASSERT (awk->tree.begin->next == QSE_NULL);*/
qse_awk_clrpt (awk, awk->tree.begin);
awk->tree.begin = QSE_NULL;
awk->tree.begin_tail = QSE_NULL;
awk->tree.begin_tail = QSE_NULL;
}
if (awk->tree.end != QSE_NULL)
@ -370,7 +370,7 @@ void qse_awk_clear (qse_awk_t* awk)
/*QSE_ASSERT (awk->tree.end->next == QSE_NULL);*/
qse_awk_clrpt (awk, awk->tree.end);
awk->tree.end = QSE_NULL;
awk->tree.end_tail = QSE_NULL;
awk->tree.end_tail = QSE_NULL;
}
while (awk->tree.chain != QSE_NULL)
@ -395,11 +395,6 @@ void qse_awk_clear (qse_awk_t* awk)
*/
}
qse_mmgr_t* qse_awk_getmmgr (qse_awk_t* awk)
{
return awk->mmgr;
}
void* qse_awk_getxtn (qse_awk_t* awk)
{
return QSE_XTN (awk);
@ -419,13 +414,13 @@ static int dup_str_opt (qse_awk_t* awk, const void* value, qse_cstr_t* tmp)
{
if (value)
{
tmp->ptr = qse_strdup (value, awk->mmgr);
if (tmp->ptr == QSE_NULL)
tmp->ptr = qse_strdup(value, awk->mmgr);
if (!tmp->ptr)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return -1;
}
tmp->len = qse_strlen (tmp->ptr);
tmp->len = qse_strlen(tmp->ptr);
}
else
{

View File

@ -594,7 +594,7 @@ int qse_awk_fnc_length (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
default:
/* convert to string and get length */
str = qse_awk_rtx_valtostrdup (rtx, v, &len);
str = qse_awk_rtx_valtostrdup(rtx, v, &len);
if (str == QSE_NULL) return -1;
QSE_AWK_FREE (rtx->awk, str);
}
@ -1517,7 +1517,6 @@ static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
qse_size_t nargs;
qse_awk_val_t* a0;
qse_awk_int_t lv;
qse_awk_val_t* r;
int n;
@ -1527,12 +1526,7 @@ static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
a0 = qse_awk_rtx_getarg(rtx, 0);
n = qse_awk_rtx_valtoint(rtx, a0, &lv);
if (n <= -1) return -1;
r = qse_awk_rtx_makeintval(rtx, lv);
if (r == QSE_NULL) return -1;
r = qse_awk_rtx_makeintval(rtx, QSE_AWK_RTX_GETVALTYPE(rtx, a0) == QSE_AWK_VAL_NIL);
qse_awk_rtx_setretval (rtx, r);
return 0;
}

View File

@ -36,14 +36,14 @@
void* qse_awk_allocmem (qse_awk_t* awk, qse_size_t size)
{
void* ptr = QSE_AWK_ALLOC (awk, size);
void* ptr = QSE_AWK_ALLOC(awk, size);
if (ptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return ptr;
}
void* qse_awk_callocmem (qse_awk_t* awk, qse_size_t size)
{
void* ptr = QSE_AWK_ALLOC (awk, size);
void* ptr = QSE_AWK_ALLOC(awk, size);
if (ptr) QSE_MEMSET (ptr, 0, size);
else qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return ptr;
@ -51,8 +51,8 @@ void* qse_awk_callocmem (qse_awk_t* awk, qse_size_t size)
void* qse_awk_reallocmem (qse_awk_t* awk, void* ptr, qse_size_t size)
{
void* nptr = QSE_AWK_REALLOC (awk, ptr, size);
if (nptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
void* nptr = QSE_AWK_REALLOC(awk, ptr, size);
if (!nptr) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return nptr;
}
@ -63,22 +63,22 @@ void qse_awk_freemem (qse_awk_t* awk, void* ptr)
qse_char_t* qse_awk_strdup (qse_awk_t* awk, const qse_char_t* s)
{
qse_char_t* ptr = QSE_AWK_STRDUP (awk, s);
if (ptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
qse_char_t* ptr = QSE_AWK_STRDUP(awk, s);
if (!ptr) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return ptr;
}
qse_char_t* qse_awk_strxdup (qse_awk_t* awk, const qse_char_t* s, qse_size_t l)
{
qse_char_t* ptr = QSE_AWK_STRXDUP (awk, s, l);
if (ptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
qse_char_t* ptr = QSE_AWK_STRXDUP(awk, s, l);
if (!ptr) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return ptr;
}
qse_char_t* qse_awk_cstrdup (qse_awk_t* awk, const qse_cstr_t* s)
{
qse_char_t* ptr = qse_cstrdup (s, awk->mmgr);
if (ptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
qse_char_t* ptr = qse_cstrdup(s, awk->mmgr);
if (!ptr) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return ptr;
}

View File

@ -4252,8 +4252,10 @@ static qse_awk_nde_t* parse_increment (qse_awk_t* awk, const qse_awk_loc_t* xloc
#define FNTYPE_FNC 1
#define FNTYPE_FUN 2
static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name)
static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_fun_t** fun)
{
qse_htb_pair_t* pair;
/* check if it is an awk function being processed currently */
if (awk->tree.cur_fun.ptr)
{
@ -4265,14 +4267,20 @@ 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)
pair = qse_htb_search(awk->tree.funs, name->ptr, name->len);
if (pair)
{
/* one of the functions defined previously */
if (fun)
{
*fun = (qse_awk_fun_t*)QSE_HTB_VPTR(pair);
QSE_ASSERT (*fun != QSE_NULL);
}
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))
{
/* one of the function calls not resolved so far. */
return FNTYPE_FUN;
@ -4289,7 +4297,7 @@ static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_cstr_t* name)
return FNTYPE_FNC;
}
return isfunname(awk, name);
return isfunname(awk, name, QSE_NULL);
}
static qse_awk_nde_t* parse_primary_int (qse_awk_t* awk, const qse_awk_loc_t* xloc)
@ -4981,7 +4989,7 @@ oops:
}
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
static qse_awk_nde_t* parse_fun_as_value (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc)
static qse_awk_nde_t* parse_fun_as_value (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_loc_t* xloc, qse_awk_fun_t* funptr)
{
qse_awk_nde_fun_t* nde;
@ -4997,6 +5005,7 @@ static qse_awk_nde_t* parse_fun_as_value (qse_awk_t* awk, const qse_cstr_t* nam
nde->loc = *xloc;
nde->name.ptr = name->ptr;
nde->name.len = name->len;
nde->funptr = funptr;
return (qse_awk_nde_t*)nde;
@ -5067,8 +5076,9 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
else
{
int fntype;
qse_awk_fun_t* funptr = QSE_NULL;
fntype = isfunname(awk, name);
fntype = isfunname(awk, name, &funptr);
if (fntype)
{
@ -5084,7 +5094,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (qse_awk_t* awk, const qse_awk_l
{
/* function name appeared without () */
#if defined(ENABLE_FEATURE_FUN_AS_VALUE)
nde = parse_fun_as_value(awk, name, xloc);
nde = parse_fun_as_value(awk, name, xloc, funptr);
#else
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
#endif

View File

@ -4188,46 +4188,106 @@ static qse_awk_val_t* eval_binop_band (
return qse_awk_rtx_makeintval (rtx, l1 & l2);
}
static QSE_INLINE int __cmp_nil_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
/* -------------------------------------------------------------------- */
enum cmp_op_t
{
CMP_OP_EQ = 0,
CMP_OP_NE = 1,
CMP_OP_GT = 2,
CMP_OP_GE = 3,
CMP_OP_LT = 4,
CMP_OP_LE = 5
};
typedef enum cmp_op_t cmp_op_t;
static QSE_INLINE cmp_op_t inverse_cmp_op (cmp_op_t op)
{
static cmp_op_t inverse_cmp_op_tab[] =
{
CMP_OP_NE,
CMP_OP_EQ,
CMP_OP_LT,
CMP_OP_LE,
CMP_OP_GT,
CMP_OP_GE
};
return inverse_cmp_op_tab[op];
}
static QSE_INLINE int __cmp_ensure_not_equal (cmp_op_t op_hint)
{
/* checking equality is mostly obvious. however, it is not possible
* to test if one is less/greater than the other for some operands.
* this function return a number that ensures to make NE to true and
* all other operations false */
switch (op_hint)
{
case CMP_OP_EQ:
case CMP_OP_NE:
return 1; /* not equal */
case CMP_OP_GT:
case CMP_OP_LT:
return 0; /* make GT or LT to be false by claiming equal */
case CMP_OP_GE:
return -1; /* make GE false by claiming less */
case CMP_OP_LE:
return 1; /* make LE false by claiming greater */
}
}
/* -------------------------------------------------------------------- */
static QSE_INLINE int __cmp_nil_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return 0;
}
static QSE_INLINE int __cmp_nil_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_nil_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_int_t v = QSE_AWK_RTX_GETINTFROMVAL (rtx, right);
return (v < 0)? 1: ((v > 0)? -1: 0);
}
static QSE_INLINE int __cmp_nil_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_nil_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
if (((qse_awk_val_flt_t*)right)->val < 0) return 1;
if (((qse_awk_val_flt_t*)right)->val > 0) return -1;
return 0;
}
static QSE_INLINE int __cmp_nil_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_nil_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return (((qse_awk_val_str_t*)right)->val.len == 0)? 0: -1;
}
static QSE_INLINE int __cmp_nil_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_nil_mbs (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return (((qse_awk_val_mbs_t*)right)->val.len == 0)? 0: -1;
}
static QSE_INLINE int __cmp_nil_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_nil_fun (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* != -> true, all others -> false */
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_nil_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return (QSE_HTB_SIZE(((qse_awk_val_map_t*)right)->map) == 0)? 0: -1;
}
static QSE_INLINE int __cmp_int_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
/* -------------------------------------------------------------------- */
static QSE_INLINE int __cmp_int_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_int_t v = QSE_AWK_RTX_GETINTFROMVAL(rtx, left);
return (v > 0)? 1: ((v < 0)? -1: 0);
}
static QSE_INLINE int __cmp_int_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_int_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_int_t v1 = QSE_AWK_RTX_GETINTFROMVAL(rtx, left);
@ -4236,7 +4296,7 @@ static QSE_INLINE int __cmp_int_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qs
}
static QSE_INLINE int __cmp_int_flt (
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_int_t v1 = QSE_AWK_RTX_GETINTFROMVAL (rtx, left);
if (v1 > ((qse_awk_val_flt_t*)right)->val) return 1;
@ -4244,9 +4304,10 @@ static QSE_INLINE int __cmp_int_flt (
return 0;
}
static QSE_INLINE int __cmp_int_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_int_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_rtx_valtostr_out_t out;
qse_char_t* str0;
qse_size_t len0;
int n;
/* SCO CC doesn't seem to handle right->nstr > 0 properly */
@ -4263,7 +4324,7 @@ static QSE_INLINE int __cmp_int_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qs
&ll, &rr
);
v1 = QSE_AWK_RTX_GETINTFROMVAL (rtx, left);
v1 = QSE_AWK_RTX_GETINTFROMVAL(rtx, left);
if (n == 0)
{
/* a numeric integral string */
@ -4276,40 +4337,76 @@ static QSE_INLINE int __cmp_int_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qs
}
}
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
if (qse_awk_rtx_valtostr(rtx, left, &out) <= -1) return CMP_ERROR;
str0 = qse_awk_rtx_valtostrdup(rtx, left, &len0);
if (!str0) return CMP_ERROR;
if (rtx->gbl.ignorecase)
{
n = qse_strxncasecmp(
out.u.cpldup.ptr,
out.u.cpldup.len,
((qse_awk_val_str_t*)right)->val.ptr,
((qse_awk_val_str_t*)right)->val.len
);
n = qse_strxncasecmp(str0, len0, ((qse_awk_val_str_t*)right)->val.ptr, ((qse_awk_val_str_t*)right)->val.len);
}
else
{
n = qse_strxncmp(
out.u.cpldup.ptr,
out.u.cpldup.len,
((qse_awk_val_str_t*)right)->val.ptr,
((qse_awk_val_str_t*)right)->val.len
);
n = qse_strxncmp(str0, len0, ((qse_awk_val_str_t*)right)->val.ptr, ((qse_awk_val_str_t*)right)->val.len);
}
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
qse_awk_rtx_freemem (rtx, str0);
return n;
}
static QSE_INLINE int __cmp_int_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_int_mbs (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* can't compare an integer with a byte array */
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return CMP_ERROR;
qse_mchar_t* str0;
qse_size_t len0;
int n;
if (rtx->awk->opt.trait & QSE_AWK_NCMPONSTR || right->nstr /*> 0*/)
{
qse_awk_int_t ll, v1;
qse_awk_flt_t rr;
n = qse_awk_rtx_mbstonum (
rtx,
QSE_AWK_RTX_STRTONUM_MAKE_OPTION(1, 0),
((qse_awk_val_mbs_t*)right)->val.ptr,
((qse_awk_val_mbs_t*)right)->val.len,
&ll, &rr
);
v1 = QSE_AWK_RTX_GETINTFROMVAL(rtx, left);
if (n == 0)
{
/* a numeric integral string */
return (v1 > ll)? 1: ((v1 < ll)? -1: 0);
}
else if (n > 0)
{
/* a numeric floating-point string */
return (v1 > rr)? 1: ((v1 < rr)? -1: 0);
}
}
str0 = qse_awk_rtx_valtombsdup(rtx, left, &len0);
if (!str0) return QSE_NULL;
if (rtx->gbl.ignorecase)
{
n = qse_mbsxncasecmp(str0, len0, ((qse_awk_val_mbs_t*)right)->val.ptr, ((qse_awk_val_mbs_t*)right)->val.len);
}
else
{
n = qse_mbsxncmp(str0, len0, ((qse_awk_val_mbs_t*)right)->val.ptr, ((qse_awk_val_mbs_t*)right)->val.len);
}
qse_awk_rtx_freemem (rtx, str0);
return n;
}
static QSE_INLINE int __cmp_int_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_int_fun (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_int_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* compare an integer and the size of a map */
qse_awk_int_t v1 = QSE_AWK_RTX_GETINTFROMVAL(rtx, left);
@ -4319,14 +4416,16 @@ static QSE_INLINE int __cmp_int_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qs
return 0;
}
static QSE_INLINE int __cmp_flt_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
/* -------------------------------------------------------------------- */
static QSE_INLINE int __cmp_flt_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
if (((qse_awk_val_flt_t*)left)->val > 0) return 1;
if (((qse_awk_val_flt_t*)left)->val < 0) return -1;
return 0;
}
static int __cmp_flt_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_flt_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_int_t v2 = QSE_AWK_RTX_GETINTFROMVAL (rtx, right);
if (((qse_awk_val_flt_t*)left)->val > v2) return 1;
@ -4334,7 +4433,7 @@ static int __cmp_flt_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t
return 0;
}
static int __cmp_flt_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_flt_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
if (((qse_awk_val_flt_t*)left)->val >
((qse_awk_val_flt_t*)right)->val) return 1;
@ -4343,9 +4442,10 @@ static int __cmp_flt_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t
return 0;
}
static int __cmp_flt_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_flt_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_rtx_valtostr_out_t out;
qse_char_t* str0;
qse_size_t len0;
int n;
/* SCO CC doesn't seem to handle right->nstr > 0 properly */
@ -4354,54 +4454,71 @@ static int __cmp_flt_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t
const qse_char_t* end;
qse_awk_flt_t rr;
rr = qse_awk_strxtoflt (
rtx->awk,
((qse_awk_val_str_t*)right)->val.ptr,
((qse_awk_val_str_t*)right)->val.len,
&end
);
if (end == ((qse_awk_val_str_t*)right)->val.ptr +
((qse_awk_val_str_t*)right)->val.len)
rr = qse_awk_strxtoflt(rtx->awk, ((qse_awk_val_str_t*)right)->val.ptr, ((qse_awk_val_str_t*)right)->val.len, &end);
if (end == ((qse_awk_val_str_t*)right)->val.ptr + ((qse_awk_val_str_t*)right)->val.len)
{
return (((qse_awk_val_flt_t*)left)->val > rr)? 1:
(((qse_awk_val_flt_t*)left)->val < rr)? -1: 0;
}
}
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
if (qse_awk_rtx_valtostr(rtx, left, &out) <= -1) return CMP_ERROR;
str0 = qse_awk_rtx_valtostrdup(rtx, left, &len0);
if (!str0) return CMP_ERROR;
if (rtx->gbl.ignorecase)
{
n = qse_strxncasecmp (
out.u.cpldup.ptr,
out.u.cpldup.len,
((qse_awk_val_str_t*)right)->val.ptr,
((qse_awk_val_str_t*)right)->val.len
);
n = qse_strxncasecmp(str0, len0, ((qse_awk_val_str_t*)right)->val.ptr, ((qse_awk_val_str_t*)right)->val.len);
}
else
{
n = qse_strxncmp (
out.u.cpldup.ptr,
out.u.cpldup.len,
((qse_awk_val_str_t*)right)->val.ptr,
((qse_awk_val_str_t*)right)->val.len
);
n = qse_strxncmp(str0, len0, ((qse_awk_val_str_t*)right)->val.ptr, ((qse_awk_val_str_t*)right)->val.len);
}
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
qse_awk_rtx_freemem (rtx, str0);
return n;
}
static int __cmp_flt_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_flt_mbs (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* can't compare a float with a byte array */
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return CMP_ERROR;
qse_mchar_t* str0;
qse_size_t len0;
int n;
if (rtx->awk->opt.trait & QSE_AWK_NCMPONSTR || right->nstr /*> 0*/)
{
const qse_mchar_t* end;
qse_awk_flt_t rr;
rr = qse_awk_mbsxtoflt(rtx->awk, ((qse_awk_val_mbs_t*)right)->val.ptr, ((qse_awk_val_mbs_t*)right)->val.len, &end);
if (end == ((qse_awk_val_mbs_t*)right)->val.ptr + ((qse_awk_val_mbs_t*)right)->val.len)
{
return (((qse_awk_val_flt_t*)left)->val > rr)? 1:
(((qse_awk_val_flt_t*)left)->val < rr)? -1: 0;
}
}
str0 = qse_awk_rtx_valtombsdup(rtx, left, &len0);
if (!str0) return CMP_ERROR;
if (rtx->gbl.ignorecase)
{
n = qse_mbsxncasecmp(str0, len0, ((qse_awk_val_mbs_t*)right)->val.ptr, ((qse_awk_val_mbs_t*)right)->val.len);
}
else
{
n = qse_mbsxncmp(str0, len0, ((qse_awk_val_mbs_t*)right)->val.ptr, ((qse_awk_val_mbs_t*)right)->val.len);
}
qse_awk_rtx_freemem (rtx, str0);
return n;
}
static QSE_INLINE int __cmp_flt_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_flt_fun (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_flt_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* compare a float with the size of a map */
qse_awk_int_t v2 = QSE_HTB_SIZE(((qse_awk_val_map_t*)right)->map);
@ -4410,22 +4527,30 @@ static QSE_INLINE int __cmp_flt_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qs
return 0;
}
static QSE_INLINE int __cmp_str_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
/* -------------------------------------------------------------------- */
static QSE_INLINE int __cmp_str_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return (((qse_awk_val_str_t*)left)->val.len == 0)? 0: 1;
}
static QSE_INLINE int __cmp_str_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_str_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_int_str(rtx, right, left);
int n;
n = __cmp_int_str(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_str_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_str_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_flt_str (rtx, right, left);
int n;
n = __cmp_flt_str(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_str_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_str_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_val_str_t* ls, * rs;
@ -4498,7 +4623,7 @@ static QSE_INLINE int __cmp_str_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qs
}
}
static QSE_INLINE int __cmp_str_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_str_mbs (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_val_str_t* ls = (qse_awk_val_str_t*)left;
qse_awk_val_mbs_t* rs = (qse_awk_val_mbs_t*)right;
@ -4526,34 +4651,48 @@ static QSE_INLINE int __cmp_str_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t* left
#endif
}
static QSE_INLINE int __cmp_str_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_str_fun (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* can't compare a map with a string */
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return CMP_ERROR;
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_bytearr_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_str_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
/* -------------------------------------------------------------------- */
static QSE_INLINE int __cmp_mbs_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return (((qse_awk_val_mbs_t*)left)->val.len == 0)? 0: 1;
}
static QSE_INLINE int __cmp_bytearr_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_mbs_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_int_bytearr(rtx, right, left);
int n;
n = __cmp_int_mbs(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_bytearr_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_mbs_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_flt_bytearr(rtx, right, left);
int n;
n = __cmp_flt_mbs(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_bytearr_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_mbs_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_str_bytearr(rtx, right, left);
int n;
n = __cmp_str_mbs(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_bytearr_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_mbs_mbs (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_val_mbs_t* ls = (qse_awk_val_mbs_t*)left;
qse_awk_val_mbs_t* rs = (qse_awk_val_mbs_t*)right;
@ -4563,66 +4702,119 @@ static QSE_INLINE int __cmp_bytearr_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t*
return qse_mbsxncmp(ls->val.ptr, ls->val.len, rs->val.ptr, rs->val.len);
}
static QSE_INLINE int __cmp_bytearr_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_mbs_fun (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* can't compare a byte array with a map */
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return CMP_ERROR;
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_mbs_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_nil_map (rtx, right, left);
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
/* -------------------------------------------------------------------- */
static QSE_INLINE int __cmp_fun_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_int_map (rtx, right, left);
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_fun_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return -__cmp_flt_map (rtx, right, left);
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_fun_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* can't compare a map with a string */
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return CMP_ERROR;
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_bytearr (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_fun_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* can't compare a map with a byte array */
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return CMP_ERROR;
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_fun_mbs (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_fun_fun (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return (((qse_awk_val_fun_t*)left)->fun == ((qse_awk_val_fun_t*)right)->fun)? 0: __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_fun_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
/* -------------------------------------------------------------------- */
static QSE_INLINE int __cmp_map_nil (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
int n;
n = __cmp_nil_map(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_map_int (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
int n;
n = __cmp_int_map(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_map_flt (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
int n;
n = __cmp_flt_map(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static QSE_INLINE int __cmp_map_str (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_mbs (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_fun (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(op_hint);
}
static QSE_INLINE int __cmp_map_map (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
/* can't compare a map with a map */
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return CMP_ERROR;
}
/* -------------------------------------------------------------------- */
static int __cmp_val(
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
static QSE_INLINE int __cmp_val(qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right, cmp_op_t op_hint)
{
qse_awk_val_type_t lvtype, rvtype;
typedef int (*cmp_val_t) (qse_awk_rtx_t*, qse_awk_val_t*, qse_awk_val_t*);
typedef int (*cmp_val_t) (qse_awk_rtx_t*, qse_awk_val_t*, qse_awk_val_t*, cmp_op_t op_hint);
static cmp_val_t func[] =
{
/* this table must be synchronized with
* the QSE_AWK_VAL_XXX values in awk.h */
__cmp_nil_nil, __cmp_nil_int, __cmp_nil_flt, __cmp_nil_str, __cmp_nil_bytearr, __cmp_nil_map,
__cmp_int_nil, __cmp_int_int, __cmp_int_flt, __cmp_int_str, __cmp_int_bytearr, __cmp_int_map,
__cmp_flt_nil, __cmp_flt_int, __cmp_flt_flt, __cmp_flt_str, __cmp_flt_bytearr, __cmp_flt_map,
__cmp_str_nil, __cmp_str_int, __cmp_str_flt, __cmp_str_str, __cmp_str_bytearr, __cmp_str_map,
__cmp_bytearr_nil, __cmp_bytearr_int, __cmp_bytearr_flt, __cmp_bytearr_str, __cmp_bytearr_bytearr, __cmp_bytearr_map,
__cmp_map_nil, __cmp_map_int, __cmp_map_flt, __cmp_map_str, __cmp_map_bytearr, __cmp_map_map
__cmp_nil_nil, __cmp_nil_int, __cmp_nil_flt, __cmp_nil_str, __cmp_nil_mbs, __cmp_nil_fun, __cmp_nil_map,
__cmp_int_nil, __cmp_int_int, __cmp_int_flt, __cmp_int_str, __cmp_int_mbs, __cmp_int_fun, __cmp_int_map,
__cmp_flt_nil, __cmp_flt_int, __cmp_flt_flt, __cmp_flt_str, __cmp_flt_mbs, __cmp_flt_fun, __cmp_flt_map,
__cmp_str_nil, __cmp_str_int, __cmp_str_flt, __cmp_str_str, __cmp_str_mbs, __cmp_str_fun, __cmp_str_map,
__cmp_mbs_nil, __cmp_mbs_int, __cmp_mbs_flt, __cmp_mbs_str, __cmp_mbs_mbs, __cmp_mbs_fun, __cmp_mbs_map,
__cmp_fun_nil, __cmp_fun_int, __cmp_fun_flt, __cmp_fun_str, __cmp_fun_mbs, __cmp_fun_fun, __cmp_fun_map,
__cmp_map_nil, __cmp_map_int, __cmp_map_flt, __cmp_map_str, __cmp_map_mbs, __cmp_map_fun, __cmp_map_map
};
lvtype = QSE_AWK_RTX_GETVALTYPE(rtx, left);
@ -4639,14 +4831,20 @@ static int __cmp_val(
QSE_ASSERT (rvtype >= QSE_AWK_VAL_NIL && rvtype <= QSE_AWK_VAL_MAP);
/* mapping fomula and table layout assume:
* QSE_AWK_VAL_NIL = 0
* QSE_AWK_VAL_INT = 1
* QSE_AWK_VAL_FLT = 2
* QSE_AWK_VAL_STR = 3
* QSE_AWK_VAL_MBS = 4
* QSE_AWK_VAL_MAP = 5
* QSE_AWK_VAL_NIL = 0
* QSE_AWK_VAL_INT = 1
* QSE_AWK_VAL_FLT = 2
* QSE_AWK_VAL_STR = 3
* QSE_AWK_VAL_MBS = 4
* QSE_AWK_VAL_FUN = 5
* QSE_AWK_VAL_MAP = 6
*
* op_hint indicate the operation in progress when this function is called.
* this hint doesn't require the comparison function to compare using this
* operation. the comparision function should return 0 if equal, -1 if less,
* 1 if greater, CMP_ERROR upon error regardless of this hint.
*/
return func[lvtype * 6 + rvtype](rtx, left, right);
return func[lvtype * 7 + rvtype](rtx, left, right, op_hint);
}
static int teq_val (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
@ -4693,6 +4891,10 @@ static int teq_val (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* righ
((qse_awk_val_mbs_t*)right)->val.len) == 0;
break;
case QSE_AWK_VAL_FUN:
n = ((qse_awk_val_fun_t*)left)->fun == ((qse_awk_val_fun_t*)right)->fun;
break;
default:
/* map-x and map-y are always different regardless of
* their contents. however, if they are pointing to the
@ -4709,52 +4911,52 @@ static int teq_val (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* righ
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;
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)
{
return teq_val (rtx, left, right)? QSE_AWK_VAL_ZERO: QSE_AWK_VAL_ONE;
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)
{
int n = __cmp_val(rtx, left, right);
int n = __cmp_val(rtx, left, right, CMP_OP_EQ);
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)
{
int n = __cmp_val(rtx, left, right);
int n = __cmp_val(rtx, left, right, CMP_OP_NE);
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)
{
int n = __cmp_val(rtx, left, right);
int n = __cmp_val(rtx, left, right, CMP_OP_GT);
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)
{
int n = __cmp_val(rtx, left, right);
int n = __cmp_val(rtx, left, right, CMP_OP_GE);
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)
{
int n = __cmp_val(rtx, left, right);
int n = __cmp_val(rtx, left, right, CMP_OP_LT);
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)
{
int n = __cmp_val(rtx, left, right);
int n = __cmp_val(rtx, left, right, CMP_OP_LE);
if (n == CMP_ERROR) return QSE_NULL;
return (n <= 0)? QSE_AWK_VAL_ONE: QSE_AWK_VAL_ZERO;
}
@ -6267,11 +6469,13 @@ static qse_awk_val_t* eval_fun (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
{
qse_awk_val_t* val;
qse_awk_fun_t* fun;
qse_htb_pair_t* pair;
fun = ((qse_awk_nde_fun_t*)nde)->ptr;
fun = ((qse_awk_nde_fun_t*)nde)->funptr;
if (!fun)
{
qse_htb_pair_t* pair;
/* TODO: support bultin functions?, support module functions? */
pair = qse_htb_search(rtx->awk->tree.funs, ((qse_awk_nde_fun_t*)nde)->name.ptr, ((qse_awk_nde_fun_t*)nde)->name.len);
if (!pair)

View File

@ -179,7 +179,7 @@ struct qse_awk_nde_fun_t
{
QSE_AWK_NDE_HDR;
qse_cstr_t name; /* function name */
qse_awk_fun_t* ptr; /* QSE_NULL or actual pointer */
qse_awk_fun_t* funptr; /* QSE_NULL or actual pointer */
};
/* QSE_AWK_NDE_NAMED, QSE_AWK_NDE_GBL,

View File

@ -759,10 +759,10 @@ const qse_char_t* qse_awk_rtx_getvaltypename(qse_awk_rtx_t* rtx, qse_awk_val_t*
QSE_T("flt"),
QSE_T("str"),
QSE_T("mbs"),
QSE_T("fun"),
QSE_T("map"),
QSE_T("rex"),
QSE_T("ref"),
QSE_T("fun")
QSE_T("ref")
};
return __val_type_name[QSE_AWK_RTX_GETVALTYPE(rtx, val)];
@ -854,6 +854,10 @@ void qse_awk_rtx_freeval (qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache)
break;
}
case QSE_AWK_VAL_FUN:
QSE_AWK_FREE (rtx->awk, val);
break;
case QSE_AWK_VAL_MAP:
{
qse_htb_fini (((qse_awk_val_map_t*)val)->map);
@ -871,10 +875,6 @@ void qse_awk_rtx_freeval (qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache)
break;
}
case QSE_AWK_VAL_FUN:
QSE_AWK_FREE (rtx->awk, val);
break;
}
}
}
@ -1007,14 +1007,14 @@ int qse_awk_rtx_valtobool (qse_awk_rtx_t* rtx, const qse_awk_val_t* val)
return ((qse_awk_val_mbs_t*)val)->val.len > 0;
case QSE_AWK_VAL_REX: /* TODO: is this correct? */
return ((qse_awk_val_rex_t*)val)->str.len > 0;
case QSE_AWK_VAL_FUN:
/* return always true */
return 1;
case QSE_AWK_VAL_MAP:
/* true if the map size is greater than 0. false if not */
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 (
@ -1506,6 +1506,11 @@ int qse_awk_rtx_valtostr (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_rt
#endif
}
case QSE_AWK_VAL_FUN:
{
return str_to_str(rtx, ((qse_awk_val_fun_t*)v)->fun->name.ptr, ((qse_awk_val_fun_t*)v)->fun->name.len, out);
}
case QSE_AWK_VAL_MAP:
{
if (rtx->awk->opt.trait & QSE_AWK_FLEXMAP)
@ -1519,11 +1524,6 @@ 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 str_to_str(rtx, ((qse_awk_val_fun_t*)v)->fun->name.ptr, ((qse_awk_val_fun_t*)v)->fun->name.len, out);
}
}
@ -1809,6 +1809,12 @@ int qse_awk_rtx_valtonum (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_in
);
}
case QSE_AWK_VAL_FUN:
{
/* unable to convert a function to a number */
break;
}
case QSE_AWK_VAL_MAP:
{
if (rtx->awk->opt.trait & QSE_AWK_FLEXMAP)
@ -1823,12 +1829,6 @@ int qse_awk_rtx_valtonum (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_in
{
return val_ref_to_num(rtx, (qse_awk_val_ref_t*)v, l, r);
}
case QSE_AWK_VAL_FUN:
{
/* unable to convert a function to a number */
break;
}
}
#ifdef DEBUG_VAL
@ -2153,6 +2153,10 @@ void qse_awk_dprintval (qse_awk_rtx_t* run, qse_awk_val_t* val)
qse_errputstrf (QSE_T("/%s/"), ((qse_awk_val_rex_t*)val)->ptr);
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;
case QSE_AWK_VAL_MAP:
qse_errputstrf (QSE_T("MAP["));
qse_htb_walk (((qse_awk_val_map_t*)val)->map, print_pair, run);
@ -2165,10 +2169,6 @@ void qse_awk_dprintval (qse_awk_rtx_t* run, qse_awk_val_t* val)
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"));
}