more code for array support

This commit is contained in:
hyung-hwan 2020-04-24 17:27:56 +00:00
parent 1b7ef41ee4
commit 70f759b140
7 changed files with 228 additions and 168 deletions

View File

@ -142,20 +142,17 @@ const hawk_ooch_t* hawk_dfl_errstr (hawk_errnum_t errnum)
HAWK_T("right-hand side of the 'in' operator not a map"),
HAWK_T("right-hand side of the 'in' operator not a map nor nil"),
HAWK_T("value not referenceable"),
HAWK_T("cannot return a map"), /* EMAPRET */
HAWK_T("cannot assign a map to a positional"), /* EMAPTOPOS */
HAWK_T("cannot assign a map to an indexed variable"),/* EMAPTOIDX */
HAWK_T("cannot assign a map to a variable"), /* EMAPTOVAR */
HAWK_T("cannot change a map to a scalar"), /* EMAPTOSCALAR */
HAWK_T("cannot change a map to another map"), /* EMAPTOMAP */
HAWK_T("cannot change a scalar to a map"), /* ESCALARTOMAP */
HAWK_T("cannot return a non-scalar value"), /* ENONSCARET */
HAWK_T("cannot assign a non-scalar value to a positional"), /* ENONSCATOPOS */
HAWK_T("cannot assign a non-scalar value to an indexed variable"),/* ENONSCATOIDX */
HAWK_T("cannot assign a non-scalar value to a variable"), /* ENONSCATOVAR */
HAWK_T("cannot change a non-scalar value to a scalar value"), /* ENONSCATOSCALAR */
HAWK_T("cannot change a non-scalar value to another non-scalar value"), /* ENONSCATONONSCA */
HAWK_T("cannot change a scalar value to a non-scalar value"), /* ESCALARTONONSCA */
HAWK_T("invalid value to convert to a string"),
HAWK_T("invalid value to convert to a number"),
HAWK_T("invalid value to a character"),
HAWK_T("invalid value for hashing"),
HAWK_T("cannot return an array"), /* EARRRET */
HAWK_T("cannot assign an array to a positional"), /* EARRTOPOS */
HAWK_T("cannot assign an array to an indexed variable"),/* EARRTOIDX */
HAWK_T("array index out of allowed range"),
HAWK_T("single-bracketed multidimensional array indices not allowed"),
HAWK_T("'next' called from BEGIN block"),

View File

@ -29,11 +29,6 @@
static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_int (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_gcrefs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_isnil (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_ismap (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_isarr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
static int fnc_asorti (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
@ -59,11 +54,6 @@ static hawk_fnc_t sysfnctab[] =
/* type info/conversion */
{ {HAWK_T("int"), 3}, 0, { {1, 1, HAWK_NULL}, fnc_int, 0 }, HAWK_NULL},
{ {HAWK_T("isarray"), 7}, 0, { {1, 1, HAWK_NULL}, fnc_isarr, 0 }, HAWK_NULL},
{ {HAWK_T("isnil"), 5}, 0, { {1, 1, HAWK_NULL}, fnc_isnil, 0 }, HAWK_NULL},
{ {HAWK_T("ismap"), 5}, 0, { {1, 1, HAWK_NULL}, fnc_ismap, 0 }, HAWK_NULL},
{ {HAWK_T("typename"), 8}, 0, { {1, 1, HAWK_NULL}, fnc_typename, 0 }, HAWK_NULL},
{ {HAWK_T("gcrefs"), 6}, 0, { {1, 1, HAWK_NULL}, fnc_gcrefs, 0 }, HAWK_NULL},
/* map(array) sort */
{ {HAWK_T("asort"), 5}, 0, { {1, 3, HAWK_T("rrv")}, fnc_asort, 0 }, HAWK_NULL},
@ -1733,73 +1723,6 @@ static int fnc_int (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
return 0;
}
static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
const hawk_ooch_t* name;
a0 = hawk_rtx_getarg(rtx, 0);
name = hawk_rtx_getvaltypename(rtx, a0);
r = hawk_rtx_makestrvalwithoocstr(rtx, name);
if (r == HAWK_NULL) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_gcrefs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
a0 = hawk_rtx_getarg(rtx, 0);
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, HAWK_VTR_IS_POINTER(a0)? a0->v_refs: 0));
return 0;
}
static int fnc_isnil (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
a0 = hawk_rtx_getarg(rtx, 0);
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_NIL);
if (r == HAWK_NULL) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_ismap (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
a0 = hawk_rtx_getarg(rtx, 0);
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MAP);
if (HAWK_UNLIKELY(!r)) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_isarr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
a0 = hawk_rtx_getarg(rtx, 0);
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_ARR);
if (HAWK_UNLIKELY(!r)) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
static HAWK_INLINE int asort_compare (const void* x1, const void* x2, void* ctx, int* cv)
{
int n;
@ -1865,6 +1788,7 @@ static HAWK_INLINE int __fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi,
a0_type = HAWK_RTX_GETVALTYPE(rtx, a0);
HAWK_ASSERT (a0_type == HAWK_VAL_REF);
/* TODO: handel HAWK_VAL_ARR */
v_type = hawk_rtx_getrefvaltype(rtx, (hawk_val_ref_t*)a0);
if (v_type != HAWK_VAL_MAP)
{

View File

@ -977,20 +977,19 @@ enum hawk_errnum_t
HAWK_ENOTMAPIN, /**< right-hand side of 'in' not a map */
HAWK_ENOTMAPNILIN, /**< right-hand side of 'in' not a map nor nil */
HAWK_ENOTREF, /**< value not referenceable */
HAWK_EMAPRET, /**< map cannot be returned */
HAWK_EMAPTOPOS, /**< map cannot be assigned to a positional */
HAWK_EMAPTOIDX, /**< map cannot be assigned to an indexed variable */
HAWK_EMAPTOVAR, /**< map cannot be assigned to a variable */
HAWK_EMAPTOSCALAR, /**< cannot change a map to a scalar value */
HAWK_EMAPTOMAP, /**< cannot change a map to another map */
HAWK_ESCALARTOMAP, /**< cannot change a scalar to a map */
HAWK_ENONSCARET, /**< non-scalar value cannot be returned */
HAWK_ENONSCATOPOS, /**< non-scalar value cannot be assigned to a positional */
HAWK_ENONSCATOIDX, /**< non-scalar value cannot be assigned to an indexed variable */
HAWK_ENONSCATOVAR, /**< non-scalar cannot be assigned to a variable */
HAWK_ENONSCATOSCALAR, /**< cannot change a non-scalar value to a scalar value */
HAWK_ENONSCATONONSCA, /**< cannot change a non-scalar value to another non-scalar value */
HAWK_ESCALARTONONSCA, /**< cannot change a scalar value to to a non-scalar value */
HAWK_EVALTOSTR, /**< invalid value to convert to a string */
HAWK_EVALTONUM, /**< invalid value to convert to a number */
HAWK_EVALTOCHR, /**< invalid value to convert to a character */
HAWK_EHASHVAL, /**< invalid value to hash */
HAWK_EARRRET, /**< array cannot be returned */
HAWK_EARRTOPOS, /**< array cannot be assigned to a positional */
HAWK_EARRTOIDX, /**< array cannot be assigned to an indexed variable */
HAWK_EARRIDXRANGE, /**< disallowed array index range */
HAWK_EARRIDXMULTI, /**< single-bracketed multidimensional array indices not allowed */
HAWK_ERNEXTBEG, /**< 'next' called from BEGIN block */

View File

@ -211,6 +211,14 @@ static int fnc_gc_set_threshold (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
return 0;
}
static int fnc_gcrefs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
a0 = hawk_rtx_getarg(rtx, 0);
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, HAWK_VTR_IS_POINTER(a0)? a0->v_refs: 0));
return 0;
}
/* -------------------------------------------------------------------------- */
static int fnc_array (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
@ -239,6 +247,66 @@ static int fnc_map (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
/* -------------------------------------------------------------------------- */
static int fnc_isnil (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
a0 = hawk_rtx_getarg(rtx, 0);
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_NIL);
if (r == HAWK_NULL) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_ismap (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
a0 = hawk_rtx_getarg(rtx, 0);
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MAP);
if (HAWK_UNLIKELY(!r)) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_isarr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
a0 = hawk_rtx_getarg(rtx, 0);
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_ARR);
if (HAWK_UNLIKELY(!r)) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_val_t* r;
const hawk_ooch_t* name;
a0 = hawk_rtx_getarg(rtx, 0);
name = hawk_rtx_getvaltypename(rtx, a0);
r = hawk_rtx_makestrvalwithoocstr(rtx, name);
if (r == HAWK_NULL) return -1;
hawk_rtx_setretval (rtx, r);
return 0;
}
/* -------------------------------------------------------------------------- */
typedef struct fnctab_t fnctab_t;
struct fnctab_t
{
@ -262,9 +330,14 @@ static fnctab_t fnctab[] =
{ HAWK_T("call"), { { 1, A_MAX, HAWK_T("vR") }, fnc_call, 0 } },
{ HAWK_T("function_exists"), { { 1, 1, HAWK_NULL }, fnc_function_exists, 0 } },
{ HAWK_T("gc"), { { 0, 1, HAWK_NULL }, fnc_gc, 0 } },
{ HAWK_T("gcrefs"), { { 1, 1, HAWK_NULL }, fnc_gcrefs, 0 } },
{ HAWK_T("gc_get_threshold"), { { 1, 1, HAWK_NULL }, fnc_gc_get_threshold, 0 } },
{ HAWK_T("gc_set_threshold"), { { 2, 2, HAWK_NULL }, fnc_gc_set_threshold, 0 } },
{ HAWK_T("map"), { { 0, A_MAX }, fnc_map, 0 } }
{ HAWK_T("isarray"), { { 1, 1, HAWK_NULL }, fnc_isarr, 0 } },
{ HAWK_T("ismap"), { { 1, 1, HAWK_NULL }, fnc_ismap, 0 } },
{ HAWK_T("isnil"), { { 1, 1, HAWK_NULL }, fnc_isnil, 0 } },
{ HAWK_T("map"), { { 0, A_MAX, HAWK_NULL }, fnc_map, 0 } },
{ HAWK_T("typename"), { { 1, 1, HAWK_NULL }, fnc_typename, 0 } }
};
static inttab_t inttab[] =

View File

@ -168,8 +168,6 @@ static hawk_val_t* eval_incpre (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_incpst (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_cnd (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_fncall_fun_ex (hawk_rtx_t* rtx, hawk_nde_t* nde, void(*errhandler)(void*), void* eharg);
static hawk_val_t* eval_fncall_fnc (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde);
@ -250,14 +248,14 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
hawk_errnum_t errnum = HAWK_ENOERR;
const hawk_ooch_t* errfmt;
if (vtype == HAWK_VAL_MAP)
if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
if (old_vtype == HAWK_VAL_NIL)
{
/* a nil valul can be overridden with any values */
/* ok. no error */
}
else if (!assign && old_vtype == HAWK_VAL_MAP)
else if (!assign && old_vtype == vtype)
{
/* when both are maps, how should this operation be
* interpreted?
@ -277,16 +275,16 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
}
else
{
errnum = HAWK_ESCALARTOMAP;
errfmt = HAWK_T("not allowed to change a scalar '%.*js' to a map");
errnum = HAWK_ESCALARTONONSCA;
errfmt = HAWK_T("not allowed to change a scalar value in '%.*js' to a non-scalar value");
}
}
else
{
if (old_vtype == HAWK_VAL_MAP)
if (old_vtype == HAWK_VAL_MAP || old_vtype == HAWK_VAL_ARR)
{
errnum = HAWK_EMAPTOSCALAR;
errfmt = HAWK_T("not allowed to change a map '%.*js' to a scalar");
errnum = HAWK_ENONSCATOSCALAR;
errfmt = HAWK_T("not allowed to change a non-scalar value in '%.*js' to a scalar value");
}
}
@ -312,7 +310,7 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
}
}
if (vtype == HAWK_VAL_MAP)
if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
if (idx >= HAWK_MIN_GBL_ID && idx <= HAWK_MAX_GBL_ID)
{
@ -325,7 +323,7 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
hawk_oocs_t ea;
ea.ptr = (hawk_ooch_t*)hawk_getgblname(hawk_rtx_gethawk(rtx), idx, &ea.len);
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_ESCALARTOMAP, HAWK_T("not allowed to change a scalar '%.*js' to a map"), ea.len, ea.ptr);
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_ESCALARTONONSCA, HAWK_T("not allowed to change a scalar value in '%.*js' to a non-scalar value"), ea.len, ea.ptr);
return -1;
}
}
@ -2709,19 +2707,12 @@ static int run_return (hawk_rtx_t* rtx, hawk_nde_return_t* nde)
{
hawk_val_type_t vtype = HAWK_RTX_GETVALTYPE(rtx, val);
if (vtype == HAWK_VAL_MAP)
if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* cannot return a map */
hawk_rtx_refupval (rtx, val);
hawk_rtx_refdownval (rtx, val);
hawk_rtx_seterrnum (rtx, &nde->loc, HAWK_EMAPRET);
return -1;
}
else if (vtype == HAWK_VAL_ARR)
{
hawk_rtx_refupval (rtx, val);
hawk_rtx_refdownval (rtx, val);
hawk_rtx_seterrnum (rtx, &nde->loc, HAWK_EARRRET);
hawk_rtx_seterrnum (rtx, &nde->loc, HAWK_ENONSCARET);
return -1;
}
}
@ -2989,7 +2980,7 @@ static hawk_val_t* assign_newmapval_to_var (hawk_rtx_t* rtx, hawk_nde_var_t* var
}
static int delete_indexed (hawk_rtx_t* rtx, hawk_val_t* vv, hawk_nde_var_t* var)
static int delete_indexed_in_map (hawk_rtx_t* rtx, hawk_val_t* vv, hawk_nde_var_t* var)
{
hawk_map_t* map;
hawk_ooch_t* str = HAWK_NULL;
@ -3039,7 +3030,7 @@ static int delete_indexed (hawk_rtx_t* rtx, hawk_val_t* vv, hawk_nde_var_t* var)
}
else
{
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENOTDEL, HAWK_T("nested scalar under '%.*js' not deletable"), var->id.name.len, var->id.name.ptr);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENOTDEL, HAWK_T("nested scalar value under '%.*js' not deletable"), var->id.name.len, var->id.name.ptr);
goto oops;
}
}
@ -3064,6 +3055,24 @@ oops:
return -1;
}
static int delete_indexed_in_arr (hawk_rtx_t* rtx, hawk_val_t* vv, hawk_nde_var_t* var)
{
hawk_arr_t* arr;
hawk_ooi_t idx;
HAWK_ASSERT (var->idx != HAWK_NULL);
HAWK_ASSERT (HAWK_RTX_GETVALTYPE(rtx, vv) == HAWK_VAL_ARR);
idx = idxnde_to_int(rtx, var->idx);
if (HAWK_UNLIKELY(idx <= -1)) return -1;
arr = ((hawk_val_arr_t*)vv)->arr;
/* no bound check because hawk_arr_delete() performs sanity check */
hawk_arr_delete (arr, idx, 1);
return 0;
}
static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde)
{
hawk_nde_var_t* var;
@ -3087,7 +3096,7 @@ static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde)
if (var->type == HAWK_NDE_NAMEDIDX || var->type == HAWK_NDE_GBLIDX ||
var->type == HAWK_NDE_LCLIDX || var->type == HAWK_NDE_ARGIDX)
{
if (delete_indexed(rtx, val, var) <= -1) goto oops;
if (delete_indexed_in_map(rtx, val, var) <= -1) goto oops;
}
else
{
@ -3104,6 +3113,17 @@ static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde)
}
break;
case HAWK_VAL_ARR:
if (var->type == HAWK_NDE_NAMEDIDX || var->type == HAWK_NDE_GBLIDX ||
var->type == HAWK_NDE_LCLIDX || var->type == HAWK_NDE_ARGIDX)
{
if (delete_indexed_in_arr(rtx, val, var) <= -1) goto oops;
}
else
{
hawk_arr_clear (((hawk_val_arr_t*)val)->arr);
}
break;
default:
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENOTDEL, HAWK_T("'%.*js' not deletable"), var->id.name.len, var->id.name.ptr);
goto oops;
@ -3754,15 +3774,10 @@ static hawk_val_t* do_assignment (hawk_rtx_t* rtx, hawk_nde_t* var, hawk_val_t*
case HAWK_NDE_ARGIDX:
#if !defined(HAWK_ENABLE_GC)
hawk_val_type_t vtype = HAWK_RTX_GETVALTYPE(rtx, val);
if (vtype == HAWK_VAL_MAP)
if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* a map cannot become a member of a map */
errnum = HAWK_EMAPTOIDX;
goto exit_on_error;
}
else if (vtype == HAWK_VAL_ARR)
{
errnum = HAWK_EARRTOIDX;
errnum = HAWK_ENONSCATOIDX;
goto exit_on_error;
}
#endif
@ -3773,15 +3788,10 @@ static hawk_val_t* do_assignment (hawk_rtx_t* rtx, hawk_nde_t* var, hawk_val_t*
case HAWK_NDE_POS:
{
hawk_val_type_t vtype = HAWK_RTX_GETVALTYPE(rtx, val);
if (vtype == HAWK_VAL_MAP)
if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* a map cannot be assigned to a positional */
errnum = HAWK_EMAPTOPOS;
goto exit_on_error;
}
else if (vtype == HAWK_VAL_ARR)
{
errnum = HAWK_EARRTOPOS;
errnum = HAWK_ENONSCATOPOS;
goto exit_on_error;
}
@ -3826,20 +3836,21 @@ static hawk_val_t* do_assignment_nonidx (hawk_rtx_t* rtx, hawk_nde_var_t* var, h
if (!(rtx->hawk->opt.trait & HAWK_FLEXMAP))
{
if (pair && HAWK_RTX_GETVALTYPE(rtx, (hawk_val_t*)HAWK_HTB_VPTR(pair)) == HAWK_VAL_MAP)
hawk_val_type_t old_vtype;
if (pair && ((old_vtype = HAWK_RTX_GETVALTYPE(rtx, (hawk_val_t*)HAWK_HTB_VPTR(pair))) == HAWK_VAL_MAP || old_vtype == HAWK_VAL_ARR))
{
/* old value is a map - it can only be accessed through indexing. */
if (vtype == HAWK_VAL_MAP)
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOMAP, HAWK_T("not allowed to change a map '%.*js' to another map"), var->id.name.len, var->id.name.ptr);
if (vtype == old_vtype)
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATONONSCA, HAWK_T("not allowed to change a non-scalar value in '%.*js' to another non-scalar value"), var->id.name.len, var->id.name.ptr);
else
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOSCALAR, HAWK_T("not allowed to change a map '%.*js' to a scalar"), var->id.name.len, var->id.name.ptr);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATOSCALAR, HAWK_T("not allowed to change a non-scalar value in '%.*js' to a scalar value"), var->id.name.len, var->id.name.ptr);
return HAWK_NULL;
}
else if (vtype == HAWK_VAL_MAP)
else if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* 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. */
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOVAR, HAWK_T("not allowed to assign a map to a variable '%.*js'"), var->id.name.len, var->id.name.ptr);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATOVAR, HAWK_T("not allowed to assign a non-scalar value to a variable '%.*js'"), var->id.name.len, var->id.name.ptr);
return HAWK_NULL;
}
}
@ -3870,20 +3881,22 @@ static hawk_val_t* do_assignment_nonidx (hawk_rtx_t* rtx, hawk_nde_var_t* var, h
if (!(rtx->hawk->opt.trait & HAWK_FLEXMAP))
{
if (HAWK_RTX_GETVALTYPE(rtx, old) == HAWK_VAL_MAP)
hawk_val_type_t old_type;
if ((old_type = HAWK_RTX_GETVALTYPE(rtx, old)) == HAWK_VAL_MAP || old_type == HAWK_VAL_ARR)
{
/* old value is a map - it can only be accessed through indexing. */
if (vtype == HAWK_VAL_MAP)
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOMAP, HAWK_T("not allowed to change a map '%.*js' to another map"), var->id.name.len, var->id.name.ptr);
if (vtype == old_type)
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATONONSCA, HAWK_T("not allowed to change a non-scalar value in '%.*js' to another non-scalar value"), var->id.name.len, var->id.name.ptr);
else
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOSCALAR, HAWK_T("not allowed to change a map '%.*js' to a scalar"), var->id.name.len, var->id.name.ptr);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATOSCALAR, HAWK_T("not allowed to change a non-scalar value in '%.*js' to a scalar value"), var->id.name.len, var->id.name.ptr);
return HAWK_NULL;
}
else if (vtype == HAWK_VAL_MAP)
else if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* 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. */
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOVAR, HAWK_T("not allowed to assign a map to a variable '%.*js'"), var->id.name.len, var->id.name.ptr);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATOVAR, HAWK_T("not allowed to assign a non-scalar value to a variable '%.*js'"), var->id.name.len, var->id.name.ptr);
return HAWK_NULL;
}
}
@ -3900,20 +3913,22 @@ static hawk_val_t* do_assignment_nonidx (hawk_rtx_t* rtx, hawk_nde_var_t* var, h
if (!(rtx->hawk->opt.trait & HAWK_FLEXMAP))
{
if (HAWK_RTX_GETVALTYPE(rtx, old) == HAWK_VAL_MAP)
hawk_val_type_t old_type;
if ((old_type = HAWK_RTX_GETVALTYPE(rtx, old) == HAWK_VAL_MAP) || old_type == HAWK_VAL_ARR)
{
/* old value is a map - it can only be accessed through indexing. */
if (vtype == HAWK_VAL_MAP)
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOMAP, HAWK_T("not allowed to change a map '%.*js' to another map"), var->id.name.len, var->id.name.ptr);
if (vtype == old_type)
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATONONSCA, HAWK_T("not allowed to change a non-scalar value in '%.*js' to another non-scalar value"), var->id.name.len, var->id.name.ptr);
else
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOSCALAR, HAWK_T("not allowed to change a map '%.*js' to a scalar"), var->id.name.len, var->id.name.ptr);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATOSCALAR, HAWK_T("not allowed to change a non-scalar value in '%.*js' to a scalar value"), var->id.name.len, var->id.name.ptr);
return HAWK_NULL;
}
else if (vtype == HAWK_VAL_MAP)
else if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* 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. */
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_EMAPTOVAR, HAWK_T("not allowed to assign a map to a variable '%.*js'"), var->id.name.len, var->id.name.ptr);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ENONSCATOVAR, HAWK_T("not allowed to assign a non-scalar value to a variable '%.*js'"), var->id.name.len, var->id.name.ptr);
return HAWK_NULL;
}
}
@ -4007,7 +4022,7 @@ static hawk_val_t* do_assignment_idx (hawk_rtx_t* rtx, hawk_nde_var_t* var, hawk
}
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);
hawk_rtx_seterrfmt (rtx, &var->loc, HAWK_ESCALARTONONSCA, HAWK_T("not allowed to change a nested scalar value under '%.*js' to a non-scalar value"), var->id.name.len, var->id.name.ptr);
goto oops_map;
}
}
@ -4064,7 +4079,7 @@ static hawk_val_t* do_assignment_idx (hawk_rtx_t* rtx, hawk_nde_var_t* var, hawk
{
/* you can't manipulate a variable pointing to
* 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_ESCALARTONONSCA, HAWK_T("not allowed to change a scalar value in '%.*js' to a non-scalar value"), var->id.name.len, var->id.name.ptr);
return HAWK_NULL;
}
}
@ -6918,7 +6933,8 @@ static hawk_val_t* eval_indexed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
if (idx <= -1) return HAWK_NULL;
arr = ((hawk_val_arr_t*)v)->arr;
/* return nil if the index is out of range or the element at the index is not set */
/* return nil if the index is out of range or the element at the index is not set.
* no check for a negative index as it's guaranteed to be positive by idxnde_to_int() */
return (idx < HAWK_ARR_SIZE(arr) && HAWK_ARR_SLOT(arr, idx))? ((hawk_val_t*)HAWK_ARR_DPTR(arr, idx)): hawk_val_nil;
}

View File

@ -1238,7 +1238,7 @@ hawk_val_t* hawk_rtx_makemapvalwithdata (hawk_rtx_t* rtx, hawk_val_map_data_t da
hawk_val_t* hawk_rtx_setmapvalfld (hawk_rtx_t* rtx, hawk_val_t* map, const hawk_ooch_t* kptr, hawk_oow_t klen, hawk_val_t* v)
{
HAWK_ASSERT (HAWK_RTX_GETVALTYPE (rtx, map) == HAWK_VAL_MAP);
HAWK_ASSERT (HAWK_RTX_GETVALTYPE(rtx, map) == HAWK_VAL_MAP);
if (hawk_map_upsert(((hawk_val_map_t*)map)->map, (hawk_ooch_t*)kptr, klen, v, 0) == HAWK_NULL) return HAWK_NULL;
@ -1344,6 +1344,7 @@ const hawk_ooch_t* hawk_rtx_getvaltypename(hawk_rtx_t* rtx, hawk_val_t* val)
HAWK_T("mbs"),
HAWK_T("fun"),
HAWK_T("map"),
HAWK_T("arr"),
HAWK_T("rex"),
HAWK_T("ref")
};
@ -1351,7 +1352,6 @@ const hawk_ooch_t* hawk_rtx_getvaltypename(hawk_rtx_t* rtx, hawk_val_t* val)
return __val_type_name[HAWK_RTX_GETVALTYPE(rtx, val)];
}
int hawk_rtx_getintfromval (hawk_rtx_t* rtx, hawk_val_t* val)
{
return HAWK_RTX_GETINTFROMVAL(rtx, val);
@ -1636,6 +1636,8 @@ int hawk_rtx_valtobool (hawk_rtx_t* rtx, const hawk_val_t* val)
case HAWK_VAL_MAP:
/* true if the map size is greater than 0. false if not */
return HAWK_MAP_SIZE(((hawk_val_map_t*)val)->map) > 0;
case HAWK_VAL_ARR:
return HAWK_ARR_SIZE(((hawk_val_arr_t*)val)->arr) > 0;
case HAWK_VAL_REF:
return val_ref_to_bool(rtx, (hawk_val_ref_t*)val);
}
@ -2068,6 +2070,13 @@ int hawk_rtx_valtostr (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_rtx_valtostr_o
}
goto invalid;
case HAWK_VAL_ARR:
if (rtx->hawk->opt.trait & HAWK_FLEXMAP)
{
return str_to_str(rtx, HAWK_T("#ARR"), 4, out);
}
goto invalid;
case HAWK_VAL_REF:
return val_ref_to_str(rtx, (hawk_val_ref_t*)v, out);
@ -2412,6 +2421,14 @@ int hawk_rtx_valtonum (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_int_t* l, hawk
}
goto invalid;
case HAWK_VAL_ARR:
if (rtx->hawk->opt.trait & HAWK_FLEXMAP)
{
*l = HAWK_ARR_SIZE(((hawk_val_arr_t*)v)->arr);
return 0; /* long */
}
goto invalid;
case HAWK_VAL_REF:
return val_ref_to_num(rtx, (hawk_val_ref_t*)v, l, r);
@ -2665,8 +2682,9 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val)
switch (vtype)
{
case HAWK_VAL_MAP:
case HAWK_VAL_ARR:
/* a map is assigned to a positional. this is disallowed. */
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EMAPTOPOS);
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENONSCATOPOS);
return -1;
case HAWK_VAL_STR:
@ -2718,11 +2736,11 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val)
case HAWK_VAL_REF_LCLIDX:
case HAWK_VAL_REF_ARGIDX:
#if !defined(HAWK_ENABLE_GC)
if (vtype == HAWK_VAL_MAP)
if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* an indexed variable cannot be assigned a map.
* in other cases, it falls down to the default case. */
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EMAPTOIDX);
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENONSCATOIDX);
return -1;
}
#endif
@ -2735,15 +2753,15 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val)
rref = (hawk_val_t**)ref->adr; /* old value pointer */
rref_vtype = HAWK_RTX_GETVALTYPE(rtx, *rref); /* old value type */
if (vtype == HAWK_VAL_MAP)
if (vtype == HAWK_VAL_MAP || vtype == HAWK_VAL_ARR)
{
/* new value: map, old value: nil or map => ok */
if (rref_vtype != HAWK_VAL_NIL && rref_vtype != HAWK_VAL_MAP)
if (rref_vtype != HAWK_VAL_NIL && rref_vtype != vtype)
{
if (!(rtx->hawk->opt.trait & HAWK_FLEXMAP))
{
/* cannot change a scalar value to a map */
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ESCALARTOMAP);
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ESCALARTONONSCA);
return -1;
}
}
@ -2751,11 +2769,11 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val)
else
{
/* new value: scalar, old value: nil or scalar => ok */
if (rref_vtype == HAWK_VAL_MAP)
if (rref_vtype == HAWK_VAL_MAP || rref_vtype == HAWK_VAL_ARR)
{
if (!(rtx->hawk->opt.trait & HAWK_FLEXMAP))
{
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EMAPTOSCALAR);
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENONSCATOSCALAR);
return -1;
}
}
@ -2779,9 +2797,9 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val)
static hawk_map_walk_t print_pair (hawk_map_t* map, hawk_map_pair_t* pair, void* arg)
{
hawk_rtx_t* run = (hawk_rtx_t*)arg;
hawk_rtx_t* rtx = (hawk_rtx_t*)arg;
HAWK_ASSERT (run == *(hawk_rtx_t**)hawk_map_getxtn(map));
HAWK_ASSERT (rtx == *(hawk_rtx_t**)hawk_map_getxtn(map));
hawk_errputstrf (HAWK_T(" %.*s=>"), HAWK_MAP_KLEN(pair), HAWK_MAP_KPTR(pair));
hawk_dprintval ((hawk_rtx_t*)arg, HAWK_MAP_VPTR(pair));
@ -2790,6 +2808,21 @@ static hawk_map_walk_t print_pair (hawk_map_t* map, hawk_map_pair_t* pair, void*
return HAWK_MAP_WALK_FORWARD;
}
static hawk_arr_walk_t print_pair (hawk_arr_t* arr, hawk_oow_t index, void* arg)
{
hawk_rtx_t* rtx = (hawk_rtx_t*)arg;
HAWK_ASSERT (rtx == *(hawk_rtx_t**)hawk_arr_getxtn(arr));
hawk_errputstrf (HAWK_T(" %lu=>"), (unsigned long int)index);
hawk_dprintval ((hawk_rtx_t*)arg, (HAWK_ARR_SLOT(arr,index)? HAWK_ARR_DPTR(arr, index): hawk_val_nil));
hawk_errputstrf (HAWK_T(" "));
return HAWK_ARR_WALK_FORWARD;
}
void hawk_dprintval (hawk_rtx_t* run, hawk_val_t* val)
{
/* TODO: better value printing ... */
@ -2832,6 +2865,12 @@ void hawk_dprintval (hawk_rtx_t* run, hawk_val_t* val)
hawk_errputstrf (HAWK_T("]"));
break;
case HAWK_VAL_ARR:
hawk_errputstrf (HAWK_T("ARR["));
hawk_arr_walk (((hawk_val_arr_t*)val)->arr, print_elem, run);
hawk_errputstrf (HAWK_T("]"));
break;
case HAWK_VAL_REF:
hawk_errputstrf (HAWK_T("REF[id=%d,val="), ((hawk_val_ref_t*)val)->id);
hawk_dprintval (run, *((hawk_val_ref_t*)val)->adr);

View File

@ -61,5 +61,17 @@ function main()
ensure (b[2], "perfect", SCRIPTNAME);
}
{
@local a;
a[1] = hawk::array();
a[1][2]=20;
ensure (a[1][2], 20, SCRIPTNAME);
a[1][2]++;
ensure (a[1][2], 21, SCRIPTNAME);
--a[1][2];
ensure (a[1][2], 20, SCRIPTNAME);
}
print "SUCCESS"
}