From 86ea4e7071c7a56a5353fa0345e79ef3ebcb1a08 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 1 Jul 2024 18:57:33 +0900 Subject: [PATCH] improved the slicing function --- lib/hcl-prv.h | 7 ------- lib/hcl.h | 7 +++++++ lib/read.c | 2 +- mod/arr.c | 56 ++++++++++++++++++++++++++++++++++++++------------- mod/str.c | 2 +- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 16247c4..85b2e6f 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -1501,13 +1501,6 @@ hcl_oop_t hcl_allocwordobj ( hcl_oow_t len ); -hcl_oop_t hcl_instantiate ( - hcl_t* hcl, - hcl_oop_class_t _class, - const void* vptr, - hcl_oow_t vlen -); - hcl_oop_t hcl_instantiatewithtrailer ( hcl_t* hcl, hcl_oop_class_t _class, diff --git a/lib/hcl.h b/lib/hcl.h index 471c031..c186539 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -2837,6 +2837,13 @@ HCL_EXPORT hcl_oop_t hcl_hatchnil ( hcl_t* hcl ); +HCL_EXPORT hcl_oop_t hcl_instantiate ( + hcl_t* hcl, + hcl_oop_class_t _class, + const void* vptr, + hcl_oow_t vlen +); + HCL_EXPORT hcl_oop_t hcl_makecons ( hcl_t* hcl, hcl_oop_t car, diff --git a/lib/read.c b/lib/read.c index 83b517d..3fe08e1 100644 --- a/lib/read.c +++ b/lib/read.c @@ -1564,7 +1564,7 @@ static int feed_process_token (hcl_t* hcl) } case HCL_TOK_RPAREN: /* xlist (), qlist #() */ - case HCL_TOK_RBRACK: /* bytearray #[], array [] */ + case HCL_TOK_RBRACK: /* bytearray #b[], array #[] */ case HCL_TOK_RBRACE: /* dictionary #{}, block {} */ { int oldflagv; diff --git a/mod/arr.c b/mod/arr.c index a054dfd..56d16eb 100644 --- a/mod/arr.c +++ b/mod/arr.c @@ -100,18 +100,18 @@ static hcl_pfrc_t pf_arr_put (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) static hcl_pfrc_t pf_arr_size (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) { - hcl_oop_oop_t arr; + hcl_oop_oop_t src; hcl_oop_t size; - arr = (hcl_oop_oop_t)HCL_STACK_GETARG(hcl, nargs, 0); + src = (hcl_oop_oop_t)HCL_STACK_GETARG(hcl, nargs, 0); - if (!HCL_IS_ARRAY(hcl,arr)) + if (!HCL_OOP_IS_POINTER(src)) { - hcl_seterrbfmt (hcl, HCL_EINVAL, "parameter not an array - %O", arr); + hcl_seterrbfmt (hcl, HCL_EINVAL, "source not sizable - %O", src); return HCL_PF_FAILURE; } - size = hcl_oowtoint(hcl, HCL_OBJ_GET_SIZE(arr)); + size = hcl_oowtoint(hcl, HCL_OBJ_GET_SIZE(src)); if (!size) return HCL_PF_FAILURE; HCL_STACK_SETRET (hcl, nargs, size); @@ -120,21 +120,23 @@ static hcl_pfrc_t pf_arr_size (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) static hcl_pfrc_t pf_arr_slice (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) { - hcl_oop_t str, slice, a1, a2; + hcl_oop_t src, slice, a1, a2; hcl_ooi_t size; hcl_ooi_t pos; hcl_ooi_t len; hcl_ooi_t i; - str = HCL_STACK_GETARG(hcl, nargs, 0); + src = HCL_STACK_GETARG(hcl, nargs, 0); a1 = HCL_STACK_GETARG(hcl, nargs, 1); a2 = HCL_STACK_GETARG(hcl, nargs, 2); - if (!HCL_IS_ARRAY(hcl, str)) + if (!HCL_OOP_IS_POINTER(src)) { - hcl_seterrbfmt (hcl, HCL_EINVAL, "parameter not array - %O", str); + unsliceable: + hcl_seterrbfmt (hcl, HCL_EINVAL, "source not sliceable - %O", src); return HCL_PF_FAILURE; } + if (!HCL_OOP_IS_SMOOI(a1)) { hcl_seterrbfmt (hcl, HCL_EINVAL, "position not numeric - %O", a1); @@ -142,23 +144,49 @@ static hcl_pfrc_t pf_arr_slice (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) } if (!HCL_OOP_IS_SMOOI(a2)) { - hcl_seterrbfmt (hcl, HCL_EINVAL, "length not string - %O", a2); + hcl_seterrbfmt (hcl, HCL_EINVAL, "length not numeric - %O", a2); return HCL_PF_FAILURE; } - size = HCL_OBJ_GET_SIZE(str); + size = HCL_OBJ_GET_SIZE(src); pos = HCL_OOP_TO_SMOOI(a1); len = HCL_OOP_TO_SMOOI(a2); if (pos < 0) pos = 0; else if (pos >= size) pos = size; if (len >= size - pos) len = size - pos; - slice = hcl_makearray(hcl, len, 0); + +/* TODO: check if the object is an indexable object from the class spec... */ + /* use HCL_OBJ_GET_CLASS() instead of HCL_CLASSOF() as we know it's an object */ + slice = hcl_instantiate(hcl, (hcl_oop_class_t)HCL_OBJ_GET_CLASS(src), HCL_NULL, len); if (HCL_UNLIKELY(!slice)) return HCL_PF_FAILURE; - for (i = 0; i < len; i++) +/* OR if add by the number of fixed fields??? */ + switch (HCL_OBJ_GET_FLAGS_TYPE(src)) { - HCL_OBJ_GET_OOP_VAL(slice, i) = HCL_OBJ_GET_OOP_VAL(str, pos + i); + case HCL_OBJ_TYPE_OOP: + for (i = 0; i < len; i++) HCL_OBJ_GET_OOP_VAL(slice, i) = HCL_OBJ_GET_OOP_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_CHAR: + for (i = 0; i < len; i++) HCL_OBJ_GET_CHAR_VAL(slice, i) = HCL_OBJ_GET_CHAR_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_BYTE: + for (i = 0; i < len; i++) HCL_OBJ_GET_BYTE_VAL(slice, i) = HCL_OBJ_GET_BYTE_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_HALFWORD: + for (i = 0; i < len; i++) HCL_OBJ_GET_HALFWORD_VAL(slice, i) = HCL_OBJ_GET_HALFWORD_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_WORD: + for (i = 0; i < len; i++) HCL_OBJ_GET_WORD_VAL(slice, i) = HCL_OBJ_GET_WORD_VAL(src, pos + i); + break; + + default: + goto unsliceable; + break; } HCL_STACK_SETRET (hcl, nargs, slice); diff --git a/mod/str.c b/mod/str.c index 28cc51e..9519f30 100644 --- a/mod/str.c +++ b/mod/str.c @@ -145,7 +145,7 @@ static hcl_pfrc_t pf_str_slice (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) } if (!HCL_OOP_IS_SMOOI(a2)) { - hcl_seterrbfmt (hcl, HCL_EINVAL, "length not string - %O", a2); + hcl_seterrbfmt (hcl, HCL_EINVAL, "length not numeric - %O", a2); return HCL_PF_FAILURE; }