implementing assignment with true multi-dimensional map
This commit is contained in:
parent
76d295365a
commit
164d91661b
167
hawk/lib/run.c
167
hawk/lib/run.c
@ -2976,6 +2976,8 @@ static int run_delete_unnamed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
|||||||
|
|
||||||
vtype = HAWK_RTX_GETVALTYPE(rtx, val);
|
vtype = HAWK_RTX_GETVALTYPE(rtx, val);
|
||||||
if (vtype == HAWK_VAL_NIL)
|
if (vtype == HAWK_VAL_NIL)
|
||||||
|
{
|
||||||
|
if (!(rtx->hawk->opt.trait & HAWK_FLEXMAP))
|
||||||
{
|
{
|
||||||
hawk_val_t* tmp;
|
hawk_val_t* tmp;
|
||||||
|
|
||||||
@ -2983,11 +2985,7 @@ static int run_delete_unnamed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
|||||||
* create a map and assign it to the variable */
|
* create a map and assign it to the variable */
|
||||||
|
|
||||||
tmp = hawk_rtx_makemapval(rtx);
|
tmp = hawk_rtx_makemapval(rtx);
|
||||||
if (HAWK_UNLIKELY(!tmp))
|
if (HAWK_UNLIKELY(!tmp)) goto oops;
|
||||||
{
|
|
||||||
ADJERR_LOC (rtx, &var->loc);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no need to reduce the reference count of
|
/* no need to reduce the reference count of
|
||||||
* the previous value because it was nil. */
|
* the previous value because it was nil. */
|
||||||
@ -3002,11 +3000,7 @@ static int run_delete_unnamed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
|||||||
x = hawk_rtx_setgbl(rtx, (int)var->id.idxa, tmp);
|
x = hawk_rtx_setgbl(rtx, (int)var->id.idxa, tmp);
|
||||||
hawk_rtx_refdownval (rtx, tmp);
|
hawk_rtx_refdownval (rtx, tmp);
|
||||||
|
|
||||||
if (HAWK_UNLIKELY(x <= -1))
|
if (HAWK_UNLIKELY(x <= -1)) goto oops;
|
||||||
{
|
|
||||||
ADJERR_LOC (rtx, &var->loc);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3022,6 +3016,7 @@ static int run_delete_unnamed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hawk_map_t* map;
|
hawk_map_t* map;
|
||||||
@ -3029,7 +3024,7 @@ static int run_delete_unnamed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
|||||||
if (vtype != HAWK_VAL_MAP)
|
if (vtype != HAWK_VAL_MAP)
|
||||||
{
|
{
|
||||||
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENOTDEL, HAWK_T("'%.*js' not deletable"), var->id.name.len, var->id.name.ptr);
|
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENOTDEL, HAWK_T("'%.*js' not deletable"), var->id.name.len, var->id.name.ptr);
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
map = ((hawk_val_map_t*)val)->map;
|
map = ((hawk_val_map_t*)val)->map;
|
||||||
@ -3037,15 +3032,28 @@ static int run_delete_unnamed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
|||||||
var->type == HAWK_NDE_LCLIDX ||
|
var->type == HAWK_NDE_LCLIDX ||
|
||||||
var->type == HAWK_NDE_ARGIDX)
|
var->type == HAWK_NDE_ARGIDX)
|
||||||
{
|
{
|
||||||
if (delete_indexed(rtx, map, var) <= -1) return -1;
|
if (delete_indexed(rtx, map, var) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
BEGIN {
|
||||||
|
@local a;
|
||||||
|
a[1] = 20; a[2] = "hello"; a[3][4][5]="ttt";
|
||||||
|
print typename(a), length(a);
|
||||||
|
delete a;
|
||||||
|
print typename(a), length(a);
|
||||||
|
}
|
||||||
|
*/
|
||||||
hawk_map_clear (map);
|
hawk_map_clear (map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
ADJERR_LOC (rtx, &var->loc);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde)
|
static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde)
|
||||||
@ -3904,9 +3912,10 @@ static hawk_val_t* do_assignment_nonidx (hawk_rtx_t* rtx, hawk_nde_var_t* var, h
|
|||||||
|
|
||||||
static hawk_val_t* do_assignment_idx (hawk_rtx_t* rtx, hawk_nde_var_t* var, hawk_val_t* val)
|
static hawk_val_t* do_assignment_idx (hawk_rtx_t* rtx, hawk_nde_var_t* var, hawk_val_t* val)
|
||||||
{
|
{
|
||||||
hawk_val_map_t* map;
|
hawk_map_t* map;
|
||||||
hawk_val_type_t mvtype;
|
hawk_val_t* vv; /* existing value pointed to by var */
|
||||||
hawk_ooch_t* str;
|
hawk_val_type_t vtype;
|
||||||
|
hawk_ooch_t* str = HAWK_NULL;
|
||||||
hawk_oow_t len;
|
hawk_oow_t len;
|
||||||
hawk_ooch_t idxbuf[IDXBUFSIZE];
|
hawk_ooch_t idxbuf[IDXBUFSIZE];
|
||||||
hawk_nde_t* remidx;
|
hawk_nde_t* remidx;
|
||||||
@ -3927,35 +3936,34 @@ retry:
|
|||||||
{
|
{
|
||||||
hawk_htb_pair_t* pair;
|
hawk_htb_pair_t* pair;
|
||||||
pair = hawk_htb_search(rtx->named, var->id.name.ptr, var->id.name.len);
|
pair = hawk_htb_search(rtx->named, var->id.name.ptr, var->id.name.len);
|
||||||
map = (pair == HAWK_NULL)? (hawk_val_map_t*)hawk_val_nil: (hawk_val_map_t*)HAWK_HTB_VPTR(pair);
|
vv = (pair == HAWK_NULL)? hawk_val_nil: HAWK_HTB_VPTR(pair);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case HAWK_NDE_GBLIDX:
|
case HAWK_NDE_GBLIDX:
|
||||||
map = (hawk_val_map_t*)HAWK_RTX_STACK_GBL(rtx,var->id.idxa);
|
vv = HAWK_RTX_STACK_GBL(rtx,var->id.idxa);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAWK_NDE_LCLIDX:
|
case HAWK_NDE_LCLIDX:
|
||||||
map = (hawk_val_map_t*)HAWK_RTX_STACK_LCL(rtx,var->id.idxa);
|
vv = HAWK_RTX_STACK_LCL(rtx,var->id.idxa);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* HAWK_NDE_ARGIDX */
|
default: /* HAWK_NDE_ARGIDX */
|
||||||
map = (hawk_val_map_t*)HAWK_RTX_STACK_ARG(rtx,var->id.idxa);
|
vv = HAWK_RTX_STACK_ARG(rtx,var->id.idxa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mvtype = HAWK_RTX_GETVALTYPE(rtx, map);
|
/* check the value that the assigned variable points to */
|
||||||
if (mvtype == HAWK_VAL_NIL)
|
vtype = HAWK_RTX_GETVALTYPE(rtx, vv);
|
||||||
|
switch (vtype)
|
||||||
|
{
|
||||||
|
case HAWK_VAL_NIL:
|
||||||
{
|
{
|
||||||
hawk_val_t* tmp;
|
hawk_val_t* tmp;
|
||||||
|
|
||||||
/* the map is not initialized yet */
|
/* the map is not initialized yet */
|
||||||
tmp = hawk_rtx_makemapval(rtx);
|
tmp = hawk_rtx_makemapval(rtx);
|
||||||
if (HAWK_UNLIKELY(!tmp))
|
if (HAWK_UNLIKELY(!tmp)) goto oops;
|
||||||
{
|
|
||||||
ADJERR_LOC (rtx, &var->loc);
|
|
||||||
return HAWK_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (var->type)
|
switch (var->type)
|
||||||
{
|
{
|
||||||
@ -3965,11 +3973,10 @@ retry:
|
|||||||
* of the previous value here as it is done by
|
* of the previous value here as it is done by
|
||||||
* hawk_htb_upsert */
|
* hawk_htb_upsert */
|
||||||
hawk_rtx_refupval (rtx, tmp);
|
hawk_rtx_refupval (rtx, tmp);
|
||||||
if (hawk_htb_upsert(rtx->named, var->id.name.ptr, var->id.name.len, tmp, 0) == HAWK_NULL)
|
if (HAWK_UNLIKELY(hawk_htb_upsert(rtx->named, var->id.name.ptr, var->id.name.len, tmp, 0) == HAWK_NULL))
|
||||||
{
|
{
|
||||||
hawk_rtx_refdownval (rtx, tmp);
|
hawk_rtx_refdownval (rtx, tmp);
|
||||||
ADJERR_LOC (rtx, &var->loc);
|
goto oops;
|
||||||
return HAWK_NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -3982,31 +3989,34 @@ retry:
|
|||||||
hawk_rtx_refupval (rtx, tmp);
|
hawk_rtx_refupval (rtx, tmp);
|
||||||
x = hawk_rtx_setgbl(rtx, (int)var->id.idxa, tmp);
|
x = hawk_rtx_setgbl(rtx, (int)var->id.idxa, tmp);
|
||||||
hawk_rtx_refdownval (rtx, tmp);
|
hawk_rtx_refdownval (rtx, tmp);
|
||||||
if (HAWK_UNLIKELY(x <= -1))
|
if (HAWK_UNLIKELY(x <= -1)) goto oops;
|
||||||
{
|
|
||||||
ADJERR_LOC (rtx, &var->loc);
|
|
||||||
return HAWK_NULL;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case HAWK_NDE_LCLIDX:
|
case HAWK_NDE_LCLIDX:
|
||||||
hawk_rtx_refdownval (rtx, (hawk_val_t*)map);
|
hawk_rtx_refdownval (rtx, vv);
|
||||||
HAWK_RTX_STACK_LCL(rtx,var->id.idxa) = tmp;
|
HAWK_RTX_STACK_LCL(rtx,var->id.idxa) = tmp;
|
||||||
hawk_rtx_refupval (rtx, tmp);
|
hawk_rtx_refupval (rtx, tmp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* HAWK_NDE_ARGIDX */
|
default: /* HAWK_NDE_ARGIDX */
|
||||||
hawk_rtx_refdownval (rtx, (hawk_val_t*)map);
|
hawk_rtx_refdownval (rtx, vv);
|
||||||
HAWK_RTX_STACK_ARG(rtx,var->id.idxa) = tmp;
|
HAWK_RTX_STACK_ARG(rtx,var->id.idxa) = tmp;
|
||||||
hawk_rtx_refupval (rtx, tmp);
|
hawk_rtx_refupval (rtx, tmp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
map = (hawk_val_map_t*)tmp;
|
vv = tmp;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (mvtype != HAWK_VAL_MAP)
|
|
||||||
{
|
|
||||||
|
case HAWK_VAL_MAP:
|
||||||
|
/* nothing to do */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
if (rtx->hawk->opt.trait & HAWK_FLEXMAP)
|
if (rtx->hawk->opt.trait & HAWK_FLEXMAP)
|
||||||
{
|
{
|
||||||
/* if FLEXMAP is on, you can switch a scalar value to a map */
|
/* if FLEXMAP is on, you can switch a scalar value to a map */
|
||||||
@ -4028,29 +4038,87 @@ retry:
|
|||||||
/* you can't manipulate a variable pointing to
|
/* you can't manipulate a variable pointing to
|
||||||
* a scalar value with an index if FLEXMAP is off. */
|
* a scalar value with an index if FLEXMAP is off. */
|
||||||
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ESCALARTOMAP, HAWK_T("not allowed to change a scalar '%.*js' to a map"), var->id.name.len, var->id.name.ptr);
|
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ESCALARTOMAP, HAWK_T("not allowed to change a scalar '%.*js' to a map"), var->id.name.len, var->id.name.ptr);
|
||||||
return HAWK_NULL;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = HAWK_COUNTOF(idxbuf);
|
len = HAWK_COUNTOF(idxbuf);
|
||||||
str = idxnde_to_str(rtx, var->idx, idxbuf, &len, &remidx);
|
str = idxnde_to_str(rtx, var->idx, idxbuf, &len, &remidx);
|
||||||
if (HAWK_UNLIKELY(!str)) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!str)) goto oops;
|
||||||
|
|
||||||
|
map = ((hawk_val_map_t*)vv)->map;
|
||||||
|
|
||||||
#if defined(DEBUG_RUN)
|
#if defined(HAWK_ENABLE_GC)
|
||||||
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_T("**** index str=>%s, map->ref=%d, map->type=%d\n"), str, (int)map->ref, (int)map->type);
|
while (remidx)
|
||||||
|
{
|
||||||
|
hawk_map_pair_t* pair;
|
||||||
|
|
||||||
|
pair = hawk_map_search(map, str, len);
|
||||||
|
|
||||||
|
vv = pair? (hawk_val_t*)HAWK_HTB_VPTR(pair): hawk_val_nil;
|
||||||
|
vtype = HAWK_RTX_GETVALTYPE(rtx, vv);
|
||||||
|
|
||||||
|
switch (vtype)
|
||||||
|
{
|
||||||
|
case HAWK_VAL_NIL:
|
||||||
|
remidx_nil_to_map:
|
||||||
|
vv = hawk_rtx_makemapval(rtx);
|
||||||
|
if (HAWK_UNLIKELY(!vv)) goto oops;
|
||||||
|
|
||||||
|
hawk_rtx_refupval (rtx, vv);
|
||||||
|
pair = hawk_map_upsert(map, str, len, vv, 0);
|
||||||
|
if (HAWK_UNLIKELY(!pair))
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval (rtx, vv);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
map = ((hawk_val_map_t*)vv)->map;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_VAL_MAP:
|
||||||
|
map = ((hawk_val_map_t*)vv)->map;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (rtx->hawk->opt.trait & HAWK_FLEXMAP)
|
||||||
|
{
|
||||||
|
/* BEGIN { @local a, b; b="hello"; a[1]=b; a[1][2]=20; print a[1][2];} */
|
||||||
|
/* BEGIN { a[1]="hello"; a[1][2]=20; print a[1][2]; } */
|
||||||
|
/* BEGIN { b="hello"; a[1]=b; a[1][2]=20; print a[1][2]; } */
|
||||||
|
goto remidx_nil_to_map;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ESCALARTOMAP, HAWK_T("not allowed to change a nested scalar under '%.*js' to a map"), var->id.name.len, var->id.name.ptr);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str != idxbuf) hawk_rtx_freemem (rtx, str);
|
||||||
|
len = HAWK_COUNTOF(idxbuf);
|
||||||
|
str = idxnde_to_str(rtx, remidx, idxbuf, &len, &remidx);
|
||||||
|
if (HAWK_UNLIKELY(!str)) goto oops;
|
||||||
|
|
||||||
|
pair = hawk_map_search(map, str, len);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (hawk_map_upsert(map->map, str, len, val, 0) == HAWK_NULL)
|
#if defined(DEBUG_RUN)
|
||||||
{
|
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_T("**** index str=>%s, map->ref=%d, map->type=%d\n"), str, (int)v->ref, (int)v->type);
|
||||||
if (str != idxbuf) hawk_rtx_freemem (rtx, str);
|
#endif
|
||||||
ADJERR_LOC (rtx, &var->loc);
|
|
||||||
return HAWK_NULL;
|
if (HAWK_UNLIKELY(hawk_map_upsert(map, str, len, val, 0) == HAWK_NULL)) goto oops;
|
||||||
}
|
|
||||||
|
|
||||||
if (str != idxbuf) hawk_rtx_freemem (rtx, str);
|
if (str != idxbuf) hawk_rtx_freemem (rtx, str);
|
||||||
hawk_rtx_refupval (rtx, val);
|
hawk_rtx_refupval (rtx, val);
|
||||||
return val;
|
return val;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (str && str != idxbuf) hawk_rtx_freemem (rtx, str);
|
||||||
|
ADJERR_LOC (rtx, &var->loc);
|
||||||
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hawk_val_t* do_assignment_pos (hawk_rtx_t* rtx, hawk_nde_pos_t* pos, hawk_val_t* val)
|
static hawk_val_t* do_assignment_pos (hawk_rtx_t* rtx, hawk_nde_pos_t* pos, hawk_val_t* val)
|
||||||
@ -7360,6 +7428,7 @@ static hawk_ooch_t* idxnde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_ooch_t
|
|||||||
{
|
{
|
||||||
hawk_rtx_refdownval (rtx, idx);
|
hawk_rtx_refdownval (rtx, idx);
|
||||||
hawk_ooecs_fini (&idxstr);
|
hawk_ooecs_fini (&idxstr);
|
||||||
|
ADJERR_LOC (rtx, &nde->loc);
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user