summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2024-07-29 15:04:34 +0200
committerJo-Philipp Wich <jo@mein.io>2025-02-20 09:09:56 +0100
commit9260bd5354bf2cf39e3c125f776ed832f28bc356 (patch)
treebc724ba0fde8cd213e12131a038d66c3282ad969
parent0255af462be3c4b2aeaa77014376e22e9300ffc3 (diff)
WIP: lib: support map() over objects
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--lib.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/lib.c b/lib.c
index 6415e3c..16f3533 100644
--- a/lib.c
+++ b/lib.c
@@ -1154,6 +1154,29 @@ uc_lc(uc_vm_t *vm, size_t nargs)
return rv;
}
+static bool
+uc_map_cb(uc_vm_t *vm, uc_value_t *cb, uc_value_t *out,
+ uc_value_t *item, uc_value_t *index, uc_value_t *obj)
+{
+ uc_vm_ctx_push(vm);
+ uc_vm_stack_push(vm, ucv_get(cb));
+ uc_vm_stack_push(vm, ucv_get(item));
+ uc_vm_stack_push(vm, index);
+ uc_vm_stack_push(vm, ucv_get(obj));
+
+ if (uc_vm_call(vm, true, 3)) {
+ ucv_put(out);
+
+ return false;
+ }
+
+ uc_value_t *rv = uc_vm_stack_pop(vm);
+
+ ucv_array_push(out, rv);
+
+ return true;
+}
+
/**
* Transform the array passed as the first argument by invoking the function
* specified in the second argument for each array item.
@@ -1217,30 +1240,33 @@ uc_map(uc_vm_t *vm, size_t nargs)
{
uc_value_t *obj = uc_fn_arg(0);
uc_value_t *func = uc_fn_arg(1);
- uc_value_t *arr, *rv;
+ uc_value_t *arr = NULL;
size_t arridx, arrlen;
- if (ucv_type(obj) != UC_ARRAY)
- return NULL;
+ switch (ucv_type(obj)) {
+ case UC_ARRAY:
+ arr = ucv_array_new(vm);
- arr = ucv_array_new(vm);
+ for (arrlen = ucv_array_length(obj), arridx = 0; arridx < arrlen; arridx++) {
+ if (!uc_map_cb(vm, func, arr, ucv_array_get(obj, arridx),
+ ucv_uint64_new(arridx), obj))
+ return NULL;
+ }
- for (arrlen = ucv_array_length(obj), arridx = 0; arridx < arrlen; arridx++) {
- uc_vm_ctx_push(vm);
- uc_vm_stack_push(vm, ucv_get(func));
- uc_vm_stack_push(vm, ucv_get(ucv_array_get(obj, arridx)));
- uc_vm_stack_push(vm, ucv_int64_new(arridx));
- uc_vm_stack_push(vm, ucv_get(obj));
+ break;
- if (uc_vm_call(vm, true, 3)) {
- ucv_put(arr);
+ case UC_OBJECT:
+ arr = ucv_array_new(vm);
- return NULL;
+ ucv_object_foreach(obj, k, v) {
+ if (!uc_map_cb(vm, func, arr, v, ucv_string_new(k), obj))
+ return NULL;
}
- rv = uc_vm_stack_pop(vm);
+ break;
- ucv_array_push(arr, rv);
+ default:
+ break;
}
return arr;