diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-08-24 12:02:49 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-08-24 12:02:49 +0200 |
commit | 631000add6379cb08968746bbb46e98b939b8c99 (patch) | |
tree | 99263a56f60eebf23d740e18b4efb1432f4cba5e | |
parent | 8a821177b01984715b42035186f562b5a427732e (diff) |
eval.c, lib.c: allow invoking functions with existing scope
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | eval.c | 23 | ||||
-rw-r--r-- | eval.h | 2 | ||||
-rw-r--r-- | lib.c | 6 |
3 files changed, 17 insertions, 14 deletions
@@ -801,11 +801,12 @@ ut_execute_object(struct ut_state *state, struct ut_opcode *op) } struct json_object * -ut_invoke(struct ut_state *state, struct ut_opcode *op, struct json_object *func, struct json_object *argvals) +ut_invoke(struct ut_state *state, struct ut_opcode *op, struct json_object *scope, + struct json_object *func, struct json_object *argvals) { struct ut_opcode *decl = json_object_get_userdata(func); struct ut_opcode *arg = decl ? decl->operand[1] : NULL; - struct json_object *scope, *rv = NULL; + struct json_object *s, *rv = NULL; struct ut_opcode *tag; size_t arridx; ut_c_fn *cfn; @@ -820,13 +821,13 @@ ut_invoke(struct ut_state *state, struct ut_opcode *op, struct json_object *func return cfn ? cfn(state, op, argvals) : NULL; } - scope = ut_addscope(state, decl); + s = scope ? scope : ut_addscope(state, decl); - if (!json_object_is_type(scope, json_type_object)) - return scope; + if (!json_object_is_type(s, json_type_object)) + return s; for (arridx = 0; arg; arridx++, arg = arg->sibling) - ut_setval(scope, arg->val, json_object_array_get_idx(argvals, arridx)); + ut_setval(s, arg->val, argvals ? json_object_array_get_idx(argvals, arridx) : NULL); rv = ut_execute_op_sequence(state, decl->operand[2]); tag = json_object_get_userdata(rv); @@ -851,9 +852,11 @@ ut_invoke(struct ut_state *state, struct ut_opcode *op, struct json_object *func break; } - state->stack.scope[--state->stack.off] = NULL; + if (!scope) { + state->stack.scope[--state->stack.off] = NULL; - json_object_put(scope); + json_object_put(s); + } return rv; } @@ -876,7 +879,7 @@ ut_execute_call(struct ut_state *state, struct ut_opcode *op) free(lhs); } else { - rv = ut_invoke(state, op, func, argvals); + rv = ut_invoke(state, op, NULL, func, argvals); } ut_putval(argvals); @@ -1294,7 +1297,7 @@ ut_run(struct ut_state *state) ut_lib_init(state, scope); args = json_object_new_array(); - rv = ut_invoke(state, state->main, state->main->val, args); + rv = ut_invoke(state, state->main, NULL, state->main->val, args); json_object_put(args); json_object_put(rv); @@ -40,7 +40,7 @@ enum json_type ut_cast_number(struct json_object *v, int64_t *n, double *d); struct json_object * -ut_invoke(struct ut_state *, struct ut_opcode *, struct json_object *, struct json_object *); +ut_invoke(struct ut_state *, struct ut_opcode *, struct json_object *, struct json_object *, struct json_object *); enum ut_error_type ut_run(struct ut_state *state); @@ -435,7 +435,7 @@ ut_filter(struct ut_state *s, struct ut_opcode *op, struct json_object *args) json_object_array_put_idx(cmpargs, 0, json_object_get(json_object_array_get_idx(obj, arridx))); json_object_array_put_idx(cmpargs, 1, json_object_new_int64(arridx)); - rv = ut_invoke(s, op, func, cmpargs); + rv = ut_invoke(s, op, NULL, func, cmpargs); if (ut_val_is_truish(rv)) json_object_array_add(arr, json_object_get(json_object_array_get_idx(obj, arridx))); @@ -622,7 +622,7 @@ ut_map(struct ut_state *s, struct ut_opcode *op, struct json_object *args) json_object_array_put_idx(cmpargs, 0, json_object_get(json_object_array_get_idx(obj, arridx))); json_object_array_put_idx(cmpargs, 1, json_object_new_int64(arridx)); - json_object_array_add(arr, ut_invoke(s, op, func, cmpargs)); + json_object_array_add(arr, ut_invoke(s, op, NULL, func, cmpargs)); } ut_putval(cmpargs); @@ -779,7 +779,7 @@ sort_fn(const void *k1, const void *k2) json_object_array_put_idx(sort_ctx.args, 0, *v1); json_object_array_put_idx(sort_ctx.args, 1, *v2); - rv = ut_invoke(sort_ctx.s, sort_ctx.op, sort_ctx.fn, sort_ctx.args); + rv = ut_invoke(sort_ctx.s, sort_ctx.op, NULL, sort_ctx.fn, sort_ctx.args); ret = !ut_val_is_truish(rv); ut_putval(rv); |