summaryrefslogtreecommitdiffhomepage
path: root/lib.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-10-04 20:22:50 +0200
committerJo-Philipp Wich <jo@mein.io>2022-10-04 21:43:57 +0200
commit00965fabd5daa2be1991daf3ddf9f838ca534957 (patch)
treec622f10ca64b0a0f90600decd48ad50a8c17c6f7 /lib.c
parenta5e59c9e93b9d435caa3fe786c745f0357bb3c0f (diff)
lib: implement slice() function
Implement a new function `slice()` to complement the existing `splice()` function and model it's semantics after the ES6 `Array.slice()` version. Fixes: #106 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index 51b99bf..834388a 100644
--- a/lib.c
+++ b/lib.c
@@ -1019,6 +1019,51 @@ uc_splice(uc_vm_t *vm, size_t nargs)
}
static uc_value_t *
+uc_slice(uc_vm_t *vm, size_t nargs)
+{
+ uc_value_t *arr = uc_fn_arg(0);
+ uc_value_t *sv = uc_fn_arg(1);
+ uc_value_t *ev = uc_fn_arg(2);
+ uc_value_t *res = NULL;
+ int64_t off, end;
+ size_t len;
+
+ if (ucv_type(arr) != UC_ARRAY)
+ return NULL;
+
+ len = ucv_array_length(arr);
+ off = sv ? ucv_to_integer(sv) : 0;
+ end = ev ? ucv_to_integer(ev) : (int64_t)len;
+
+ if (off < 0) {
+ off = len + off;
+
+ if (off < 0)
+ off = 0;
+ }
+ else if ((uint64_t)off > len) {
+ off = len;
+ }
+
+ if (end < 0) {
+ end = len + end;
+
+ if (end < 0)
+ end = 0;
+ }
+ else if ((uint64_t)end > len) {
+ end = len;
+ }
+
+ res = ucv_array_new(vm);
+
+ while (off < end)
+ ucv_array_push(res, ucv_get(ucv_array_get(arr, off++)));
+
+ return res;
+}
+
+static uc_value_t *
uc_split(uc_vm_t *vm, size_t nargs)
{
uc_value_t *str = uc_fn_arg(0);
@@ -3845,6 +3890,7 @@ const uc_function_list_t uc_stdlib_functions[] = {
{ "shift", uc_shift },
{ "sort", uc_sort },
{ "splice", uc_splice },
+ { "slice", uc_slice },
{ "split", uc_split },
{ "substr", uc_substr },
{ "time", uc_time },