enhanced the concat operator handler to process mbs properly

This commit is contained in:
hyung-hwan 2020-12-09 04:02:04 +00:00
parent 1d83f8cfe7
commit 2e25911bfd
7 changed files with 227 additions and 78 deletions

View File

@ -594,7 +594,7 @@ static HAWK_INLINE void HAWK_RTX_STACK_POP (hawk_rtx_t* rtx)
(refval)->v_type = HAWK_VAL_REF; \ (refval)->v_type = HAWK_VAL_REF; \
(refval)->v_refs = (_nrefs); \ (refval)->v_refs = (_nrefs); \
(refval)->v_static = 0; \ (refval)->v_static = 0; \
(refval)->nstr = 0; \ (refval)->v_nstr = 0; \
(refval)->v_gc = 0; \ (refval)->v_gc = 0; \
(refval)->id = (_id); \ (refval)->id = (_id); \
(refval)->adr = (_adr); \ (refval)->adr = (_adr); \

View File

@ -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_type - type of a value from #hawk_val_type_t
* - v_refs - reference count * - v_refs - reference count
* - v_static - static value indicator * - 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 \ #define HAWK_VAL_HDR \
unsigned int v_type: 4; \ unsigned int v_type: 4; \
unsigned int v_refs: 24; \ unsigned int v_refs: 24; \
unsigned int v_static: 1; \ unsigned int v_static: 1; \
unsigned int nstr: 2; \ unsigned int v_nstr: 2; \
unsigned int v_gc: 1 unsigned int v_gc: 1
*/ */
#define HAWK_VAL_HDR \ #define HAWK_VAL_HDR \
hawk_uintptr_t v_type: 4; \ hawk_uintptr_t v_type: 4; \
hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \ hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \
hawk_uintptr_t v_static: 1; \ hawk_uintptr_t v_static: 1; \
hawk_uintptr_t nstr: 2; \ hawk_uintptr_t v_nstr: 2; \
hawk_uintptr_t v_gc: 1 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. * The hawk_rtx_makembsvalwithbchars() function create a byte array value.
* \return value on success, #HAWK_NULL on failure * \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, hawk_rtx_t* rtx,
const hawk_bch_t* ptr, const hawk_bch_t* ptr,
hawk_oow_t len hawk_oow_t len
); );
hawk_val_t* hawk_rtx_makembsvalwithuchars ( HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithuchars (
hawk_rtx_t* rtx, hawk_rtx_t* rtx,
const hawk_uch_t* ptr, const hawk_uch_t* ptr,
hawk_oow_t len hawk_oow_t len
); );
hawk_val_t* hawk_rtx_makembsvalwithbcs ( HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithbcs (
hawk_rtx_t* rtx, hawk_rtx_t* rtx,
const hawk_bcs_t* bcs const hawk_bcs_t* bcs
); );
hawk_val_t* hawk_rtx_makembsvalwithucs ( HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithucs (
hawk_rtx_t* rtx, hawk_rtx_t* rtx,
const hawk_ucs_t* ucs 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 ( HAWK_EXPORT hawk_val_t* hawk_rtx_makenumormbsvalwithuchars (

View File

@ -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) 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_val_t* retv;
hawk_oow_t nargs, i; 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); nargs = hawk_rtx_getnargs(rtx);
retv = hawk_rtx_makestrvalwithoochars(rtx, HAWK_NULL, nargs); if (nargs == 1)
if (!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_val_t* a0;
hawk_int_t cc; hawk_int_t cc;
a0 = hawk_rtx_getarg(rtx, i); a0 = hawk_rtx_getarg(rtx, 0);
if (hawk_rtx_valtoint(rtx, a0, &cc) <= -1) if (hawk_rtx_valtoint(rtx, a0, &cc) <= -1) return -1;
{
hawk_rtx_freeval (rtx, retv, 0);
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); hawk_rtx_setretval (rtx, retv);
@ -466,7 +483,7 @@ done:
static int fnc_tonum (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) static int fnc_tonum (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{ {
/* str::tonum(value) */ /* str::tonum(value) */
/* str::tonum(string, base) */ /* str::tonum(string/character, base) */
/*hawk_t* hawk = hawk_rtx_gethawk(rtx);*/ /*hawk_t* hawk = hawk_rtx_gethawk(rtx);*/
hawk_val_t* retv; hawk_val_t* retv;

View File

@ -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; hawk_oow_t len0;
int n; int n;
/* SCO CC doesn't seem to handle right->nstr > 0 properly */ /* SCO CC doesn't seem to handle right->v_nstr > 0 properly */
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_int_t ll, v1;
hawk_flt_t rr; 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; hawk_oow_t len0;
int n; 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_int_t ll, v1;
hawk_flt_t rr; 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; hawk_oow_t len0;
int n; int n;
/* SCO CC doesn't seem to handle right->nstr > 0 properly */ /* SCO CC doesn't seem to handle right->v_nstr > 0 properly */
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/) if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/)
{ {
const hawk_ooch_t* end; const hawk_ooch_t* end;
hawk_flt_t rr; 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; hawk_oow_t len0;
int n; 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; const hawk_bch_t* end;
hawk_flt_t rr; 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; ls = (hawk_val_str_t*)left;
rs = (hawk_val_str_t*)right; 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 */ /* both are definitely strings */
return hawk_comp_oochars(ls->val.ptr, ls->val.len, rs->val.ptr, rs->val.len, rtx->gbl.ignorecase); 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); stripspc = HAWK_RTX_IS_STRIPSTRSPC_ON(rtx);
if (ls->nstr == 1) if (ls->v_nstr == 1)
{ {
hawk_int_t ll; 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); 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; 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_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); 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_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); 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; 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_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); 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) static hawk_val_t* eval_binop_concat (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right)
{ {
hawk_val_t* res; hawk_val_t* res;
hawk_rtx_valtostr_out_t lout, rout;
lout.type = HAWK_RTX_VALTOSTR_CPLDUP; if (HAWK_RTX_GETVALTYPE(rtx, left) == HAWK_VAL_MBS)
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)
{ {
hawk_rtx_freemem (rtx, lout.u.cpldup.ptr); hawk_bcs_t l, r;
return HAWK_NULL;
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( hawk_oocs_t l, r;
rtx,
lout.u.cpldup.ptr, lout.u.cpldup.len,
rout.u.cpldup.ptr, rout.u.cpldup.len
);
hawk_rtx_freemem (rtx, rout.u.cpldup.ptr); l.ptr = hawk_rtx_getvaloocstr(rtx, left, &l.len);
hawk_rtx_freemem (rtx, lout.u.cpldup.ptr); 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; return res;
} }

View File

@ -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); HAWK_ASSERT (l >= 2);
f += 2; /* skip ${ */ f += 2; /* skip ${ */
if (ident) ident->ptr = f; if (ident) ident->ptr = (hawk_uch_t*)f;
while (1) 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 := */ f += 2; /* skip := */
if (dfl) dfl->ptr = f; if (dfl) dfl->ptr = (hawk_uch_t*)f;
while (1) while (1)
{ {
if (f >= end) return HAWK_NULL; 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); HAWK_ASSERT (l >= 2);
f += 2; /* skip ${ */ f += 2; /* skip ${ */
if (ident) ident->ptr = f; if (ident) ident->ptr = (hawk_bch_t*)f;
while (1) 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 := */ f += 2; /* skip := */
if (dfl) dfl->ptr = f; if (dfl) dfl->ptr = (hawk_bch_t*)f;
while (1) while (1)
{ {
if (f >= end) return HAWK_NULL; if (f >= end) return HAWK_NULL;

View File

@ -224,7 +224,7 @@ static void gc_dump_refs (hawk_rtx_t* rtx, hawk_gch_t* list)
gch = list->gc_next; gch = list->gc_next;
while (gch != list) 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; gch = gch->gc_next;
} }
hawk_logbfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, "[GC] dumped %ju values\n", count); 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_type = HAWK_VAL_INT;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->i_val = v; val->i_val = v;
val->nde = HAWK_NULL; 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_type = HAWK_VAL_FLT;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->val = v; val->val = v;
val->nde = HAWK_NULL; val->nde = HAWK_NULL;
@ -615,7 +615,7 @@ init:
val->v_type = HAWK_VAL_STR; val->v_type = HAWK_VAL_STR;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->val.len = len1 + len2; val->val.len = len1 + len2;
val->val.ptr = (hawk_ooch_t*)(val + 1); 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 /* set the numeric string flag if a string
* can be converted to a number */ * can be converted to a number */
HAWK_ASSERT (x == 0 || x == 1); 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; 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 /* set the numeric string flag if a string
* can be converted to a number */ * can be converted to a number */
HAWK_ASSERT (x == 0 || x == 1); 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; return v;
@ -825,17 +825,16 @@ hawk_val_t* hawk_rtx_makenstrvalwithbcs (hawk_rtx_t* rtx, const hawk_bcs_t* str)
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
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_t* hawk_rtx_makembsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* ptr, hawk_oow_t len)
{ {
hawk_val_mbs_t* val; hawk_val_mbs_t* val = HAWK_NULL;
hawk_oow_t aligned_len; hawk_oow_t aligned_len;
#if defined(HAWK_ENABLE_MBS_CACHE) #if defined(HAWK_ENABLE_MBS_CACHE)
hawk_oow_t i; hawk_oow_t i;
#endif #endif
if (HAWK_UNLIKELY(len <= 0)) return hawk_val_zlm; if (HAWK_UNLIKELY(len1 <= 0 && len2 <= 0)) return hawk_val_zls;
aligned_len = HAWK_ALIGN_POW2((len + 1), HAWK_MBS_CACHE_BLOCK_UNIT); aligned_len = HAWK_ALIGN_POW2((len1 + len2 + 1), HAWK_MBS_CACHE_BLOCK_UNIT);
#if defined(HAWK_ENABLE_MBS_CACHE) #if defined(HAWK_ENABLE_MBS_CACHE)
i = aligned_len / HAWK_MBS_CACHE_BLOCK_UNIT; i = aligned_len / HAWK_MBS_CACHE_BLOCK_UNIT;
@ -858,16 +857,24 @@ init:
val->v_type = HAWK_VAL_MBS; val->v_type = HAWK_VAL_MBS;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->val.len = len; val->val.len = len1 + len2;
val->val.ptr = (hawk_bch_t*)(val + 1); val->val.ptr = (hawk_bch_t*)(val + 1);
if (ptr) HAWK_MEMCPY (val->val.ptr, ptr, len); if (HAWK_LIKELY(mbs1)) hawk_copy_bchars_to_bcstr_unlimited (&val->val.ptr[0], mbs1, len1);
val->val.ptr[len] = '\0'; 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; 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) 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); bcs = hawk_rtx_duputobchars(rtx, ucs, len, &bcslen);
if (HAWK_UNLIKELY(!bcs)) return HAWK_NULL; 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); hawk_rtx_freemem (rtx, bcs);
return val; return val;
} }
hawk_val_t* hawk_rtx_makembsvalwithbcs (hawk_rtx_t* rtx, const hawk_bcs_t* bcs) 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) 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) hawk_val_t* hawk_rtx_makenumormbsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* ptr, hawk_oow_t len)
{ {
int x; 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_type = HAWK_VAL_REX;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->str.len = str->len; val->str.len = str->len;
@ -1022,7 +1066,7 @@ retry:
val->v_type = HAWK_VAL_ARR; val->v_type = HAWK_VAL_ARR;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->arr = (hawk_arr_t*)(val + 1); val->arr = (hawk_arr_t*)(val + 1);
@ -1130,7 +1174,7 @@ retry:
val->v_type = HAWK_VAL_MAP; val->v_type = HAWK_VAL_MAP;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->map = (hawk_map_t*)(val + 1); 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_type = HAWK_VAL_FUN;
val->v_refs = 0; val->v_refs = 0;
val->v_static = 0; val->v_static = 0;
val->nstr = 0; val->v_nstr = 0;
val->v_gc = 0; val->v_gc = 0;
val->fun = (hawk_fun_t*)fun; 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_count[i] < HAWK_COUNTOF(rtx->str_cache[i]))
{ {
rtx->str_cache[i][rtx->str_cache_count[i]++] = v; rtx->str_cache[i][rtx->str_cache_count[i]++] = v;
v->nstr = 0; v->v_nstr = 0;
} }
else hawk_rtx_freemem (rtx, val); else hawk_rtx_freemem (rtx, val);
break; break;
@ -2385,6 +2429,18 @@ hawk_bch_t* hawk_rtx_getvalbcstrwithcmgr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_o
/* fall through */ /* fall through */
#endif #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: default:
return hawk_rtx_valtobcstrdupwithcmgr(rtx, v, len, cmgr); return hawk_rtx_valtobcstrdupwithcmgr(rtx, v, len, cmgr);
} }

View File

@ -141,5 +141,44 @@ function main()
ensure (((10,30,30) in c), 0, @SCRIPTNAME, @SCRIPTLINE); 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" print "SUCCESS"
} }