diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-11-05 22:56:14 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-11-05 23:17:03 +0100 |
commit | f6869ee3b02a60b202c703f7caef165ee3845e5a (patch) | |
tree | e618e1bbb93c10fc45100afada4ed537e5655733 /eval.c | |
parent | feb815bc1a058b91eed9dea3c5cad8ea52d51806 (diff) |
eval: rework handling of list expressions
Tune the grammar and rework the VM to properly yield the last result of
list expressions in various contexts.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 38 |
1 files changed, 24 insertions, 14 deletions
@@ -137,6 +137,9 @@ static struct json_object * ut_execute_op(struct ut_state *state, uint32_t off); static struct json_object * +ut_execute_op_sequence(struct ut_state *state, uint32_t off); + +static struct json_object * ut_execute_list(struct ut_state *state, uint32_t off); static char * @@ -216,11 +219,11 @@ ut_getref(struct ut_state *state, uint32_t off, struct json_object **key) if (key) *key = off2 ? json_object_get(ut_get_op(state, off2)->val) : NULL; - return ut_execute_op(state, off1); + return ut_execute_op_sequence(state, off1); } else if (op && op->type == T_LBRACK && op->is_postfix) { if (key) { - val = off2 ? ut_execute_op(state, off2) : NULL; + val = off2 ? ut_execute_op_sequence(state, off2) : NULL; if (ut_is_type(val, T_EXCEPTION)) return val; @@ -228,7 +231,7 @@ ut_getref(struct ut_state *state, uint32_t off, struct json_object **key) *key = val; } - return ut_execute_op(state, off1); + return ut_execute_op_sequence(state, off1); } else if (op && op->type == T_LABEL) { sc = state->scope; @@ -397,7 +400,7 @@ ut_execute_assign(struct ut_state *state, uint32_t off) if (!key) return scope; - val = ut_execute_op(state, value); + val = ut_execute_op_sequence(state, value); if (!ut_is_type(val, T_EXCEPTION)) ut_setval(scope, key, val); @@ -422,7 +425,7 @@ ut_execute_local(struct ut_state *state, uint32_t off) if (alop) { label = alop->val; - val = asop->tree.operand[1] ? ut_execute_op(state, asop->tree.operand[1]) : NULL; + val = asop->tree.operand[1] ? ut_execute_op_sequence(state, asop->tree.operand[1]) : NULL; if (ut_is_type(val, T_EXCEPTION)) return val; @@ -504,7 +507,7 @@ ut_execute_for(struct ut_state *state, uint32_t off) if (ut_is_type(scope, T_EXCEPTION)) return scope; - val = ut_execute_op(state, init->tree.operand[1]); + val = ut_execute_op_sequence(state, init->tree.operand[1]); if (ut_is_type(val, T_EXCEPTION)) return val; @@ -663,7 +666,7 @@ ut_execute_and_or(struct ut_state *state, uint32_t off) for (i = 0; i < ARRAY_SIZE(op->tree.operand) && op->tree.operand[i]; i++) { json_object_put(val); - val = ut_execute_op(state, op->tree.operand[i]); + val = ut_execute_op_sequence(state, op->tree.operand[i]); if (ut_is_type(val, T_EXCEPTION)) break; @@ -749,7 +752,7 @@ _ut_get_operands(struct ut_state *state, struct ut_op *op, size_t n, struct json if (child && child->is_list) v[i] = ut_execute_list(state, ut_get_off(state, child)); else if (child) - v[i] = ut_execute_op(state, ut_get_off(state, child)); + v[i] = ut_execute_op_sequence(state, ut_get_off(state, child)); else v[i] = NULL; @@ -967,14 +970,12 @@ static struct json_object * ut_execute_object(struct ut_state *state, uint32_t off) { struct json_object *ex, *v, *obj = ut_new_object(NULL); - struct ut_op *key, *val; + struct ut_op *key; char *istr; size_t i; - for (key = ut_get_child(state, off, 0), val = ut_get_op(state, key ? key->tree.next : 0); - key != NULL && val != NULL; - key = ut_get_op(state, val->tree.next), val = ut_get_op(state, key ? key->tree.next : 0)) { - v = ut_execute_op(state, ut_get_off(state, val)); + for (key = ut_get_child(state, off, 0); key; key = ut_get_op(state, key->tree.next)) { + v = ut_execute_op_sequence(state, key->tree.operand[0]); if (ut_is_type(v, T_EXCEPTION)) { json_object_put(obj); @@ -1005,7 +1006,7 @@ ut_execute_object(struct ut_state *state, uint32_t off) break; default: - ex = ut_new_exception(state, val->off, "Type error: (%s) is not iterable", + ex = ut_new_exception(state, key->off, "Type error: (%s) is not iterable", json_object_get_string(v)); json_object_put(obj); @@ -1626,6 +1627,14 @@ ut_execute_lbrack(struct ut_state *state, uint32_t off) return ut_execute_list(state, op->tree.operand[0]); } +static struct json_object * +ut_execute_exp_list(struct ut_state *state, uint32_t off) +{ + struct ut_op *op = ut_get_op(state, off); + + return ut_execute_op_sequence(state, op->tree.operand[0]); +} + static struct json_object *(*fns[__T_MAX])(struct ut_state *, uint32_t) = { [T_NUMBER] = ut_execute_atom, [T_DOUBLE] = ut_execute_atom, @@ -1680,6 +1689,7 @@ static struct json_object *(*fns[__T_MAX])(struct ut_state *, uint32_t) = { [T_CONTINUE] = ut_execute_break_cont, [T_TRY] = ut_execute_try_catch, [T_SWITCH] = ut_execute_switch_case, + [T_COMMA] = ut_execute_exp_list, }; static struct json_object * |