diff --git a/hawk/lib/hawk-prv.h b/hawk/lib/hawk-prv.h index d6e4f6e4..4edc66ba 100644 --- a/hawk/lib/hawk-prv.h +++ b/hawk/lib/hawk-prv.h @@ -594,7 +594,7 @@ static HAWK_INLINE void HAWK_RTX_STACK_POP (hawk_rtx_t* rtx) (refval)->v_type = HAWK_VAL_REF; \ (refval)->v_refs = (_nrefs); \ (refval)->v_static = 0; \ - (refval)->nstr = 0; \ + (refval)->v_nstr = 0; \ (refval)->v_gc = 0; \ (refval)->id = (_id); \ (refval)->adr = (_adr); \ diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index 77fcb75b..b2cef2d8 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -161,21 +161,22 @@ static HAWK_INLINE hawk_gch_t* hawk_val_to_gch(hawk_val_t* v) * - v_type - type of a value from #hawk_val_type_t * - v_refs - reference count * - v_static - static value indicator - * - nstr - numeric string marker, 1 -> integer, 2 -> floating-point number + * - v_nstr - numeric string marker, 1 -> integer, 2 -> floating-point number + * - v_gc - used for garbage collection together with v_refs */ /* #define HAWK_VAL_HDR \ unsigned int v_type: 4; \ unsigned int v_refs: 24; \ unsigned int v_static: 1; \ - unsigned int nstr: 2; \ + unsigned int v_nstr: 2; \ unsigned int v_gc: 1 */ #define HAWK_VAL_HDR \ hawk_uintptr_t v_type: 4; \ hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \ hawk_uintptr_t v_static: 1; \ - hawk_uintptr_t nstr: 2; \ + hawk_uintptr_t v_nstr: 2; \ hawk_uintptr_t v_gc: 1 /** @@ -2841,28 +2842,44 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_makenstrvalwithbcs ( * The hawk_rtx_makembsvalwithbchars() function create a byte array value. * \return value on success, #HAWK_NULL on failure */ -hawk_val_t* hawk_rtx_makembsvalwithbchars ( +HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithbchars ( hawk_rtx_t* rtx, const hawk_bch_t* ptr, hawk_oow_t len ); -hawk_val_t* hawk_rtx_makembsvalwithuchars ( +HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithuchars ( hawk_rtx_t* rtx, const hawk_uch_t* ptr, hawk_oow_t len ); -hawk_val_t* hawk_rtx_makembsvalwithbcs ( +HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithbcs ( hawk_rtx_t* rtx, const hawk_bcs_t* bcs ); -hawk_val_t* hawk_rtx_makembsvalwithucs ( +HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithucs ( hawk_rtx_t* rtx, const hawk_ucs_t* ucs ); +HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithuchars2 ( + hawk_rtx_t* rtx, + const hawk_uch_t* ucs1, + hawk_oow_t len1, + const hawk_uch_t* ucs2, + hawk_oow_t len2 +); + +HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithbchars2 ( + hawk_rtx_t* rtx, + const hawk_bch_t* bcs1, + hawk_oow_t len1, + const hawk_bch_t* bcs2, + hawk_oow_t len2 +); + /* -------------------------------------------------------------------------- */ HAWK_EXPORT hawk_val_t* hawk_rtx_makenumormbsvalwithuchars ( diff --git a/hawk/lib/mod-str.c b/hawk/lib/mod-str.c index 663caac6..e19a4205 100644 --- a/hawk/lib/mod-str.c +++ b/hawk/lib/mod-str.c @@ -250,7 +250,10 @@ static int fnc_isxdigit (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) static int fnc_fromcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) { - /* create a string from a series of charcter codes */ + /* create a string from a series of character codes. + * create a character from a single character code. + * - str::fromcharcode(65) for 'A' + * - str::fromcharcode(65, 66, 67) for "ABC" */ hawk_val_t* retv; hawk_oow_t nargs, i; @@ -258,24 +261,38 @@ static int fnc_fromcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) nargs = hawk_rtx_getnargs(rtx); - retv = hawk_rtx_makestrvalwithoochars(rtx, HAWK_NULL, nargs); - if (!retv) return -1; - - ptr0 = (hawk_oochu_t*)((hawk_val_str_t*)retv)->val.ptr; - - for (i = 0; i < nargs; i++) + if (nargs == 1) { hawk_val_t* a0; hawk_int_t cc; - a0 = hawk_rtx_getarg(rtx, i); - if (hawk_rtx_valtoint(rtx, a0, &cc) <= -1) - { - hawk_rtx_freeval (rtx, retv, 0); - return -1; - } + a0 = hawk_rtx_getarg(rtx, 0); + if (hawk_rtx_valtoint(rtx, a0, &cc) <= -1) return -1; - ptr0[i] = cc; + retv = hawk_rtx_makecharval(rtx, (hawk_ooch_t)cc); + if (HAWK_UNLIKELY(!retv)) return -1; + } + else + { + retv = hawk_rtx_makestrvalwithoochars(rtx, HAWK_NULL, nargs); + if (HAWK_UNLIKELY(!retv)) return -1; + + ptr0 = (hawk_oochu_t*)((hawk_val_str_t*)retv)->val.ptr; + + for (i = 0; i < nargs; i++) + { + hawk_val_t* a0; + hawk_int_t cc; + + a0 = hawk_rtx_getarg(rtx, i); + if (hawk_rtx_valtoint(rtx, a0, &cc) <= -1) + { + hawk_rtx_freeval (rtx, retv, 0); + return -1; + } + + ptr0[i] = cc; + } } hawk_rtx_setretval (rtx, retv); @@ -466,7 +483,7 @@ done: static int fnc_tonum (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) { /* str::tonum(value) */ - /* str::tonum(string, base) */ + /* str::tonum(string/character, base) */ /*hawk_t* hawk = hawk_rtx_gethawk(rtx);*/ hawk_val_t* retv; diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 2e0d7d42..05367a7e 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -4772,8 +4772,8 @@ static HAWK_INLINE int __cmp_int_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va hawk_oow_t len0; int n; - /* SCO CC doesn't seem to handle right->nstr > 0 properly */ - if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/) + /* SCO CC doesn't seem to handle right->v_nstr > 0 properly */ + if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/) { hawk_int_t ll, v1; hawk_flt_t rr; @@ -4813,7 +4813,7 @@ static HAWK_INLINE int __cmp_int_mbs (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va hawk_oow_t len0; int n; - if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/) + if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/) { hawk_int_t ll, v1; hawk_flt_t rr; @@ -4902,8 +4902,8 @@ static HAWK_INLINE int __cmp_flt_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va hawk_oow_t len0; int n; - /* SCO CC doesn't seem to handle right->nstr > 0 properly */ - if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/) + /* SCO CC doesn't seem to handle right->v_nstr > 0 properly */ + if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/) { const hawk_ooch_t* end; hawk_flt_t rr; @@ -4931,7 +4931,7 @@ static HAWK_INLINE int __cmp_flt_mbs (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va hawk_oow_t len0; int n; - if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/) + if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/) { const hawk_bch_t* end; hawk_flt_t rr; @@ -5005,7 +5005,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va ls = (hawk_val_str_t*)left; rs = (hawk_val_str_t*)right; - if (HAWK_LIKELY(ls->nstr == 0 || rs->nstr == 0)) + if (HAWK_LIKELY(ls->v_nstr == 0 || rs->v_nstr == 0)) { /* both are definitely strings */ return hawk_comp_oochars(ls->val.ptr, ls->val.len, rs->val.ptr, rs->val.len, rtx->gbl.ignorecase); @@ -5013,13 +5013,13 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va stripspc = HAWK_RTX_IS_STRIPSTRSPC_ON(rtx); - if (ls->nstr == 1) + if (ls->v_nstr == 1) { hawk_int_t ll; ll = hawk_oochars_to_int(ls->val.ptr, ls->val.len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(stripspc, stripspc, 0), HAWK_NULL, HAWK_NULL); - if (rs->nstr == 1) + if (rs->v_nstr == 1) { hawk_int_t rr; @@ -5032,7 +5032,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va { hawk_flt_t rr; - HAWK_ASSERT (rs->nstr == 2); + HAWK_ASSERT (rs->v_nstr == 2); rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, stripspc); @@ -5044,11 +5044,11 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va { hawk_flt_t ll; - HAWK_ASSERT (ls->nstr == 2); + HAWK_ASSERT (ls->v_nstr == 2); ll = hawk_oochars_to_flt(ls->val.ptr, ls->val.len, HAWK_NULL, stripspc); - if (rs->nstr == 1) + if (rs->v_nstr == 1) { hawk_int_t rr; @@ -5061,7 +5061,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va { hawk_flt_t rr; - HAWK_ASSERT (rs->nstr == 2); + HAWK_ASSERT (rs->v_nstr == 2); rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, stripspc); @@ -5786,26 +5786,46 @@ static hawk_val_t* eval_binop_exp (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t static hawk_val_t* eval_binop_concat (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) { hawk_val_t* res; - hawk_rtx_valtostr_out_t lout, rout; - lout.type = HAWK_RTX_VALTOSTR_CPLDUP; - if (hawk_rtx_valtostr(rtx, left, &lout) <= -1) return HAWK_NULL; - - rout.type = HAWK_RTX_VALTOSTR_CPLDUP; - if (hawk_rtx_valtostr(rtx, right, &rout) <= -1) + if (HAWK_RTX_GETVALTYPE(rtx, left) == HAWK_VAL_MBS) { - hawk_rtx_freemem (rtx, lout.u.cpldup.ptr); - return HAWK_NULL; + hawk_bcs_t l, r; + + l.ptr = hawk_rtx_getvalbcstr(rtx, left, &l.len); + if (HAWK_UNLIKELY(!l.ptr)) return HAWK_NULL; + + r.ptr = hawk_rtx_getvalbcstr(rtx, right, &r.len); + if (HAWK_UNLIKELY(!r.ptr)) + { + hawk_rtx_freevalbcstr (rtx, left, l.ptr); + return HAWK_NULL; + } + + res = (hawk_val_t*)hawk_rtx_makembsvalwithbchars2(rtx, l.ptr, l.len, r.ptr, r.len); + + hawk_rtx_freevalbcstr (rtx, right, r.ptr); + hawk_rtx_freevalbcstr (rtx, left, l.ptr); } + else + { - res = hawk_rtx_makestrvalwithoochars2( - rtx, - lout.u.cpldup.ptr, lout.u.cpldup.len, - rout.u.cpldup.ptr, rout.u.cpldup.len - ); + hawk_oocs_t l, r; - hawk_rtx_freemem (rtx, rout.u.cpldup.ptr); - hawk_rtx_freemem (rtx, lout.u.cpldup.ptr); + l.ptr = hawk_rtx_getvaloocstr(rtx, left, &l.len); + if (HAWK_UNLIKELY(!l.ptr)) return HAWK_NULL; + + r.ptr = hawk_rtx_getvaloocstr(rtx, right, &r.len); + if (HAWK_UNLIKELY(!r.ptr)) + { + hawk_rtx_freevaloocstr (rtx, left, l.ptr); + return HAWK_NULL; + } + + res = (hawk_val_t*)hawk_rtx_makestrvalwithoochars2(rtx, l.ptr, l.len, r.ptr, r.len); + + hawk_rtx_freevaloocstr (rtx, right, r.ptr); + hawk_rtx_freevaloocstr (rtx, left, l.ptr); + } return res; } diff --git a/hawk/lib/utl-str.c b/hawk/lib/utl-str.c index 3b32f58f..c9af7471 100644 --- a/hawk/lib/utl-str.c +++ b/hawk/lib/utl-str.c @@ -2187,7 +2187,7 @@ static const hawk_uch_t* scan_dollar_for_subst_u (const hawk_uch_t* f, hawk_oow_ HAWK_ASSERT (l >= 2); f += 2; /* skip ${ */ - if (ident) ident->ptr = f; + if (ident) ident->ptr = (hawk_uch_t*)f; while (1) { @@ -2208,7 +2208,7 @@ static const hawk_uch_t* scan_dollar_for_subst_u (const hawk_uch_t* f, hawk_oow_ f += 2; /* skip := */ - if (dfl) dfl->ptr = f; + if (dfl) dfl->ptr = (hawk_uch_t*)f; while (1) { if (f >= end) return HAWK_NULL; @@ -2340,7 +2340,7 @@ static const hawk_bch_t* scan_dollar_for_subst_b (const hawk_bch_t* f, hawk_oow_ HAWK_ASSERT (l >= 2); f += 2; /* skip ${ */ - if (ident) ident->ptr = f; + if (ident) ident->ptr = (hawk_bch_t*)f; while (1) { @@ -2361,7 +2361,7 @@ static const hawk_bch_t* scan_dollar_for_subst_b (const hawk_bch_t* f, hawk_oow_ f += 2; /* skip := */ - if (dfl) dfl->ptr = f; + if (dfl) dfl->ptr = (hawk_bch_t*)f; while (1) { if (f >= end) return HAWK_NULL; diff --git a/hawk/lib/val.c b/hawk/lib/val.c index 23bdb121..27525782 100644 --- a/hawk/lib/val.c +++ b/hawk/lib/val.c @@ -224,7 +224,7 @@ static void gc_dump_refs (hawk_rtx_t* rtx, hawk_gch_t* list) gch = list->gc_next; while (gch != list) { - hawk_logbfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, "[GC] GCH %p gc_refs %d\n", gch, (int)gch->gc_refs); + hawk_logbfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, "[GC] GCH %p gc_refs %d\n", gch, (int)gch->gc_refs); gch = gch->gc_next; } hawk_logbfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, "[GC] dumped %ju values\n", count); @@ -533,7 +533,7 @@ hawk_val_t* hawk_rtx_makeintval (hawk_rtx_t* rtx, hawk_int_t v) val->v_type = HAWK_VAL_INT; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; val->i_val = v; val->nde = HAWK_NULL; @@ -572,7 +572,7 @@ hawk_val_t* hawk_rtx_makefltval (hawk_rtx_t* rtx, hawk_flt_t v) val->v_type = HAWK_VAL_FLT; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; val->val = v; val->nde = HAWK_NULL; @@ -615,7 +615,7 @@ init: val->v_type = HAWK_VAL_STR; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; val->val.len = len1 + len2; val->val.ptr = (hawk_ooch_t*)(val + 1); @@ -775,7 +775,7 @@ hawk_val_t* hawk_rtx_makenstrvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* p /* set the numeric string flag if a string * can be converted to a number */ HAWK_ASSERT (x == 0 || x == 1); - v->nstr = x + 1; /* long -> 1, real -> 2 */ + v->v_nstr = x + 1; /* long -> 1, real -> 2 */ } return v; @@ -797,7 +797,7 @@ hawk_val_t* hawk_rtx_makenstrvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* p /* set the numeric string flag if a string * can be converted to a number */ HAWK_ASSERT (x == 0 || x == 1); - v->nstr = x + 1; /* long -> 1, real -> 2 */ + v->v_nstr = x + 1; /* long -> 1, real -> 2 */ } return v; @@ -825,17 +825,16 @@ hawk_val_t* hawk_rtx_makenstrvalwithbcs (hawk_rtx_t* rtx, const hawk_bcs_t* str) /* --------------------------------------------------------------------- */ - -hawk_val_t* hawk_rtx_makembsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* ptr, hawk_oow_t len) +static HAWK_INLINE hawk_val_t* make_mbs_val (hawk_rtx_t* rtx, const hawk_bch_t* mbs1, hawk_oow_t len1, const hawk_bch_t* mbs2, hawk_oow_t len2) { - hawk_val_mbs_t* val; + hawk_val_mbs_t* val = HAWK_NULL; hawk_oow_t aligned_len; #if defined(HAWK_ENABLE_MBS_CACHE) hawk_oow_t i; #endif - if (HAWK_UNLIKELY(len <= 0)) return hawk_val_zlm; - aligned_len = HAWK_ALIGN_POW2((len + 1), HAWK_MBS_CACHE_BLOCK_UNIT); + if (HAWK_UNLIKELY(len1 <= 0 && len2 <= 0)) return hawk_val_zls; + aligned_len = HAWK_ALIGN_POW2((len1 + len2 + 1), HAWK_MBS_CACHE_BLOCK_UNIT); #if defined(HAWK_ENABLE_MBS_CACHE) i = aligned_len / HAWK_MBS_CACHE_BLOCK_UNIT; @@ -858,16 +857,24 @@ init: val->v_type = HAWK_VAL_MBS; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; - val->val.len = len; + val->val.len = len1 + len2; val->val.ptr = (hawk_bch_t*)(val + 1); - if (ptr) HAWK_MEMCPY (val->val.ptr, ptr, len); - val->val.ptr[len] = '\0'; + if (HAWK_LIKELY(mbs1)) hawk_copy_bchars_to_bcstr_unlimited (&val->val.ptr[0], mbs1, len1); + if (mbs2) hawk_copy_bchars_to_bcstr_unlimited (&val->val.ptr[len1], mbs2, len2); + val->val.ptr[val->val.len] = '\0'; +#if defined(DEBUG_VAL) + hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, HAWK_T("make_mbs_val => %p - [%O]\n"), val, val); +#endif return (hawk_val_t*)val; } +hawk_val_t* hawk_rtx_makembsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* ptr, hawk_oow_t len) +{ + return make_mbs_val(rtx, ptr, len, HAWK_NULL, 0); +} hawk_val_t* hawk_rtx_makembsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* ucs, hawk_oow_t len) { @@ -880,16 +887,15 @@ hawk_val_t* hawk_rtx_makembsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* uc bcs = hawk_rtx_duputobchars(rtx, ucs, len, &bcslen); if (HAWK_UNLIKELY(!bcs)) return HAWK_NULL; - val = hawk_rtx_makembsvalwithbchars(rtx, bcs, bcslen); + val = make_mbs_val(rtx, bcs, bcslen, HAWK_NULL, 0); hawk_rtx_freemem (rtx, bcs); return val; - } hawk_val_t* hawk_rtx_makembsvalwithbcs (hawk_rtx_t* rtx, const hawk_bcs_t* bcs) { - return hawk_rtx_makembsvalwithbchars(rtx, bcs->ptr, bcs->len); + return make_mbs_val(rtx, bcs->ptr, bcs->len, HAWK_NULL, 0); } hawk_val_t* hawk_rtx_makembsvalwithucs (hawk_rtx_t* rtx, const hawk_ucs_t* ucs) @@ -899,6 +905,44 @@ hawk_val_t* hawk_rtx_makembsvalwithucs (hawk_rtx_t* rtx, const hawk_ucs_t* ucs) /* --------------------------------------------------------------------- */ +hawk_val_t* hawk_rtx_makembsvalwithuchars2 (hawk_rtx_t* rtx, const hawk_uch_t* ucs1, hawk_oow_t len1, const hawk_uch_t* ucs2, hawk_oow_t len2) +{ +#if defined(HAWK_OOCH_IS_UCH) + hawk_val_t* v; + hawk_bch_t* bcs; + hawk_oow_t bcslen; + + bcs = hawk_rtx_dupu2tobchars(rtx, ucs1, len1, ucs2, len2, &bcslen); + if (HAWK_UNLIKELY(!bcs)) return HAWK_NULL; + + v = make_mbs_val(rtx, bcs, bcslen, HAWK_NULL, 0); + hawk_rtx_freemem (rtx, bcs); + return v; +#else + return make_mbs_val(rtx, ucs1, len1, ucs2, len2); +#endif +} + +hawk_val_t* hawk_rtx_makembsvalwithbchars2 (hawk_rtx_t* rtx, const hawk_bch_t* bcs1, hawk_oow_t len1, const hawk_bch_t* bcs2, hawk_oow_t len2) +{ +#if defined(HAWK_OOCH_IS_UCH) + return make_mbs_val(rtx, bcs1, len1, bcs2, len2); +#else + hawk_val_t* v; + hawk_uch_t* ucs; + hawk_oow_t ucslen; + + ucs = hawk_rtx_dupb2tobchars(rtx, bcs1, len1, bcs2, len2, &ucslen, 1); + if (HAWK_UNLIKELY(!ucs)) return HAWK_NULL; + + v = make_mbs_val(rtx, ucs, ucslen, HAWK_NULL, 0); + hawk_rtx_freemem (rtx, ucs); + return v; +#endif +} + +/* --------------------------------------------------------------------- */ + hawk_val_t* hawk_rtx_makenumormbsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* ptr, hawk_oow_t len) { int x; @@ -944,7 +988,7 @@ hawk_val_t* hawk_rtx_makerexval (hawk_rtx_t* rtx, const hawk_oocs_t* str, hawk_t val->v_type = HAWK_VAL_REX; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; val->str.len = str->len; @@ -1022,7 +1066,7 @@ retry: val->v_type = HAWK_VAL_ARR; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; val->arr = (hawk_arr_t*)(val + 1); @@ -1130,7 +1174,7 @@ retry: val->v_type = HAWK_VAL_MAP; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; val->map = (hawk_map_t*)(val + 1); @@ -1350,7 +1394,7 @@ hawk_val_t* hawk_rtx_makefunval (hawk_rtx_t* rtx, const hawk_fun_t* fun) val->v_type = HAWK_VAL_FUN; val->v_refs = 0; val->v_static = 0; - val->nstr = 0; + val->v_nstr = 0; val->v_gc = 0; val->fun = (hawk_fun_t*)fun; @@ -1449,7 +1493,7 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int flags) rtx->str_cache_count[i] < HAWK_COUNTOF(rtx->str_cache[i])) { rtx->str_cache[i][rtx->str_cache_count[i]++] = v; - v->nstr = 0; + v->v_nstr = 0; } else hawk_rtx_freemem (rtx, val); break; @@ -2385,6 +2429,18 @@ hawk_bch_t* hawk_rtx_getvalbcstrwithcmgr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_o /* fall through */ #endif + +#if 0 + case HAWK_VAL_CHAR: + i can treat a character value between 0 and 255 as a byte. + but doing so can cause inconsitency between the two ranges: + * 128 - 255 (kept as a single byte) + * 255 - max character value (encoded to multiple bytes) + + it looks more consistent that 255 becomes \xc3\xbf (assuming utf8). + so no special handling for HAWK_VAL_CHAR here. +#endif + default: return hawk_rtx_valtobcstrdupwithcmgr(rtx, v, len, cmgr); } diff --git a/hawk/t/h-001.hawk b/hawk/t/h-001.hawk index 784fa41c..ebca40f7 100644 --- a/hawk/t/h-001.hawk +++ b/hawk/t/h-001.hawk @@ -141,5 +141,44 @@ function main() ensure (((10,30,30) in c), 0, @SCRIPTNAME, @SCRIPTLINE); } + + { + # concatenation operator + ensure ((@b"hawk" 10) === @b"hawk10", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" 10) === "hawk10", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" "hawk") === @b"hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" @b"hawk") === "hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" '1') === @b"hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" '1') === "hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure (('*' @b"hawk" '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (('*' "hawk" '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" '⚾') === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" '⚾') === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" str::fromcharcode(0x26be)) === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" str::fromcharcode(0x26be)) === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" %% 10) === @b"hawk10", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" %% 10) === "hawk10", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" %% "hawk") === @b"hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" %% @b"hawk") === "hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" %% '1') === @b"hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" %% '1') === "hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure (('*' %% @b"hawk" %% '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (('*' %% "hawk" %% '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" %% '⚾') === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" %% '⚾') === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE); + + ensure ((@b"hawk" %% str::fromcharcode(0x26be)) === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE); + ensure (("hawk" %% str::fromcharcode(0x26be)) === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE); + } print "SUCCESS" }