diff options
author | Jo-Philipp Wich <jo@mein.io> | 2024-07-29 15:04:34 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2025-02-20 09:09:56 +0100 |
commit | 9260bd5354bf2cf39e3c125f776ed832f28bc356 (patch) | |
tree | bc724ba0fde8cd213e12131a038d66c3282ad969 | |
parent | 0255af462be3c4b2aeaa77014376e22e9300ffc3 (diff) |
WIP: lib: support map() over objects
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | lib.c | 56 |
1 files changed, 41 insertions, 15 deletions
@@ -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; |