From fe1ff5cdbabdc9114eaeb81acd33aaa51746eba3 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 22 Oct 2014 17:05:45 +0000 Subject: [PATCH] added qse_awk_rtx_getvaltype() and qse_awk_rtx_getintfromval() macros --- qse/include/qse/awk/awk.h | 9 +- qse/lib/awk/Awk.cpp | 20 +- qse/lib/awk/StdAwk.cpp | 2 +- qse/lib/awk/fnc.c | 121 +++-- qse/lib/awk/misc.c | 4 +- qse/lib/awk/rec.c | 15 +- qse/lib/awk/rio.c | 23 +- qse/lib/awk/run.c | 946 ++++++++++++++++++-------------------- qse/lib/awk/run.h | 2 +- qse/lib/awk/std.c | 2 +- qse/lib/awk/val.c | 183 +++++--- 11 files changed, 682 insertions(+), 645 deletions(-) diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 7eb5398c..464c8f9a 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -135,7 +135,7 @@ typedef struct qse_awk_loc_t qse_awk_loc_t; unsigned int nstr: 2 */ #define QSE_AWK_VAL_HDR \ - qse_uintptr_t type: 3; \ + qse_uintptr_t v_type: 3; \ qse_uintptr_t ref: ((QSE_SIZEOF_UINTPTR_T * 8) - 6); \ qse_uintptr_t stat: 1; \ qse_uintptr_t nstr: 2 @@ -169,7 +169,7 @@ typedef struct qse_awk_val_nil_t qse_awk_val_nil_t; struct qse_awk_val_int_t { QSE_AWK_VAL_HDR; - qse_awk_int_t val; + qse_awk_int_t i_val; void* nde; }; typedef struct qse_awk_val_int_t qse_awk_val_int_t; @@ -1389,6 +1389,7 @@ enum qse_awk_val_type_t QSE_AWK_VAL_REF = 6, /**< reference to other types */ QSE_AWK_VAL_FUN = 7 }; +typedef enum qse_awk_val_type_t qse_awk_val_type_t; /** * The values defined are used to set the type field of the @@ -2552,6 +2553,10 @@ QSE_EXPORT void qse_awk_rtx_refdownval_nofree ( qse_awk_val_t* val /**< value pointer */ ); + +#define qse_awk_rtx_getvaltype(rtx,v) ((v)->v_type) +#define qse_awk_rtx_getintfromval(rtx,v) (((qse_awk_val_int_t*)(v))->i_val) + /** * The qse_awk_rtx_valtobool() function converts a value \a val to a boolean * value. diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index e397e609..e009d619 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -455,9 +455,9 @@ int Awk::Value::getStr (const char_t** str, size_t* len) const QSE_ASSERT (this->val != QSE_NULL); - if (this->run != QSE_NULL) + if (this->run) { - if (this->val->type == QSE_AWK_VAL_STR) + if (qse_awk_rtx_getvaltype (this->run->rtx, this->val) == QSE_AWK_VAL_STR) { p = ((qse_awk_val_str_t*)this->val)->val.ptr; l = ((qse_awk_val_str_t*)this->val)->val.len; @@ -643,7 +643,7 @@ int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v) { QSE_ASSERT (r != QSE_NULL); - if (val->type != QSE_AWK_VAL_MAP) + if (qse_awk_rtx_getvaltype (r->rtx, val) != QSE_AWK_VAL_MAP) { // the previous value is not a map. // a new map value needs to be created first. @@ -803,7 +803,7 @@ int Awk::Value::setIndexedStr (Run* r, const Index& idx, const char_t* str, bool bool Awk::Value::isIndexed () const { QSE_ASSERT (val != QSE_NULL); - return val->type == QSE_AWK_VAL_MAP; + return qse_awk_rtx_getvaltype (this->run->rtx, val) == QSE_AWK_VAL_MAP; } int Awk::Value::getIndexed (const Index& idx, Value* v) const @@ -811,8 +811,8 @@ int Awk::Value::getIndexed (const Index& idx, Value* v) const QSE_ASSERT (val != QSE_NULL); // not a map. v is just nil. not an error - if (val->type != QSE_AWK_VAL_MAP) - { + if (qse_awk_rtx_getvaltype (this->run->rtx, val) != QSE_AWK_VAL_MAP) + { v->clear (); return 0; } @@ -836,7 +836,7 @@ Awk::Value::IndexIterator Awk::Value::getFirstIndex (Index* idx) const { QSE_ASSERT (this->val != QSE_NULL); - if (this->val->type != QSE_AWK_VAL_MAP) return IndexIterator::END; + if (qse_awk_rtx_getvaltype (this->run->rtx, this->val) != QSE_AWK_VAL_MAP) return IndexIterator::END; QSE_ASSERT (this->run != QSE_NULL); @@ -856,7 +856,7 @@ Awk::Value::IndexIterator Awk::Value::getNextIndex ( { QSE_ASSERT (val != QSE_NULL); - if (val->type != QSE_AWK_VAL_MAP) return IndexIterator::END; + if (qse_awk_rtx_getvaltype (this->run->rtx, val) != QSE_AWK_VAL_MAP) return IndexIterator::END; QSE_ASSERT (this->run != QSE_NULL); @@ -1399,7 +1399,7 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi) int xx; val_t* v = qse_awk_rtx_getarg (run->rtx, i); - if (v->type == QSE_AWK_VAL_REF) + if (qse_awk_rtx_getvaltype (run->rtx, v) == QSE_AWK_VAL_REF) { qse_awk_val_ref_t* ref = (qse_awk_val_ref_t*)v; @@ -1470,7 +1470,7 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi) "Do NOT change the run field from function handler"); val_t* v = qse_awk_rtx_getarg (run->rtx, i); - if (v->type == QSE_AWK_VAL_REF) + if (qse_awk_rtx_getvaltype (run->rtx, v) == QSE_AWK_VAL_REF) { if (qse_awk_rtx_setrefval (run->rtx, (qse_awk_val_ref_t*)v, args[i].toVal()) <= -1) { diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index 84c6b445..3be6753c 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -843,7 +843,7 @@ int StdAwk::open_console_in (Console& io) */ argv = qse_awk_rtx_getgbl (rtx, this->gbl_argv); QSE_ASSERT (argv != QSE_NULL); - QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, argv) == QSE_AWK_VAL_MAP); map = ((qse_awk_val_map_t*)argv)->map; QSE_ASSERT (map != QSE_NULL); diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 8c8bc4c3..cb6c91d1 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -434,8 +434,7 @@ static int index_or_rindex (qse_awk_rtx_t* rtx, int rindex) str1 = qse_awk_rtx_getvalstr (rtx, a1, &len1); if (str1 == QSE_NULL) { - if (a0->type != QSE_AWK_VAL_STR) - qse_awk_rtx_freevalstr (rtx, a0, str0); + qse_awk_rtx_freevalstr (rtx, a0, str0); return -1; } @@ -494,6 +493,7 @@ int qse_awk_fnc_length (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { qse_size_t nargs; qse_awk_val_t* v; + qse_awk_val_type_t vtype; qse_char_t* str; qse_size_t len; @@ -508,12 +508,14 @@ int qse_awk_fnc_length (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) else { v = qse_awk_rtx_getarg (rtx, 0); - if (v->type == QSE_AWK_VAL_MAP) + vtype = qse_awk_rtx_getvaltype (rtx, v); + + if (vtype == QSE_AWK_VAL_MAP) { /* map size */ len = QSE_HTB_SIZE(((qse_awk_val_map_t*)v)->map); } - else if (v->type == QSE_AWK_VAL_STR) + else if (vtype == QSE_AWK_VAL_STR) { /* string length */ len = ((qse_awk_val_str_t*)v)->val.len; @@ -597,9 +599,11 @@ int qse_awk_fnc_split (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { qse_size_t nargs; qse_awk_val_t* a0, * a1, * a2, * t1, * t2; + qse_awk_val_type_t a1_vtype, a2_vtype, t1_vtype; - qse_cstr_t str, fs; - qse_char_t* str_free = QSE_NULL, * fs_free = QSE_NULL; + qse_cstr_t str = { QSE_NULL, 0 }; + qse_cstr_t fs; + qse_char_t* fs_free = QSE_NULL; const qse_char_t* p; qse_size_t str_left, org_len; void* fs_rex = QSE_NULL; @@ -618,8 +622,11 @@ int qse_awk_fnc_split (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) a1 = qse_awk_rtx_getarg (rtx, 1); a2 = (nargs >= 3)? qse_awk_rtx_getarg (rtx, 2): QSE_NULL; - QSE_ASSERT (a1->type == QSE_AWK_VAL_REF); + a1_vtype = qse_awk_rtx_getvaltype (rtx, a1); + QSE_ASSERT (a1_vtype == QSE_AWK_VAL_REF); + +/* if (a0->type == QSE_AWK_VAL_STR) { str.ptr = ((qse_awk_val_str_t*)a0)->val.ptr; @@ -631,17 +638,21 @@ int qse_awk_fnc_split (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) if (str.ptr == QSE_NULL) return -1; str_free = (qse_char_t*)str.ptr; } +*/ + str.ptr = qse_awk_rtx_getvalstr (rtx, a0, &str.len); + if (str.ptr == QSE_NULL) goto oops; if (a2 == QSE_NULL) { /* get the value from FS */ t1 = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_FS); - if (t1->type == QSE_AWK_VAL_NIL) + t1_vtype = qse_awk_rtx_getvaltype (rtx, t1); + if (t1_vtype == QSE_AWK_VAL_NIL) { fs.ptr = QSE_T(" "); fs.len = 1; } - else if (t1->type == QSE_AWK_VAL_STR) + else if (t1_vtype == QSE_AWK_VAL_STR) { fs.ptr = ((qse_awk_val_str_t*)t1)->val.ptr; fs.len = ((qse_awk_val_str_t*)t1)->val.len; @@ -655,46 +666,51 @@ int qse_awk_fnc_split (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) if (fs.len > 1) fs_rex = rtx->gbl.fs[rtx->gbl.ignorecase]; } - else if (a2->type == QSE_AWK_VAL_REX) - { - /* the third parameter is a regular expression */ - fs_rex = ((qse_awk_val_rex_t*)a2)->code[rtx->gbl.ignorecase]; - - /* make the loop below to take fs_rex by - * setting fs_len greater than 1*/ - fs.ptr = QSE_NULL; - fs.len = 2; - } else { - if (a2->type == QSE_AWK_VAL_STR) + a2_vtype = qse_awk_rtx_getvaltype (rtx, a2); + + if (a2_vtype == QSE_AWK_VAL_REX) { - fs.ptr = ((qse_awk_val_str_t*)a2)->val.ptr; - fs.len = ((qse_awk_val_str_t*)a2)->val.len; + /* the third parameter is a regular expression */ + fs_rex = ((qse_awk_val_rex_t*)a2)->code[rtx->gbl.ignorecase]; + + /* make the loop below to take fs_rex by + * setting fs_len greater than 1*/ + fs.ptr = QSE_NULL; + fs.len = 2; } - else + else { - fs.ptr = qse_awk_rtx_valtostrdup (rtx, a2, &fs.len); - if (fs.ptr == QSE_NULL) goto oops; - fs_free = (qse_char_t*)fs.ptr; - } - - if (fs.len > 1) - { - int x; - - if (rtx->gbl.ignorecase) - x = qse_awk_buildrex (rtx->awk, fs.ptr, fs.len, &errnum, QSE_NULL, &fs_rex); - else - x = qse_awk_buildrex (rtx->awk, fs.ptr, fs.len, &errnum, &fs_rex, QSE_NULL); - - if (x <= -1) + if (a2_vtype == QSE_AWK_VAL_STR) { - qse_awk_rtx_seterrnum (rtx, errnum, QSE_NULL); - goto oops; + fs.ptr = ((qse_awk_val_str_t*)a2)->val.ptr; + fs.len = ((qse_awk_val_str_t*)a2)->val.len; + } + else + { + fs.ptr = qse_awk_rtx_valtostrdup (rtx, a2, &fs.len); + if (fs.ptr == QSE_NULL) goto oops; + fs_free = (qse_char_t*)fs.ptr; } - fs_rex_free = fs_rex; + if (fs.len > 1) + { + int x; + + if (rtx->gbl.ignorecase) + x = qse_awk_buildrex (rtx->awk, fs.ptr, fs.len, &errnum, QSE_NULL, &fs_rex); + else + x = qse_awk_buildrex (rtx->awk, fs.ptr, fs.len, &errnum, &fs_rex, QSE_NULL); + + if (x <= -1) + { + qse_awk_rtx_seterrnum (rtx, errnum, QSE_NULL); + goto oops; + } + + fs_rex_free = fs_rex; + } } } @@ -763,8 +779,11 @@ int qse_awk_fnc_split (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) str.len = str_left - (p - str.ptr); } - if (str_free) QSE_AWK_FREE (rtx->awk, str_free); + /*if (str_free) QSE_AWK_FREE (rtx->awk, str_free);*/ + qse_awk_rtx_freevalstr (rtx, a0, str.ptr); + if (fs_free) QSE_AWK_FREE (rtx->awk, fs_free); + if (fs_rex_free) { if (rtx->gbl.ignorecase) @@ -782,8 +801,11 @@ int qse_awk_fnc_split (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) return 0; oops: - if (str_free) QSE_AWK_FREE (rtx->awk, str_free); + /*if (str_free) QSE_AWK_FREE (rtx->awk, str_free);*/ + if (str.ptr) qse_awk_rtx_freevalstr (rtx, a0, str.ptr); + if (fs_free) QSE_AWK_FREE (rtx->awk, fs_free); + if (fs_rex_free) { if (rtx->gbl.ignorecase) @@ -856,6 +878,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_awk_int_t max_count) { qse_size_t nargs; qse_awk_val_t* a0, * a1, * a2, * v; + qse_awk_val_type_t a0_vtype, a1_vtype; qse_cstr_t s0, s1, s2; const qse_char_t* s2_end; @@ -881,13 +904,15 @@ static int __substitute (qse_awk_rtx_t* run, qse_awk_int_t max_count) a1 = qse_awk_rtx_getarg (run, 1); a2 = (nargs >= 3)? qse_awk_rtx_getarg (run, 2): QSE_NULL; - QSE_ASSERT (a2 == QSE_NULL || a2->type == QSE_AWK_VAL_REF); + a0_vtype = qse_awk_rtx_getvaltype (rtx, a0); + a1_vtype = qse_awk_rtx_getvaltype (rtx, a1); + QSE_ASSERT (a2 == QSE_NULL || qse_awk_rtx_getvaltype(rtx, a2) == QSE_AWK_VAL_REF); - if (a0->type == QSE_AWK_VAL_REX) + if (a0_vtype == QSE_AWK_VAL_REX) { rex = ((qse_awk_val_rex_t*)a0)->code[run->gbl.ignorecase]; } - else if (a0->type == QSE_AWK_VAL_STR) + else if (a0_vtype == QSE_AWK_VAL_STR) { s0.ptr = ((qse_awk_val_str_t*)a0)->val.ptr; s0.len = ((qse_awk_val_str_t*)a0)->val.len; @@ -899,7 +924,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_awk_int_t max_count) s0_free = (qse_char_t*)s0.ptr; } - if (a1->type == QSE_AWK_VAL_STR) + if (a1_vtype == QSE_AWK_VAL_STR) { s1.ptr = ((qse_awk_val_str_t*)a1)->val.ptr; s1.len = ((qse_awk_val_str_t*)a1)->val.len; @@ -931,7 +956,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_awk_int_t max_count) } new_inited = 1; - if (a0->type != QSE_AWK_VAL_REX) + if (a0_vtype != QSE_AWK_VAL_REX) { qse_awk_errnum_t errnum; int x; diff --git a/qse/lib/awk/misc.c b/qse/lib/awk/misc.c index cf3f446b..29470a20 100644 --- a/qse/lib/awk/misc.c +++ b/qse/lib/awk/misc.c @@ -1298,7 +1298,7 @@ int qse_awk_rtx_matchrex ( icase = rtx->gbl.ignorecase; - if (val->type == QSE_AWK_VAL_REX) + if (qse_awk_rtx_getvaltype (rtx, val) == QSE_AWK_VAL_REX) { code = ((qse_awk_val_rex_t*)val)->code[icase]; } @@ -1335,7 +1335,7 @@ int qse_awk_rtx_matchrex ( if (x <= -1) qse_awk_rtx_seterrnum (rtx, awkerr, QSE_NULL); #endif - if (val->type == QSE_AWK_VAL_REX) + if (qse_awk_rtx_getvaltype(rtx, val) == QSE_AWK_VAL_REX) { /* nothing to free */ } diff --git a/qse/lib/awk/rec.c b/qse/lib/awk/rec.c index e839c4b1..f97be873 100644 --- a/qse/lib/awk/rec.c +++ b/qse/lib/awk/rec.c @@ -56,7 +56,7 @@ int qse_awk_rtx_setrec ( return -1; } - QSE_ASSERT (run->inrec.d0->type == QSE_AWK_VAL_NIL); + QSE_ASSERT (qse_awk_rtx_getvaltype (run, run->inrec.d0) == QSE_AWK_VAL_NIL); /* d0 should be cleared before the next line is reached * as it doesn't call qse_awk_rtx_refdownval on run->inrec.d0 */ run->inrec.d0 = v; @@ -98,23 +98,26 @@ static int split_record (qse_awk_rtx_t* rtx) qse_char_t* p, * px; qse_size_t len, nflds; qse_awk_val_t* v, * fs; + qse_awk_val_type_t fsvtype; qse_char_t* fs_ptr, * fs_free; qse_size_t fs_len; qse_awk_errnum_t errnum; int how; - + + /* inrec should be cleared before split_record is called */ QSE_ASSERT (rtx->inrec.nflds == 0); /* get FS */ fs = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_FS); - if (fs->type == QSE_AWK_VAL_NIL) + fsvtype = qse_awk_rtx_getvaltype (rtx, fs); + if (fsvtype == QSE_AWK_VAL_NIL) { fs_ptr = QSE_T(" "); fs_len = 1; fs_free = QSE_NULL; } - else if (fs->type == QSE_AWK_VAL_STR) + else if (fsvtype == QSE_AWK_VAL_STR) { fs_ptr = ((qse_awk_val_str_t*)fs)->val.ptr; fs_len = ((qse_awk_val_str_t*)fs)->val.len; @@ -506,9 +509,9 @@ static int recomp_record_fields ( } v = qse_awk_rtx_getgbl (run, QSE_AWK_GBL_NF); - QSE_ASSERT (v->type == QSE_AWK_VAL_INT); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, v) == QSE_AWK_VAL_INT); - if (((qse_awk_val_int_t*)v)->val != max) + if (qse_awk_rtx_getintfromval (rtx, v)!= max) { v = qse_awk_rtx_makeintval (run, (qse_awk_int_t)max); if (v == QSE_NULL) return -1; diff --git a/qse/lib/awk/rio.c b/qse/lib/awk/rio.c index fd4e6363..ed61ce06 100644 --- a/qse/lib/awk/rio.c +++ b/qse/lib/awk/rio.c @@ -194,8 +194,12 @@ static QSE_INLINE int resolve_rs ( qse_awk_rtx_t* rtx, qse_awk_val_t* rs, qse_cstr_t* rrs) { int ret = 0; + qse_awk_val_type_t rs_vtype; - switch (rs->type) + + rs_vtype = qse_awk_rtx_getvaltype (rtx, rs); + + switch (rs_vtype) { case QSE_AWK_VAL_NIL: rrs->ptr = QSE_NULL; @@ -623,7 +627,7 @@ int qse_awk_rtx_readio ( } } - if (rrs.ptr && rs->type != QSE_AWK_VAL_STR) + if (rrs.ptr && qse_awk_rtx_getvaltype (rtx, rs) != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, rrs.ptr); qse_awk_rtx_refdownval (run, rs); @@ -637,8 +641,12 @@ int qse_awk_rtx_writeio_val ( qse_char_t* str; qse_size_t len; int n; + qse_awk_val_type_t vtype; - if (v->type == QSE_AWK_VAL_STR) + + vtype = qse_awk_rtx_getvaltype (run, v); + + if (vtype == QSE_AWK_VAL_STR) { str = ((qse_awk_val_str_t*)v)->val.ptr; len = ((qse_awk_val_str_t*)v)->val.len; @@ -657,7 +665,14 @@ int qse_awk_rtx_writeio_val ( n = qse_awk_rtx_writeio_str (run, out_type, name, str, len); - if (v->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, str); + if (vtype == QSE_AWK_VAL_STR) + { + /* nothing to free */ + } + else + { + QSE_AWK_FREE (run->awk, str); + } return n; } diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index b2e9ce43..ee540f6c 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -292,21 +292,25 @@ static int set_global ( { qse_awk_val_t* old; qse_awk_rtx_ecb_t* ecb; - + qse_awk_val_type_t vtype, old_vtype; + old = RTX_STACK_GBL (rtx, idx); + vtype = qse_awk_rtx_getvaltype (rtx, val); + old_vtype = qse_awk_rtx_getvaltype (rtx, old); + if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP)) { qse_awk_errnum_t errnum = QSE_AWK_ENOERR; - if (val->type == QSE_AWK_VAL_MAP) + if (vtype == QSE_AWK_VAL_MAP) { - if (old->type == QSE_AWK_VAL_NIL) + if (old_vtype == QSE_AWK_VAL_NIL) { /* a nil valul can be overridden with any values */ /* ok. no error */ } - else if (!assign && old->type == QSE_AWK_VAL_MAP) + else if (!assign && old_vtype == QSE_AWK_VAL_MAP) { /* when both are maps, how should this operation be * interpreted? @@ -331,7 +335,7 @@ static int set_global ( } else { - if (old->type == QSE_AWK_VAL_MAP) errnum = QSE_AWK_ENMAPTOSCALAR; + if (old_vtype == QSE_AWK_VAL_MAP) errnum = QSE_AWK_ENMAPTOSCALAR; } if (errnum != QSE_AWK_ENOERR) @@ -356,7 +360,7 @@ static int set_global ( } } - if (val->type == QSE_AWK_VAL_MAP) + if (vtype == QSE_AWK_VAL_MAP) { if (idx >= QSE_AWK_MIN_GBL_ID && idx <= QSE_AWK_MAX_GBL_ID) { @@ -430,7 +434,7 @@ static int set_global ( qse_char_t* fs_ptr; qse_size_t fs_len; - if (val->type == QSE_AWK_VAL_STR) + if (vtype == QSE_AWK_VAL_STR) { fs_ptr = ((qse_awk_val_str_t*)val)->val.ptr; fs_len = ((qse_awk_val_str_t*)val)->val.len; @@ -441,7 +445,7 @@ static int set_global ( /* due to the expression evaluation rule, the * regular expression can not be an assigned value */ - QSE_ASSERT (val->type != QSE_AWK_VAL_REX); + QSE_ASSERT (vtype != QSE_AWK_VAL_REX); out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; if (qse_awk_rtx_valtostr (rtx, val, &out) <= -1) return -1; @@ -458,7 +462,7 @@ static int set_global ( if (qse_awk_buildrex (rtx->awk, fs_ptr, fs_len, &errnum, &rex, &irex) <= -1) { SETERR_COD (rtx, errnum); - if (val->type != QSE_AWK_VAL_STR) + if (vtype != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, fs_ptr); return -1; } @@ -470,19 +474,17 @@ static int set_global ( rtx->gbl.fs[1] = irex; } - if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, fs_ptr); + if (vtype != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, fs_ptr); break; } case QSE_AWK_GBL_IGNORECASE: { + qse_awk_val_type_t vtype = qse_awk_rtx_getvaltype (rtx, val); rtx->gbl.ignorecase = - ((val->type == QSE_AWK_VAL_INT && - ((qse_awk_val_int_t*)val)->val != 0) || - (val->type == QSE_AWK_VAL_FLT && - ((qse_awk_val_flt_t*)val)->val != 0.0) || - (val->type == QSE_AWK_VAL_STR && - ((qse_awk_val_str_t*)val)->val.len != 0))? 1: 0; + ((vtype == QSE_AWK_VAL_INT && qse_awk_rtx_getintfromval (rtx,val) != 0) || + (vtype == QSE_AWK_VAL_FLT && ((qse_awk_val_flt_t*)val)->val != 0.0) || + (vtype == QSE_AWK_VAL_STR && ((qse_awk_val_str_t*)val)->val.len != 0))? 1: 0; break; } @@ -580,7 +582,7 @@ static int set_global ( { qse_cstr_t rss; - if (val->type == QSE_AWK_VAL_STR) + if (vtype == QSE_AWK_VAL_STR) { rss = ((qse_awk_val_str_t*)val)->val; } @@ -591,7 +593,7 @@ static int set_global ( /* due to the expression evaluation rule, the * regular expression can not be an assigned * value */ - QSE_ASSERT (val->type != QSE_AWK_VAL_REX); + QSE_ASSERT (vtype != QSE_AWK_VAL_REX); out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; if (qse_awk_rtx_valtostr (rtx, val, &out) <= -1) return -1; @@ -615,7 +617,7 @@ static int set_global ( if (qse_awk_buildrex (rtx->awk, rss.ptr, rss.len, &errnum, &rex, &irex) <= -1) { SETERR_COD (rtx, errnum); - if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, rss.ptr); + if (vtype != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, rss.ptr); return -1; } @@ -623,7 +625,7 @@ static int set_global ( rtx->gbl.rs[1] = irex; } - if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, rss.ptr); + if (vtype != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, rss.ptr); break; } @@ -2286,6 +2288,7 @@ static int run_foreach (qse_awk_rtx_t* rtx, qse_awk_nde_foreach_t* nde) qse_awk_val_t* rv; qse_htb_t* map; struct foreach_walker_t walker; + qse_awk_val_type_t rvtype; test = (qse_awk_nde_exp_t*)nde->test; QSE_ASSERT ( @@ -2300,13 +2303,14 @@ static int run_foreach (qse_awk_rtx_t* rtx, qse_awk_nde_foreach_t* nde) if (rv == QSE_NULL) return -1; qse_awk_rtx_refupval (rtx, rv); - if (rv->type == QSE_AWK_VAL_NIL) + rvtype = qse_awk_rtx_getvaltype (rtx, rv); + if (rvtype == QSE_AWK_VAL_NIL) { /* just return without excuting the loop body */ qse_awk_rtx_refdownval (rtx, rv); return 0; } - else if (rv->type != QSE_AWK_VAL_MAP) + else if (rvtype != QSE_AWK_VAL_MAP) { qse_awk_rtx_refdownval (rtx, rv); SETERR_LOC (rtx, QSE_AWK_ENOTMAPIN, &test->right->loc); @@ -2330,13 +2334,13 @@ static int run_break (qse_awk_rtx_t* run, qse_awk_nde_break_t* nde) return 0; } -static int run_continue (qse_awk_rtx_t* run, qse_awk_nde_continue_t* nde) +static int run_continue (qse_awk_rtx_t* rtx, qse_awk_nde_continue_t* nde) { - run->exit_level = EXIT_CONTINUE; + rtx->exit_level = EXIT_CONTINUE; return 0; } -static int run_return (qse_awk_rtx_t* run, qse_awk_nde_return_t* nde) +static int run_return (qse_awk_rtx_t* rtx, qse_awk_nde_return_t* nde) { if (nde->val != QSE_NULL) { @@ -2346,33 +2350,33 @@ static int run_return (qse_awk_rtx_t* run, qse_awk_nde_return_t* nde) * by the parser first of all */ QSE_ASSERT (nde->val->next == QSE_NULL); - val = eval_expression (run, nde->val); + val = eval_expression (rtx, nde->val); if (val == QSE_NULL) return -1; - if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP)) + if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP)) { - if (val->type == QSE_AWK_VAL_MAP) + if (qse_awk_rtx_getvaltype (rtx, val) == QSE_AWK_VAL_MAP) { /* cannot return a map */ - qse_awk_rtx_refupval (run, val); - qse_awk_rtx_refdownval (run, val); - SETERR_LOC (run, QSE_AWK_EMAPRET, &nde->loc); + qse_awk_rtx_refupval (rtx, val); + qse_awk_rtx_refdownval (rtx, val); + SETERR_LOC (rtx, QSE_AWK_EMAPRET, &nde->loc); return -1; } } - qse_awk_rtx_refdownval (run, RTX_STACK_RETVAL(run)); - RTX_STACK_RETVAL(run) = val; + qse_awk_rtx_refdownval (rtx, RTX_STACK_RETVAL(rtx)); + RTX_STACK_RETVAL(rtx) = val; /* NOTE: see eval_call() for the trick */ - qse_awk_rtx_refupval (run, val); + qse_awk_rtx_refupval (rtx, val); } - run->exit_level = EXIT_FUNCTION; + rtx->exit_level = EXIT_FUNCTION; return 0; } -static int run_exit (qse_awk_rtx_t* run, qse_awk_nde_exit_t* nde) +static int run_exit (qse_awk_rtx_t* rtx, qse_awk_nde_exit_t* nde) { if (nde->val != QSE_NULL) { @@ -2382,16 +2386,16 @@ static int run_exit (qse_awk_rtx_t* run, qse_awk_nde_exit_t* nde) * by the parser first of all */ QSE_ASSERT (nde->val->next == QSE_NULL); - val = eval_expression (run, nde->val); + val = eval_expression (rtx, nde->val); if (val == QSE_NULL) return -1; - qse_awk_rtx_refdownval (run, RTX_STACK_RETVAL_GBL(run)); - RTX_STACK_RETVAL_GBL(run) = val; /* global return value */ + qse_awk_rtx_refdownval (rtx, RTX_STACK_RETVAL_GBL(rtx)); + RTX_STACK_RETVAL_GBL(rtx) = val; /* global return value */ - qse_awk_rtx_refupval (run, val); + qse_awk_rtx_refupval (rtx, val); } - run->exit_level = (nde->abort)? EXIT_ABORT: EXIT_GLOBAL; + rtx->exit_level = (nde->abort)? EXIT_ABORT: EXIT_GLOBAL; return 0; } @@ -2502,7 +2506,7 @@ static int delete_indexed ( qse_awk_rtx_refupval (rtx, idx); - if (idx->type == QSE_AWK_VAL_STR) + if (qse_awk_rtx_getvaltype (rtx, idx) == QSE_AWK_VAL_STR) { /* delete x["abc"] */ @@ -2601,7 +2605,7 @@ static int run_delete_named (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var) val = (qse_awk_val_t*)QSE_HTB_VPTR(pair); QSE_ASSERT (val != QSE_NULL); - if (val->type != QSE_AWK_VAL_MAP) + if (qse_awk_rtx_getvaltype (rtx, val) != QSE_AWK_VAL_MAP) { SETERR_ARGX_LOC ( rtx, QSE_AWK_ENOTDEL, @@ -2629,6 +2633,7 @@ static int run_delete_named (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var) static int run_delete_unnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var) { qse_awk_val_t* val; + qse_awk_val_type_t vtype; switch (var->type) { @@ -2649,7 +2654,8 @@ static int run_delete_unnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var) QSE_ASSERT (val != QSE_NULL); - if (val->type == QSE_AWK_VAL_NIL) + vtype = qse_awk_rtx_getvaltype (rtx, val); + if (vtype == QSE_AWK_VAL_NIL) { qse_awk_val_t* tmp; @@ -2700,7 +2706,7 @@ static int run_delete_unnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var) { qse_htb_t* map; - if (val->type != QSE_AWK_VAL_MAP) + if (vtype != QSE_AWK_VAL_MAP) { SETERR_ARGX_LOC ( rtx, QSE_AWK_ENOTDEL, @@ -2795,7 +2801,7 @@ static int reset_variable (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var) QSE_ASSERT (val != QSE_NULL); - if (val->type != QSE_AWK_VAL_NIL) + if (qse_awk_rtx_getvaltype (rtx, val) != QSE_AWK_VAL_NIL) { qse_awk_rtx_refdownval (rtx, val); switch (var->type) @@ -3103,7 +3109,7 @@ static int run_printf (qse_awk_rtx_t* rtx, qse_awk_nde_print_t* nde) } qse_awk_rtx_refupval (rtx, v); - if (v->type != QSE_AWK_VAL_STR) + if (qse_awk_rtx_getvaltype (rtx, v) != QSE_AWK_VAL_STR) { /* the remaining arguments are ignored as the format cannot * contain any % characters */ @@ -3212,10 +3218,9 @@ static qse_awk_val_t* eval_expression (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) v = eval_expression0 (rtx, nde); if (v == QSE_NULL) return QSE_NULL; - if (v->type == QSE_AWK_VAL_REX) + if (qse_awk_rtx_getvaltype (rtx, v) == QSE_AWK_VAL_REX) { qse_cstr_t vs; - int opt = 0; /* special case where a regular expression is used in * without any match operators: @@ -3224,7 +3229,7 @@ static qse_awk_val_t* eval_expression (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) */ qse_awk_rtx_refupval (rtx, v); - if (rtx->inrec.d0->type == QSE_AWK_VAL_NIL) + if (qse_awk_rtx_getvaltype (rtx, rtx->inrec.d0) == QSE_AWK_VAL_NIL) { /* the record has never been read. * probably, this function has been triggered @@ -3235,12 +3240,12 @@ static qse_awk_val_t* eval_expression (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) else { QSE_ASSERTX ( - rtx->inrec.d0->type == QSE_AWK_VAL_STR, + qse_awk_rtx_getvaltype(rtx, rtx->inrec.d0) == QSE_AWK_VAL_STR, "the internal value representing $0 should always be of the string type once it has been set/updated. it is nil initially."); vs.ptr = ((qse_awk_val_str_t*)rtx->inrec.d0)->val.ptr; vs.len = ((qse_awk_val_str_t*)rtx->inrec.d0)->val.len; - } + } n = qse_awk_rtx_matchrex (rtx, v, &vs, &vs, QSE_NULL); if (n <= -1) @@ -3451,7 +3456,7 @@ static qse_awk_val_t* do_assignment ( case QSE_AWK_NDE_GBLIDX: case QSE_AWK_NDE_LCLIDX: case QSE_AWK_NDE_ARGIDX: - if (val->type == QSE_AWK_VAL_MAP) + if (qse_awk_rtx_getvaltype(rtx, val) == QSE_AWK_VAL_MAP) { /* a map cannot become a member of a map */ errnum = QSE_AWK_EMAPTOIDX; @@ -3462,13 +3467,13 @@ static qse_awk_val_t* do_assignment ( break; case QSE_AWK_NDE_POS: - if (val->type == QSE_AWK_VAL_MAP) + if (qse_awk_rtx_getvaltype(rtx, val) == QSE_AWK_VAL_MAP) { /* a map cannot be assigned to a positional */ errnum = QSE_AWK_EMAPTOPOS; goto exit_on_error; } - + ret = do_assignment_pos (rtx, (qse_awk_nde_pos_t*)var, val); break; @@ -3488,6 +3493,8 @@ exit_on_error: 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; + QSE_ASSERT ( var->type == QSE_AWK_NDE_NAMED || var->type == QSE_AWK_NDE_GBL || @@ -3496,6 +3503,7 @@ static qse_awk_val_t* do_assignment_nonidx ( ); QSE_ASSERT (var->idx == QSE_NULL); + vtype = qse_awk_rtx_getvaltype (rtx, val); switch (var->type) { @@ -3507,16 +3515,15 @@ static qse_awk_val_t* do_assignment_nonidx ( if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP)) { - if (pair && ((qse_awk_val_t*)QSE_HTB_VPTR(pair))->type == QSE_AWK_VAL_MAP) + if (pair && qse_awk_rtx_getvaltype (rtx, (qse_awk_val_t*)QSE_HTB_VPTR(pair)) == QSE_AWK_VAL_MAP) { /* old value is a map - it can only be accessed through indexing. */ qse_awk_errnum_t errnum; - errnum = (val->type == QSE_AWK_VAL_MAP)? - QSE_AWK_ENMAPTOMAP: QSE_AWK_ENMAPTOSCALAR; + errnum = (vtype == QSE_AWK_VAL_MAP)? QSE_AWK_ENMAPTOMAP: QSE_AWK_ENMAPTOSCALAR; SETERR_ARGX_LOC (run, errnum, &var->id.name, &var->loc); return QSE_NULL; } - else if (val->type == QSE_AWK_VAL_MAP) + else if (vtype == QSE_AWK_VAL_MAP) { /* old value is not a map but a new value is a map. * a map cannot be assigned to a variable if FLEXMAP is off. */ @@ -3553,16 +3560,15 @@ static qse_awk_val_t* do_assignment_nonidx ( if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP)) { - if (old->type == QSE_AWK_VAL_MAP) + if (qse_awk_rtx_getvaltype (rtx, old) == QSE_AWK_VAL_MAP) { /* old value is a map - it can only be accessed through indexing. */ qse_awk_errnum_t errnum; - errnum = (val->type == QSE_AWK_VAL_MAP)? - QSE_AWK_ENMAPTOMAP: QSE_AWK_ENMAPTOSCALAR; + errnum = (vtype == QSE_AWK_VAL_MAP)? QSE_AWK_ENMAPTOMAP: QSE_AWK_ENMAPTOSCALAR; SETERR_ARGX_LOC (run, errnum, &var->id.name, &var->loc); return QSE_NULL; } - else if (val->type == QSE_AWK_VAL_MAP) + else if (vtype == QSE_AWK_VAL_MAP) { /* old value is not a map but a new value is a map. * a map cannot be assigned to a variable if FLEXMAP is off. */ @@ -3583,16 +3589,15 @@ static qse_awk_val_t* do_assignment_nonidx ( if (!(run->awk->opt.trait & QSE_AWK_FLEXMAP)) { - if (old->type == QSE_AWK_VAL_MAP) + if (qse_awk_rtx_getvaltype (rtx, old) == QSE_AWK_VAL_MAP) { /* old value is a map - it can only be accessed through indexing. */ qse_awk_errnum_t errnum; - errnum = (val->type == QSE_AWK_VAL_MAP)? - QSE_AWK_ENMAPTOMAP: QSE_AWK_ENMAPTOSCALAR; + errnum = (vtype == QSE_AWK_VAL_MAP)? QSE_AWK_ENMAPTOMAP: QSE_AWK_ENMAPTOSCALAR; SETERR_ARGX_LOC (run, errnum, &var->id.name, &var->loc); return QSE_NULL; } - else if (val->type == QSE_AWK_VAL_MAP) + else if (vtype == QSE_AWK_VAL_MAP) { /* old value is not a map but a new value is a map. * a map cannot be assigned to a variable if FLEXMAP is off. */ @@ -3616,6 +3621,7 @@ 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; qse_char_t* str; qse_size_t len; qse_char_t idxbuf[IDXBUFSIZE]; @@ -3625,7 +3631,7 @@ static qse_awk_val_t* do_assignment_idx ( var->type == QSE_AWK_NDE_GBLIDX || var->type == QSE_AWK_NDE_LCLIDX || var->type == QSE_AWK_NDE_ARGIDX) && var->idx != QSE_NULL); - QSE_ASSERT (val->type != QSE_AWK_VAL_MAP); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, val) != QSE_AWK_VAL_MAP); retry: switch (var->type) @@ -3654,7 +3660,8 @@ retry: break; } - if (map->type == QSE_AWK_VAL_NIL) + mvtype = qse_awk_rtx_getvaltype (rtx, map); + if (mvtype == QSE_AWK_VAL_NIL) { qse_awk_val_t* tmp; @@ -3714,7 +3721,7 @@ retry: map = (qse_awk_val_map_t*)tmp; } - else if (map->type != QSE_AWK_VAL_MAP) + else if (mvtype != QSE_AWK_VAL_MAP) { if (rtx->awk->opt.trait & QSE_AWK_FLEXMAP) { @@ -3763,33 +3770,35 @@ retry: } static qse_awk_val_t* do_assignment_pos ( - qse_awk_rtx_t* run, qse_awk_nde_pos_t* pos, qse_awk_val_t* val) + 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; qse_awk_int_t lv; qse_cstr_t str; int n; - v = eval_expression (run, pos->val); + v = eval_expression (rtx, pos->val); if (v == QSE_NULL) return QSE_NULL; - 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, &pos->loc); + SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &pos->loc); return QSE_NULL; } if (!IS_VALID_POSIDX(lv)) { - SETERR_LOC (run, QSE_AWK_EPOSIDX, &pos->loc); + SETERR_LOC (rtx, QSE_AWK_EPOSIDX, &pos->loc); return QSE_NULL; } - if (val->type == QSE_AWK_VAL_STR) + vtype = qse_awk_rtx_getvaltype (rtx, val); + if (vtype == QSE_AWK_VAL_STR) { str = ((qse_awk_val_str_t*)val)->val; } @@ -3798,21 +3807,28 @@ static qse_awk_val_t* do_assignment_pos ( qse_awk_rtx_valtostr_out_t out; out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - if (qse_awk_rtx_valtostr (run, val, &out) <= -1) + if (qse_awk_rtx_valtostr (rtx, val, &out) <= -1) { - ADJERR_LOC (run, &pos->loc); + ADJERR_LOC (rtx, &pos->loc); return QSE_NULL; } str = out.u.cpldup; } - n = qse_awk_rtx_setrec (run, (qse_size_t)lv, &str); + n = qse_awk_rtx_setrec (rtx, (qse_size_t)lv, &str); - if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, str.ptr); + if (vtype == QSE_AWK_VAL_STR) + { + /* do nothing */ + } + else + { + QSE_AWK_FREE (rtx->awk, str.ptr); + } if (n <= -1) return QSE_NULL; - return (lv == 0)? run->inrec.d0: run->inrec.flds[lv-1].val; + return (lv == 0)? rtx->inrec.d0: rtx->inrec.flds[lv-1].val; } static qse_awk_val_t* eval_binary (qse_awk_rtx_t* run, qse_awk_nde_t* nde) @@ -4022,6 +4038,7 @@ 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; qse_char_t* str; qse_size_t len; qse_char_t idxbuf[IDXBUFSIZE]; @@ -4055,13 +4072,14 @@ static qse_awk_val_t* eval_binop_in ( qse_awk_rtx_refupval (run, rv); - if (rv->type == QSE_AWK_VAL_NIL) + rvtype = qse_awk_rtx_getvaltype (run, rv); + if (rvtype == QSE_AWK_VAL_NIL) { if (str != idxbuf) QSE_AWK_FREE (run->awk, str); qse_awk_rtx_refdownval (run, rv); return qse_awk_val_zero; } - else if (rv->type == QSE_AWK_VAL_MAP) + else if (rvtype == QSE_AWK_VAL_MAP) { qse_awk_val_t* res; qse_htb_t* map; @@ -4135,11 +4153,10 @@ static int __cmp_nil_nil ( } static int __cmp_nil_int ( - qse_awk_rtx_t* run, 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) { - if (((qse_awk_val_int_t*)right)->val < 0) return 1; - if (((qse_awk_val_int_t*)right)->val > 0) return -1; - return 0; + qse_awk_int_t v = qse_awk_rtx_getintfromval (rtx, right); + return (v < 0)? 1: ((v > 0)? -1: 0); } static int __cmp_nil_real ( @@ -4159,28 +4176,24 @@ static int __cmp_nil_str ( static int __cmp_int_nil ( qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right) { - if (((qse_awk_val_int_t*)left)->val > 0) return 1; - if (((qse_awk_val_int_t*)left)->val < 0) return -1; - return 0; + qse_awk_int_t v = qse_awk_rtx_getintfromval (rtx, left); + return (v > 0)? 1: ((v < 0)? -1: 0); } static int __cmp_int_int ( qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right) { - if (((qse_awk_val_int_t*)left)->val > - ((qse_awk_val_int_t*)right)->val) return 1; - if (((qse_awk_val_int_t*)left)->val < - ((qse_awk_val_int_t*)right)->val) return -1; - return 0; + qse_awk_int_t v1 = qse_awk_rtx_getintfromval (rtx, left); + qse_awk_int_t v2 = qse_awk_rtx_getintfromval (rtx, right); + return (v1 > v2)? 1: ((v1 < v2)? -1: 0); } static int __cmp_int_real ( qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right) { - if (((qse_awk_val_int_t*)left)->val > - ((qse_awk_val_flt_t*)right)->val) return 1; - if (((qse_awk_val_int_t*)left)->val < - ((qse_awk_val_flt_t*)right)->val) return -1; + qse_awk_int_t v1 = qse_awk_rtx_getintfromval (rtx, left); + if (v1 > ((qse_awk_val_flt_t*)right)->val) return 1; + if (v1 < ((qse_awk_val_flt_t*)right)->val) return -1; return 0; } @@ -4193,7 +4206,7 @@ static int __cmp_int_str ( /* SCO CC doesn't seem to handle right->nstr > 0 properly */ if (rtx->awk->opt.trait & QSE_AWK_NCMPONSTR || right->nstr /*> 0*/) { - qse_awk_int_t ll; + qse_awk_int_t ll, v1; qse_awk_flt_t rr; n = qse_awk_rtx_strtonum ( @@ -4202,17 +4215,17 @@ static int __cmp_int_str ( ((qse_awk_val_str_t*)right)->val.len, &ll, &rr ); + + v1 = qse_awk_rtx_getintfromval (rtx, left); if (n == 0) { /* a numeric integral string */ - return (((qse_awk_val_int_t*)left)->val > ll)? 1: - (((qse_awk_val_int_t*)left)->val < ll)? -1: 0; + return (v1 > ll)? 1: ((v1 < ll)? -1: 0); } else if (n > 0) { /* a numeric floating-point string */ - return (((qse_awk_val_int_t*)left)->val > rr)? 1: - (((qse_awk_val_int_t*)left)->val < rr)? -1: 0; + return (v1 > rr)? 1: ((v1 < rr)? -1: 0); } } @@ -4253,10 +4266,9 @@ static int __cmp_flt_nil ( static int __cmp_flt_int ( qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right) { - if (((qse_awk_val_flt_t*)left)->val > - ((qse_awk_val_int_t*)right)->val) return 1; - if (((qse_awk_val_flt_t*)left)->val < - ((qse_awk_val_int_t*)right)->val) return -1; + qse_awk_int_t v2 = qse_awk_rtx_getintfromval (rtx, right); + if (((qse_awk_val_flt_t*)left)->val > v2) return 1; + if (((qse_awk_val_flt_t*)left)->val < v2) return -1; return 0; } @@ -4423,6 +4435,7 @@ static int __cmp_str_str ( static int __cmp_val ( qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right) { + qse_awk_val_type_t lvtype, rvtype; typedef int (*cmp_val_t) (qse_awk_rtx_t*, qse_awk_val_t*, qse_awk_val_t*); static cmp_val_t func[] = @@ -4435,64 +4448,71 @@ static int __cmp_val ( __cmp_str_nil, __cmp_str_int, __cmp_str_real, __cmp_str_str, }; - if (left->type == QSE_AWK_VAL_MAP || right->type == QSE_AWK_VAL_MAP) + lvtype = qse_awk_rtx_getvaltype(rtx, left); + rvtype = qse_awk_rtx_getvaltype(rtx, right); + if (lvtype == QSE_AWK_VAL_MAP || rvtype == QSE_AWK_VAL_MAP) { +/* TODO: get the map size and use it for comparison */ /* a map can't be compared againt other values */ SETERR_COD (rtx, QSE_AWK_EOPERAND); return CMP_ERROR; } - QSE_ASSERT ( - left->type >= QSE_AWK_VAL_NIL && - left->type <= QSE_AWK_VAL_STR); - QSE_ASSERT ( - right->type >= QSE_AWK_VAL_NIL && - right->type <= QSE_AWK_VAL_STR); + QSE_ASSERT (lvtype >= QSE_AWK_VAL_NIL && lvtype <= QSE_AWK_VAL_STR); + QSE_ASSERT (rvtype >= QSE_AWK_VAL_NIL && rvtype <= QSE_AWK_VAL_STR); - return func[left->type*4+right->type] (rtx, left, right); + return func[lvtype * 4 + rvtype] (rtx, left, right); } static int teq_val (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right) { int n; + qse_awk_val_type_t lt, rt; if (left == right) n = 1; - else if (left->type != right->type) n = 0; else { - switch (left->type) + lt = qse_awk_rtx_getvaltype (rtx, left); + rt = qse_awk_rtx_getvaltype (rtx, right); + + if (lt != rt) n = 0; + else { - case QSE_AWK_VAL_NIL: - n = 1; - break; + switch (lt) + { + case QSE_AWK_VAL_NIL: + n = 1; + break; - case QSE_AWK_VAL_INT: - n = ((qse_awk_val_int_t*)left)->val == - ((qse_awk_val_int_t*)right)->val; - break; + case QSE_AWK_VAL_INT: + n = (qse_awk_rtx_getintfromval (rtx, left) == + qse_awk_rtx_getintfromval (rtx, right)); + break; - case QSE_AWK_VAL_FLT: - n = ((qse_awk_val_flt_t*)left)->val == - ((qse_awk_val_flt_t*)right)->val; - break; + case QSE_AWK_VAL_FLT: + n = ((qse_awk_val_flt_t*)left)->val == + ((qse_awk_val_flt_t*)right)->val; + break; - case QSE_AWK_VAL_STR: - n = qse_strxncmp ( - ((qse_awk_val_str_t*)left)->val.ptr, - ((qse_awk_val_str_t*)left)->val.len, - ((qse_awk_val_str_t*)right)->val.ptr, - ((qse_awk_val_str_t*)right)->val.len) == 0; - break; + case QSE_AWK_VAL_STR: + n = qse_strxncmp ( + ((qse_awk_val_str_t*)left)->val.ptr, + ((qse_awk_val_str_t*)left)->val.len, + ((qse_awk_val_str_t*)right)->val.ptr, + ((qse_awk_val_str_t*)right)->val.len) == 0; + break; - default: - /* map-x and map-y are always different regardless of - * their contents. however, if they are pointing to the - * same map value, it won't reach here but will be - * handled by the first check in this function */ - n = 0; - break; + default: + /* map-x and map-y are always different regardless of + * their contents. however, if they are pointing to the + * same map value, it won't reach here but will be + * handled by the first check in this function */ + n = 0; + break; + } } } + return n; } @@ -5073,8 +5093,10 @@ static qse_awk_val_t* eval_unary (qse_awk_rtx_t* run, qse_awk_nde_t* nde) break; case QSE_AWK_UNROP_LNOT: - if (left->type == QSE_AWK_VAL_STR) + if (qse_awk_rtx_getvaltype (rtx, left) == QSE_AWK_VAL_STR) { + /* 0 if the string length is greater than 0. + * 1 if it's empty */ res = qse_awk_rtx_makeintval ( run, !(((qse_awk_val_str_t*)left)->val.len > 0)); } @@ -5104,8 +5126,9 @@ static qse_awk_val_t* eval_unary (qse_awk_rtx_t* run, qse_awk_nde_t* nde) break; case QSE_AWK_UNROP_DEF: + /* is defined? */ res = qse_awk_rtx_makeintval ( - run, ((left->type == QSE_AWK_VAL_NIL)? 0: 1)); + run, ((qse_awk_rtx_getvaltype (rtx, left) == QSE_AWK_VAL_NIL)? 0: 1)); break; } @@ -5115,9 +5138,12 @@ exit_func: return res; } -static qse_awk_val_t* eval_incpre (qse_awk_rtx_t* run, qse_awk_nde_t* nde) +static qse_awk_val_t* eval_incpre (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) { qse_awk_val_t* left, * res; + qse_awk_val_type_t left_vtype; + qse_awk_int_t inc_val_int; + qse_awk_flt_t inc_val_flt; qse_awk_nde_exp_t* exp = (qse_awk_nde_exp_t*)nde; QSE_ASSERT (exp->type == QSE_AWK_NDE_EXP_INCPRE); @@ -5130,149 +5156,113 @@ static qse_awk_val_t* eval_incpre (qse_awk_rtx_t* run, qse_awk_nde_t* nde) /*exp->left->type > QSE_AWK_NDE_ARGIDX) XXX */ exp->left->type > QSE_AWK_NDE_POS) { - SETERR_LOC (run, QSE_AWK_EOPERAND, &nde->loc); + SETERR_LOC (rtx, QSE_AWK_EOPERAND, &nde->loc); return QSE_NULL; } - QSE_ASSERT (exp->left->next == QSE_NULL); - left = eval_expression (run, exp->left); - if (left == QSE_NULL) return QSE_NULL; - - qse_awk_rtx_refupval (run, left); - if (exp->opcode == QSE_AWK_INCOP_PLUS) { - if (left->type == QSE_AWK_VAL_INT) - { - qse_awk_int_t r = ((qse_awk_val_int_t*)left)->val; - res = qse_awk_rtx_makeintval (run, r + 1); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else if (left->type == QSE_AWK_VAL_FLT) - { - qse_awk_flt_t r = ((qse_awk_val_flt_t*)left)->val; - res = qse_awk_rtx_makefltval (run, r + 1.0); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else - { - qse_awk_int_t v1; - qse_awk_flt_t v2; - int n; - - n = qse_awk_rtx_valtonum (run, left, &v1, &v2); - if (n <= -1) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - if (n == 0) - { - res = qse_awk_rtx_makeintval (run, v1 + 1); - } - else /* if (n == 1) */ - { - QSE_ASSERT (n == 1); - res = qse_awk_rtx_makefltval (run, v2 + 1.0); - } - - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } + inc_val_int = 1; + inc_val_flt = 1.0; } else if (exp->opcode == QSE_AWK_INCOP_MINUS) { - if (left->type == QSE_AWK_VAL_INT) - { - qse_awk_int_t r = ((qse_awk_val_int_t*)left)->val; - res = qse_awk_rtx_makeintval (run, r - 1); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else if (left->type == QSE_AWK_VAL_FLT) - { - qse_awk_flt_t r = ((qse_awk_val_flt_t*)left)->val; - res = qse_awk_rtx_makefltval (run, r - 1.0); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else - { - qse_awk_int_t v1; - qse_awk_flt_t v2; - int n; - - n = qse_awk_rtx_valtonum (run, left, &v1, &v2); - if (n == -1) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - if (n == 0) - { - res = qse_awk_rtx_makeintval (run, v1 - 1); - } - else /* if (n == 1) */ - { - QSE_ASSERT (n == 1); - res = qse_awk_rtx_makefltval (run, v2 - 1.0); - } - - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } + inc_val_int = -1; + inc_val_flt = -1.0; } else { QSE_ASSERT (!"should never happen - invalid opcode"); - qse_awk_rtx_refdownval (run, left); - SETERR_LOC (run, QSE_AWK_EINTERN, &nde->loc); + SETERR_LOC (rtx, QSE_AWK_EINTERN, &nde->loc); return QSE_NULL; } - if (do_assignment (run, exp->left, res) == QSE_NULL) + QSE_ASSERT (exp->left->next == QSE_NULL); + left = eval_expression (rtx, exp->left); + if (left == QSE_NULL) return QSE_NULL; + + qse_awk_rtx_refupval (rtx, left); + left_vtype = qse_awk_rtx_getvaltype (rtx, left); + + switch (left_vtype) { - qse_awk_rtx_refdownval (run, left); + case QSE_AWK_VAL_INT: + { + qse_awk_int_t r = qse_awk_rtx_getintfromval (rtx, left); + res = qse_awk_rtx_makeintval (rtx, r + inc_val_int); + if (res == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + break; + } + + case QSE_AWK_VAL_FLT: + { + qse_awk_flt_t r = ((qse_awk_val_flt_t*)left)->val; + res = qse_awk_rtx_makefltval (rtx, r + inc_val_flt); + if (res == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + break; + } + + default: + { + qse_awk_int_t v1; + qse_awk_flt_t v2; + int n; + + n = qse_awk_rtx_valtonum (rtx, left, &v1, &v2); + if (n <= -1) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + if (n == 0) + { + res = qse_awk_rtx_makeintval (rtx, v1 + inc_val_int); + } + else /* if (n == 1) */ + { + QSE_ASSERT (n == 1); + res = qse_awk_rtx_makefltval (rtx, v2 + inc_val_flt); + } + + if (res == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + break; + } + } + + if (do_assignment (rtx, exp->left, res) == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); return QSE_NULL; } - qse_awk_rtx_refdownval (run, left); + qse_awk_rtx_refdownval (rtx, left); return res; } -static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) +static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) { qse_awk_val_t* left, * res, * res2; + qse_awk_val_type_t left_vtype; + qse_awk_int_t inc_val_int; + qse_awk_flt_t inc_val_flt; qse_awk_nde_exp_t* exp = (qse_awk_nde_exp_t*)nde; QSE_ASSERT (exp->type == QSE_AWK_NDE_EXP_INCPST); @@ -5285,225 +5275,148 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) /*exp->left->type > QSE_AWK_NDE_ARGIDX) XXX */ exp->left->type > QSE_AWK_NDE_POS) { - SETERR_LOC (run, QSE_AWK_EOPERAND, &nde->loc); + SETERR_LOC (rtx, QSE_AWK_EOPERAND, &nde->loc); return QSE_NULL; } - QSE_ASSERT (exp->left->next == QSE_NULL); - left = eval_expression (run, exp->left); - if (left == QSE_NULL) return QSE_NULL; - - qse_awk_rtx_refupval (run, left); - if (exp->opcode == QSE_AWK_INCOP_PLUS) { - if (left->type == QSE_AWK_VAL_INT) - { - qse_awk_int_t r = ((qse_awk_val_int_t*)left)->val; - res = qse_awk_rtx_makeintval (run, r); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makeintval (run, r + 1); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else if (left->type == QSE_AWK_VAL_FLT) - { - qse_awk_flt_t r = ((qse_awk_val_flt_t*)left)->val; - res = qse_awk_rtx_makefltval (run, r); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makefltval (run, r + 1.0); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else - { - qse_awk_int_t v1; - qse_awk_flt_t v2; - int n; - - n = qse_awk_rtx_valtonum (run, left, &v1, &v2); - if (n <= -1) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - if (n == 0) - { - res = qse_awk_rtx_makeintval (run, v1); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makeintval (run, v1 + 1); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else /* if (n == 1) */ - { - QSE_ASSERT (n == 1); - res = qse_awk_rtx_makefltval (run, v2); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makefltval (run, v2 + 1.0); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - } + inc_val_int = 1; + inc_val_flt = 1.0; } else if (exp->opcode == QSE_AWK_INCOP_MINUS) { - if (left->type == QSE_AWK_VAL_INT) - { - qse_awk_int_t r = ((qse_awk_val_int_t*)left)->val; - res = qse_awk_rtx_makeintval (run, r); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makeintval (run, r - 1); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else if (left->type == QSE_AWK_VAL_FLT) - { - qse_awk_flt_t r = ((qse_awk_val_flt_t*)left)->val; - res = qse_awk_rtx_makefltval (run, r); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makefltval (run, r - 1.0); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else - { - qse_awk_int_t v1; - qse_awk_flt_t v2; - int n; - - n = qse_awk_rtx_valtonum (run, left, &v1, &v2); - if (n == -1) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - if (n == 0) - { - res = qse_awk_rtx_makeintval (run, v1); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makeintval (run, v1 - 1); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - else /* if (n == 1) */ - { - QSE_ASSERT (n == 1); - res = qse_awk_rtx_makefltval (run, v2); - if (res == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - - res2 = qse_awk_rtx_makefltval (run, v2 - 1.0); - if (res2 == QSE_NULL) - { - qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, 1); - ADJERR_LOC (run, &nde->loc); - return QSE_NULL; - } - } - } + inc_val_int = -1; + inc_val_flt = -1.0; } else { QSE_ASSERT (!"should never happen - invalid opcode"); - qse_awk_rtx_refdownval (run, left); - SETERR_LOC (run, QSE_AWK_EINTERN, &nde->loc); + SETERR_LOC (rtx, QSE_AWK_EINTERN, &nde->loc); return QSE_NULL; } - if (do_assignment (run, exp->left, res2) == QSE_NULL) + QSE_ASSERT (exp->left->next == QSE_NULL); + left = eval_expression (rtx, exp->left); + if (left == QSE_NULL) return QSE_NULL; + + qse_awk_rtx_refupval (rtx, left); + + left_vtype = qse_awk_rtx_getvaltype (rtx, left); + + switch (left_vtype) { - qse_awk_rtx_refdownval (run, left); + case QSE_AWK_VAL_INT: + { + qse_awk_int_t r = qse_awk_rtx_getintfromval (rtx, left); + res = qse_awk_rtx_makeintval (rtx, r); + if (res == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + res2 = qse_awk_rtx_makeintval (rtx, r + inc_val_int); + if (res2 == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + qse_awk_rtx_freeval (rtx, res, 1); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + break; + } + + case QSE_AWK_VAL_FLT: + { + qse_awk_flt_t r = ((qse_awk_val_flt_t*)left)->val; + res = qse_awk_rtx_makefltval (rtx, r); + if (res == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + res2 = qse_awk_rtx_makefltval (rtx, r + inc_val_flt); + if (res2 == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + qse_awk_rtx_freeval (rtx, res, 1); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + break; + } + + default: + { + qse_awk_int_t v1; + qse_awk_flt_t v2; + int n; + + n = qse_awk_rtx_valtonum (rtx, left, &v1, &v2); + if (n <= -1) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + if (n == 0) + { + res = qse_awk_rtx_makeintval (rtx, v1); + if (res == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + res2 = qse_awk_rtx_makeintval (rtx, v1 + inc_val_int); + if (res2 == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + qse_awk_rtx_freeval (rtx, res, 1); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + } + else /* if (n == 1) */ + { + QSE_ASSERT (n == 1); + res = qse_awk_rtx_makefltval (rtx, v2); + if (res == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + + res2 = qse_awk_rtx_makefltval (rtx, v2 + inc_val_flt); + if (res2 == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); + qse_awk_rtx_freeval (rtx, res, 1); + ADJERR_LOC (rtx, &nde->loc); + return QSE_NULL; + } + } + + break; + } + } + + if (do_assignment (rtx, exp->left, res2) == QSE_NULL) + { + qse_awk_rtx_refdownval (rtx, left); return QSE_NULL; } - qse_awk_rtx_refdownval (run, left); + qse_awk_rtx_refdownval (rtx, left); return res; } @@ -6107,10 +6020,12 @@ static qse_awk_val_t** get_reference_indexed ( qse_char_t* str; qse_size_t len; qse_char_t idxbuf[IDXBUFSIZE]; + qse_awk_val_type_t vtype; QSE_ASSERT (val != QSE_NULL); - if ((*val)->type == QSE_AWK_VAL_NIL) + vtype = qse_awk_rtx_getvaltype (rtx, *val); + if (vtype == QSE_AWK_VAL_NIL) { qse_awk_val_t* tmp; @@ -6125,7 +6040,7 @@ static qse_awk_val_t** get_reference_indexed ( *val = tmp; qse_awk_rtx_refupval (run, (qse_awk_val_t*)*val); } - else if ((*val)->type != QSE_AWK_VAL_MAP) + else if (vtype != QSE_AWK_VAL_MAP) { SETERR_LOC (run, QSE_AWK_ENOTMAP, &nde->loc); return QSE_NULL; @@ -6239,10 +6154,12 @@ static qse_awk_val_t* eval_indexed ( qse_char_t* str; qse_size_t len; qse_char_t idxbuf[IDXBUFSIZE]; + qse_awk_val_type_t vtype; QSE_ASSERT (val != QSE_NULL); - if ((*val)->type == QSE_AWK_VAL_NIL) + vtype = qse_awk_rtx_getvaltype (run, *val); + if (vtype == QSE_AWK_VAL_NIL) { qse_awk_val_t* tmp; @@ -6257,7 +6174,7 @@ static qse_awk_val_t* eval_indexed ( *val = tmp; qse_awk_rtx_refupval (run, (qse_awk_val_t*)*val); } - else if ((*val)->type != QSE_AWK_VAL_MAP) + else if (vtype != QSE_AWK_VAL_MAP) { SETERR_LOC (run, QSE_AWK_ENOTMAP, &nde->loc); return QSE_NULL; @@ -6355,6 +6272,7 @@ static qse_awk_val_t* eval_getline (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) qse_char_t* dst; qse_str_t* buf; int n, x; + qse_awk_val_type_t vtype; p = (qse_awk_nde_getline_t*)nde; @@ -6373,7 +6291,8 @@ static qse_awk_val_t* eval_getline (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) if (v == QSE_NULL) return QSE_NULL; qse_awk_rtx_refupval (rtx, v); - if (v->type == QSE_AWK_VAL_STR) + vtype = qse_awk_rtx_getvaltype (rtx, v); + if (vtype == QSE_AWK_VAL_STR) { dst = ((qse_awk_val_str_t*)v)->val.ptr; len = ((qse_awk_val_str_t*)v)->val.len; @@ -6393,7 +6312,7 @@ static qse_awk_val_t* eval_getline (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) { /* the input source name is empty. * make getline return -1 */ - if (v->type == QSE_AWK_VAL_STR) + if (vtype == QSE_AWK_VAL_STR) qse_awk_rtx_refdownval (rtx, v); else QSE_AWK_FREE (rtx->awk, dst); @@ -6409,7 +6328,7 @@ static qse_awk_val_t* eval_getline (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) * character. make getline return -1. * unlike print & printf, it is not a hard * error */ - if (v->type == QSE_AWK_VAL_STR) + if (vtype == QSE_AWK_VAL_STR) qse_awk_rtx_refdownval (rtx, v); else QSE_AWK_FREE (rtx->awk, dst); @@ -6428,7 +6347,7 @@ read_console_again: if (p->in) { - if (v->type == QSE_AWK_VAL_STR) + if (vtype == QSE_AWK_VAL_STR) qse_awk_rtx_refdownval (rtx, v); else QSE_AWK_FREE (rtx->awk, dst); } @@ -6576,6 +6495,7 @@ static int shorten_record (qse_awk_rtx_t* run, qse_size_t nflds) qse_char_t* ofs_free = QSE_NULL, * ofs_ptr; qse_size_t ofs_len, i; qse_str_t tmp; + qse_awk_val_type_t vtype; QSE_ASSERT (nflds <= run->inrec.nflds); @@ -6583,14 +6503,15 @@ static int shorten_record (qse_awk_rtx_t* run, qse_size_t nflds) { v = RTX_STACK_GBL(run, QSE_AWK_GBL_OFS); qse_awk_rtx_refupval (run, v); + vtype = qse_awk_rtx_getvaltype (run, v); - if (v->type == QSE_AWK_VAL_NIL) + if (vtype == QSE_AWK_VAL_NIL) { /* OFS not set */ ofs_ptr = QSE_T(" "); ofs_len = 1; } - else if (v->type == QSE_AWK_VAL_STR) + else if (vtype == QSE_AWK_VAL_STR) { ofs_ptr = ((qse_awk_val_str_t*)v)->val.ptr; ofs_len = ((qse_awk_val_str_t*)v)->val.len; @@ -7303,6 +7224,7 @@ wp_mod_main: qse_char_t ch; qse_size_t ch_len; qse_awk_val_t* v; + qse_awk_val_type_t vtype; if (args == QSE_NULL) { @@ -7332,7 +7254,8 @@ wp_mod_main: } qse_awk_rtx_refupval (rtx, v); - switch (v->type) + vtype = qse_awk_rtx_getvaltype (rtx, v); + switch (vtype) { case QSE_AWK_VAL_NIL: ch = QSE_T('\0'); @@ -7340,7 +7263,7 @@ wp_mod_main: break; case QSE_AWK_VAL_INT: - ch = (qse_char_t)((qse_awk_val_int_t*)v)->val; + ch = (qse_char_t)qse_awk_rtx_getintfromval (rtx, v); ch_len = 1; break; @@ -7420,6 +7343,7 @@ wp_mod_main: qse_size_t str_len; qse_awk_int_t k; qse_awk_val_t* v; + qse_awk_val_type_t vtype; if (args == QSE_NULL) { @@ -7449,37 +7373,43 @@ wp_mod_main: } qse_awk_rtx_refupval (rtx, v); - if (v->type == QSE_AWK_VAL_NIL) - { - str_ptr = QSE_T(""); - str_len = 0; - } - else if (v->type == QSE_AWK_VAL_STR) - { - str_ptr = ((qse_awk_val_str_t*)v)->val.ptr; - str_len = ((qse_awk_val_str_t*)v)->val.len; - } - else - { - qse_awk_rtx_valtostr_out_t out; - if (v == val) - { - qse_awk_rtx_refdownval (rtx, v); - SETERR_COD (rtx, QSE_AWK_EFMTCNV); - return QSE_NULL; - } - - out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) - { - qse_awk_rtx_refdownval (rtx, v); - return QSE_NULL; - } + vtype = qse_awk_rtx_getvaltype (rtx, v); + switch (vtype) + { + case QSE_AWK_VAL_NIL: + str_ptr = QSE_T(""); + str_len = 0; + break; - str_ptr = out.u.cpldup.ptr; - str_len = out.u.cpldup.len; - str_free = str_ptr; + case QSE_AWK_VAL_STR: + str_ptr = ((qse_awk_val_str_t*)v)->val.ptr; + str_len = ((qse_awk_val_str_t*)v)->val.len; + break; + + default: + { + qse_awk_rtx_valtostr_out_t out; + + if (v == val) + { + qse_awk_rtx_refdownval (rtx, v); + SETERR_COD (rtx, QSE_AWK_EFMTCNV); + return QSE_NULL; + } + + out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; + if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) + { + qse_awk_rtx_refdownval (rtx, v); + return QSE_NULL; + } + + str_ptr = out.u.cpldup.ptr; + str_len = out.u.cpldup.len; + str_free = str_ptr; + break; + } } if (wp[WP_PRECISION] == -1 || wp[WP_PRECISION] > (qse_awk_int_t)str_len) wp[WP_PRECISION] = (qse_awk_int_t)str_len; diff --git a/qse/lib/awk/run.h b/qse/lib/awk/run.h index 3bf54aba..4261a0fc 100644 --- a/qse/lib/awk/run.h +++ b/qse/lib/awk/run.h @@ -91,7 +91,7 @@ enum qse_awk_unrop_type_t QSE_AWK_UNROP_MINUS, QSE_AWK_UNROP_LNOT, QSE_AWK_UNROP_BNOT, - QSE_AWK_UNROP_DEF /* : in the unary operation context */ + QSE_AWK_UNROP_DEF /* `, is defined */ }; enum qse_awk_incop_type_t diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 647475b8..9f97d8b1 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -1392,7 +1392,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) */ argv = qse_awk_rtx_getgbl (rtx, xtn->gbl_argv); QSE_ASSERT (argv != QSE_NULL); - QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, argv) == QSE_AWK_VAL_MAP); map = ((qse_awk_val_map_t*)argv)->map; QSE_ASSERT (map != QSE_NULL); diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 522a3df7..268dc2dd 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -71,7 +71,7 @@ qse_awk_val_t* qse_getawknilval (void) int qse_awk_rtx_isnilval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) { - return val->type == QSE_AWK_VAL_NIL; + return val->v_type == QSE_AWK_VAL_NIL; } qse_awk_val_t* qse_awk_rtx_makenilval (qse_awk_rtx_t* rtx) @@ -79,14 +79,50 @@ qse_awk_val_t* qse_awk_rtx_makenilval (qse_awk_rtx_t* rtx) return (qse_awk_val_t*)&awk_nil; } + +#define NUM_TYPE_BITS 2 +#define TYPE_BITS_POINTER 0 +#define TYPE_BITS_QUICKINT 1 +#define TYPE_BITS_RESERVED_1 2 +#define TYPE_BITS_RESERVED_2 3 +#define SIGN_BIT ((qse_uintptr_t)1 << (QSE_SIZEOF(qse_uintptr_t) * 8 - 1)) + +/* shrink the bit range by 1 more bit to ease signbit handling. + * i want abs(max) == abs(min). + * i don't want abs(max) + 1 == abs(min). e.g min: -32768, max: 32767 + */ +#define QUICKINT_MAX ((~(qse_uintptr_t)0) >> (NUM_TYPE_BITS + 1)) +#define QUICKINT_MIN (-QUICKINT_MAX) + +#define IS_QUICKINT(v) ((v) >= QUICKINT_MIN && (v) <= QUICKINT_MAX) +#define POINTER_TYPE_BITS(p) (((qse_uintptr_t)(p)) | NUM_TYPE_BITS) + +static QSE_INLINE qse_awk_val_t* quickint_to_pointer (qse_awk_int_t v) +{ + qse_uintptr_t r; + + if (v < 0) + { + r = (((qse_uintptr_t)-v) << NUM_TYPE_BITS) | TYPE_BITS_QUICKINT | SIGN_BIT; + } + else + { + r = ((qse_uintptr_t)v << NUM_TYPE_BITS) | TYPE_BITS_QUICKINT; + } + + return (qse_awk_val_t*)r; +} + qse_awk_val_t* qse_awk_rtx_makeintval (qse_awk_rtx_t* rtx, qse_awk_int_t v) { qse_awk_val_int_t* val; - if (v >= awk_int[0].val && - v <= awk_int[QSE_COUNTOF(awk_int)-1].val) +// if (IS_QUICKINT(v)) return quickint_to_pinter (v); + + if (v >= awk_int[0].i_val && + v <= awk_int[QSE_COUNTOF(awk_int)-1].i_val) { - return (qse_awk_val_t*)&awk_int[v-awk_int[0].val]; + return (qse_awk_val_t*)&awk_int[v-awk_int[0].i_val]; } if (rtx->vmgr.ifree == QSE_NULL) @@ -132,11 +168,11 @@ qse_awk_val_t* qse_awk_rtx_makeintval (qse_awk_rtx_t* rtx, qse_awk_int_t v) val = rtx->vmgr.ifree; rtx->vmgr.ifree = (qse_awk_val_int_t*)val->nde; - val->type = QSE_AWK_VAL_INT; + val->v_type = QSE_AWK_VAL_INT; val->ref = 0; val->stat = 0; val->nstr = 0; - val->val = v; + val->i_val = v; val->nde = QSE_NULL; #ifdef DEBUG_VAL @@ -188,7 +224,7 @@ qse_awk_val_t* qse_awk_rtx_makefltval (qse_awk_rtx_t* rtx, qse_awk_flt_t v) val = rtx->vmgr.rfree; rtx->vmgr.rfree = (qse_awk_val_flt_t*)val->nde; - val->type = QSE_AWK_VAL_FLT; + val->v_type = QSE_AWK_VAL_FLT; val->ref = 0; val->stat = 0; val->nstr = 0; @@ -235,7 +271,7 @@ qse_awk_val_t* qse_awk_rtx_makestrvalwithxstr ( #ifdef ENABLE_FEATURE_SCACHE init: #endif - val->type = QSE_AWK_VAL_STR; + val->v_type = QSE_AWK_VAL_STR; val->ref = 0; val->stat = 0; val->nstr = 0; @@ -392,7 +428,7 @@ qse_awk_val_t* qse_awk_rtx_makestrval2 ( #ifdef ENABLE_FEATURE_SCACHE init: #endif - val->type = QSE_AWK_VAL_STR; + val->v_type = QSE_AWK_VAL_STR; val->ref = 0; val->stat = 0; val->nstr = 0; @@ -457,7 +493,7 @@ qse_awk_val_t* qse_awk_rtx_makerexval ( return QSE_NULL; } - val->type = QSE_AWK_VAL_REX; + val->v_type = QSE_AWK_VAL_REX; val->ref = 0; val->stat = 0; val->nstr = 0; @@ -554,7 +590,7 @@ qse_awk_val_t* qse_awk_rtx_makemapval (qse_awk_rtx_t* rtx) return QSE_NULL; } - val->type = QSE_AWK_VAL_MAP; + val->v_type = QSE_AWK_VAL_MAP; val->ref = 0; val->stat = 0; val->nstr = 0; @@ -643,7 +679,7 @@ qse_awk_val_t* qse_awk_rtx_setmapvalfld ( qse_awk_rtx_t* rtx, qse_awk_val_t* map, const qse_char_t* kptr, qse_size_t klen, qse_awk_val_t* v) { - QSE_ASSERT (map->type == QSE_AWK_VAL_MAP); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, map) == QSE_AWK_VAL_MAP); if (qse_htb_upsert ( ((qse_awk_val_map_t*)map)->map, @@ -668,7 +704,7 @@ qse_awk_val_t* qse_awk_rtx_getmapvalfld ( { qse_htb_pair_t* pair; - QSE_ASSERT (map->type == QSE_AWK_VAL_MAP); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, map) == QSE_AWK_VAL_MAP); pair = qse_htb_search (((qse_awk_val_map_t*)map)->map, kptr, klen); if (pair == QSE_NULL) @@ -689,18 +725,18 @@ qse_awk_val_t* qse_awk_rtx_getmapvalfld ( qse_awk_val_map_itr_t* qse_awk_rtx_getfirstmapvalitr ( qse_awk_rtx_t* rtx, qse_awk_val_t* map, qse_awk_val_map_itr_t* itr) { - QSE_ASSERT (map->type == QSE_AWK_VAL_MAP); - itr->pair = qse_htb_getfirstpair ( - ((qse_awk_val_map_t*)map)->map, &itr->buckno); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, map) == QSE_AWK_VAL_MAP); + + itr->pair = qse_htb_getfirstpair (((qse_awk_val_map_t*)map)->map, &itr->buckno); return itr->pair? itr: QSE_NULL; } qse_awk_val_map_itr_t* qse_awk_rtx_getnextmapvalitr ( qse_awk_rtx_t* rtx, qse_awk_val_t* map, qse_awk_val_map_itr_t* itr) { - QSE_ASSERT (map->type == QSE_AWK_VAL_MAP); - itr->pair = qse_htb_getnextpair ( - ((qse_awk_val_map_t*)map)->map, itr->pair, &itr->buckno); + QSE_ASSERT (qse_awk_rtx_getvaltype (rtx, map) == QSE_AWK_VAL_MAP); + + itr->pair = qse_htb_getnextpair (((qse_awk_val_map_t*)map)->map, itr->pair, &itr->buckno); return itr->pair? itr: QSE_NULL; } @@ -724,7 +760,7 @@ qse_awk_val_t* qse_awk_rtx_makerefval ( } } - val->type = QSE_AWK_VAL_REF; + val->v_type = QSE_AWK_VAL_REF; val->ref = 0; val->stat = 0; val->nstr = 0; @@ -746,7 +782,7 @@ qse_awk_val_t* qse_awk_rtx_makefunval ( return QSE_NULL; } - val->type = QSE_AWK_VAL_FUN; + val->v_type = QSE_AWK_VAL_FUN; val->fun = (qse_awk_fun_t*)fun; return (qse_awk_val_t*)val; @@ -777,9 +813,20 @@ int qse_awk_rtx_isstaticval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) return IS_STATICVAL(val); } -void qse_awk_rtx_freeval ( - qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache) +void qse_awk_rtx_freeval (qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache) { + qse_awk_val_type_t vtype; + + switch (POINTER_TYPE_BITS(val)) + { +// case TYPE_BITS_QUICKINT: + /* do nothing */ +// return; + + default: + break; + } + if (IS_STATICVAL(val)) return; #ifdef DEBUG_VAL @@ -788,7 +835,8 @@ void qse_awk_rtx_freeval ( qse_errputstrf (QSE_T("\n")); #endif - switch (val->type) + vtype = qse_awk_rtx_getvaltype (rtx, val); + switch (vtype) { case QSE_AWK_VAL_NIL: { @@ -961,7 +1009,7 @@ static int val_ref_to_bool ( /* A reference value is not able to point to another * refernce value for the way values are represented * in QSEAWK */ - QSE_ASSERT ((*xref)->type != 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_valtobool (rtx, *xref); @@ -969,17 +1017,19 @@ static int val_ref_to_bool ( } } - int qse_awk_rtx_valtobool (qse_awk_rtx_t* rtx, const qse_awk_val_t* val) { + qse_awk_val_type_t vtype; + if (val == QSE_NULL) return 0; - switch (val->type) + vtype = qse_awk_rtx_getvaltype (rtx, val); + switch (vtype) { case QSE_AWK_VAL_NIL: return 0; case QSE_AWK_VAL_INT: - return ((qse_awk_val_int_t*)val)->val != 0; + return qse_awk_rtx_getintfromval (rtx, val) != 0; case QSE_AWK_VAL_FLT: return ((qse_awk_val_flt_t*)val)->val != 0.0; case QSE_AWK_VAL_STR: @@ -987,10 +1037,10 @@ int qse_awk_rtx_valtobool (qse_awk_rtx_t* rtx, const qse_awk_val_t* val) case QSE_AWK_VAL_REX: /* TODO: is this correct? */ return ((qse_awk_val_rex_t*)val)->str.len > 0; case QSE_AWK_VAL_MAP: - return 0; /* TODO: is this correct? */ + /* 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); - } QSE_ASSERTX ( @@ -1081,19 +1131,20 @@ static int val_int_to_str ( qse_awk_rtx_valtostr_out_t* out) { qse_char_t* tmp; - qse_awk_uint_t t; qse_size_t rlen = 0; int type = out->type & ~QSE_AWK_RTX_VALTOSTR_PRINT; + qse_awk_int_t orgval = qse_awk_rtx_getintfromval (rtx, v); + qse_awk_uint_t t; - if (v->val == 0) rlen++; + if (orgval == 0) rlen++; else { /* non-zero values */ - if (v->val < 0) + if (orgval < 0) { - t = v->val * -1; rlen++; + t = orgval * -1; rlen++; } - else t = v->val; + else t = orgval; while (t > 0) { rlen++; t /= 10; } } @@ -1179,10 +1230,10 @@ static int val_int_to_str ( } } - if (v->val == 0) tmp[0] = QSE_T('0'); + if (orgval == 0) tmp[0] = QSE_T('0'); else { - t = (v->val < 0)? (v->val * -1): v->val; + t = (orgval < 0)? (orgval * -1): orgval; /* fill in the buffer with digits */ while (t > 0) @@ -1192,7 +1243,7 @@ static int val_int_to_str ( } /* insert the negative sign if necessary */ - if (v->val < 0) tmp[--rlen] = QSE_T('-'); + if (orgval < 0) tmp[--rlen] = QSE_T('-'); } return 0; @@ -1365,7 +1416,7 @@ static int val_ref_to_str ( /* A reference value is not able to point to another * refernce value for the way values are represented * in QSEAWK */ - QSE_ASSERT ((*xref)->type != 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_valtostr (rtx, *xref, out); @@ -1377,7 +1428,9 @@ int qse_awk_rtx_valtostr ( qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_rtx_valtostr_out_t* out) { - switch (v->type) + qse_awk_val_type_t vtype = qse_awk_rtx_getvaltype (rtx, v); + + switch (vtype) { case QSE_AWK_VAL_NIL: { @@ -1492,7 +1545,7 @@ qse_wchar_t* qse_awk_rtx_valtowcsdup ( qse_char_t* qse_awk_rtx_getvalstr ( qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_size_t* len) { - if (v->type == QSE_AWK_VAL_STR) + if (qse_awk_rtx_getvaltype(rtx, v) == QSE_AWK_VAL_STR) { if (len) *len = ((qse_awk_val_str_t*)v)->val.len; return ((qse_awk_val_str_t*)v)->val.ptr; @@ -1506,7 +1559,7 @@ qse_char_t* qse_awk_rtx_getvalstr ( void qse_awk_rtx_freevalstr ( qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_char_t* str) { - if (v->type != QSE_AWK_VAL_STR && + if (qse_awk_rtx_getvaltype(rtx, v) != QSE_AWK_VAL_STR && str != ((qse_awk_val_str_t*)v)->val.ptr) { qse_awk_rtx_freemem (rtx, str); @@ -1563,7 +1616,7 @@ static int val_ref_to_num ( /* A reference value is not able to point to another * refernce value for the way values are represented * in QSEAWK */ - QSE_ASSERT ((*xref)->type != 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); @@ -1575,7 +1628,9 @@ static int val_ref_to_num ( int qse_awk_rtx_valtonum ( qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_awk_int_t* l, qse_awk_flt_t* r) { - switch (v->type) + qse_awk_val_type_t vtype = qse_awk_rtx_getvaltype (rtx, v); + + switch (vtype) { case QSE_AWK_VAL_NIL: { @@ -1585,7 +1640,7 @@ int qse_awk_rtx_valtonum ( case QSE_AWK_VAL_INT: { - *l = ((qse_awk_val_int_t*)v)->val; + *l = qse_awk_rtx_getintfromval (rtx, v); return 0; /* long */ } @@ -1691,20 +1746,22 @@ static qse_awk_uint_t hash (qse_uint8_t* ptr, qse_size_t len) qse_awk_int_t qse_awk_rtx_hashval (qse_awk_rtx_t* rtx, qse_awk_val_t* v) { + qse_awk_val_type_t vtype = qse_awk_rtx_getvaltype (rtx, v); qse_awk_int_t hv; - switch (v->type) + switch (vtype) { case QSE_AWK_VAL_NIL: hv = 0; break; case QSE_AWK_VAL_INT: + { + qse_awk_int_t tmp = qse_awk_rtx_getintfromval (rtx, v); /*hv = ((qse_awk_val_int_t*)v)->val;*/ - hv = (qse_awk_int_t)hash ( - (qse_uint8_t*)&((qse_awk_val_int_t*)v)->val, - QSE_SIZEOF(((qse_awk_val_int_t*)v)->val)); + hv = (qse_awk_int_t)hash ((qse_uint8_t*)&tmp, QSE_SIZEOF(tmp)); break; + } case QSE_AWK_VAL_FLT: hv = (qse_awk_int_t)hash ( @@ -1736,14 +1793,16 @@ qse_awk_int_t qse_awk_rtx_hashval (qse_awk_rtx_t* rtx, qse_awk_val_t* v) int qse_awk_rtx_setrefval (qse_awk_rtx_t* rtx, qse_awk_val_ref_t* ref, qse_awk_val_t* val) { - if (val->type == QSE_AWK_VAL_REX || val->type == QSE_AWK_VAL_REF) + qse_awk_val_type_t vtype = qse_awk_rtx_getvaltype (rtx, val); + + if (vtype == QSE_AWK_VAL_REX || vtype == QSE_AWK_VAL_REF) { /* though it is possible that an intrinsic function handler * can accept a regular expression withtout evaluation when 'x' * is specified for the parameter, this function doesn't allow * regular expression to be set to a reference variable to * avoid potential chaos. the nature of performing '/rex/ ~ $0' - * for a regular expression without the match operator + * for a regular expression without the match operator * makes it difficult to be implemented. */ qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL); return -1; @@ -1753,13 +1812,12 @@ int qse_awk_rtx_setrefval (qse_awk_rtx_t* rtx, qse_awk_val_ref_t* ref, qse_awk_v { case QSE_AWK_VAL_REF_POS: { - - switch (val->type) + switch (vtype) { case QSE_AWK_VAL_MAP: /* a map is assigned to a positional. this is disallowed. */ qse_awk_rtx_seterrnum (rtx, QSE_AWK_EMAPTOPOS, QSE_NULL); - return -1; + return -1; case QSE_AWK_VAL_STR: { @@ -1799,25 +1857,26 @@ int qse_awk_rtx_setrefval (qse_awk_rtx_t* rtx, qse_awk_val_ref_t* ref, qse_awk_v case QSE_AWK_VAL_REF_GBLIDX: case QSE_AWK_VAL_REF_LCLIDX: case QSE_AWK_VAL_REF_ARGIDX: - if (val->type == QSE_AWK_VAL_MAP) + if (vtype == QSE_AWK_VAL_MAP) { /* an indexed variable cannot be assigned a map. * in other cases, it falls down to the default case. */ qse_awk_rtx_seterrnum (rtx, QSE_AWK_EMAPTOIDX, QSE_NULL); - return -1; + return -1; } /* fall through */ default: { qse_awk_val_t** rref; - - rref = (qse_awk_val_t**)ref->adr; - if (val->type == QSE_AWK_VAL_MAP) + qse_awk_val_type_t rref_vtype; + + rref = (qse_awk_val_t**)ref->adr; /* old value pointer */ + rref_vtype = qse_awk_rtx_getvaltype (rtx, *rref); /* old value type */ + if (vtype == QSE_AWK_VAL_MAP) { /* new value: map, old value: nil or map => ok */ - if ((*rref)->type != QSE_AWK_VAL_NIL && - (*rref)->type != QSE_AWK_VAL_MAP) + if (rref_vtype != QSE_AWK_VAL_NIL && rref_vtype != QSE_AWK_VAL_MAP) { if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP)) { @@ -1830,7 +1889,7 @@ int qse_awk_rtx_setrefval (qse_awk_rtx_t* rtx, qse_awk_val_ref_t* ref, qse_awk_v else { /* new value: scalar, old value: nil or scalar => ok */ - if ((*rref)->type == QSE_AWK_VAL_MAP) + if (rref_vtype == QSE_AWK_VAL_MAP) { if (!(rtx->awk->opt.trait & QSE_AWK_FLEXMAP)) {