"def max_by(f): _max_by_impl(map([f]));",
"def min_by(f): _min_by_impl(map([f]));",
"def del(f): delpaths([path(f)]);",
+ "def _assign(paths; value): value as $v | fold . as $obj (path(paths) as $p | $obj | setpath($p; $v));",
+ "def _modify(paths; update): fold . as $obj (path(paths) as $p | $obj | setpath($p; getpath($p) | update));",
+
};
OP_HAS_VARIABLE));
}
-block gen_assign(block expr) {
- block result_var = block_bind(gen_op_var_unbound(STOREV, "result"),
- gen_noop(), OP_HAS_VARIABLE);
-
- block loop = BLOCK(gen_op_simple(DUP),
- expr,
- gen_op_var_bound(ASSIGN, result_var),
- gen_op_simple(BACKTRACK));
-
- return BLOCK(gen_op_simple(DUP),
- result_var,
- gen_op_target(FORK, loop),
- loop,
- gen_op_var_bound(LOADV, result_var));
-}
-
block gen_definedor(block a, block b) {
// var found := false
block found_var = block_bind(gen_op_var_unbound(STOREV, "found"),
block gen_both(block a, block b);
block gen_collect(block expr);
block gen_fold(const char* varname, block init, block body);
-block gen_assign(block expr);
block gen_definedor(block a, block b);
block gen_condbranch(block iftrue, block iffalse);
block gen_and(block a, block b);
break;
}
- case ASSIGN: {
- stackval replacement = stack_pop();
- stackval path_end = stack_pop();
- stackval path_start = stack_pop();
- jv_free(path_end.value);
- jv_free(path_start.value);
-
- jv path = jv_array();
- for (int i=path_start.pathidx; i<path_end.pathidx; i++) {
- path = jv_array_set(path, i, jv_copy(pathbuf[i]));
- }
-
-
-
- uint16_t level = *pc++;
- uint16_t v = *pc++;
- frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
- jv* var = frame_local_var(fp, v);
- jv result = jv_setpath(*var, path, replacement.value);
- if (jv_is_valid(result)) {
- *var = result;
- } else {
- print_error(result);
- *var = jv_null();
- }
- break;
- }
-
case INDEX: {
stackval t = stack_pop();
jv k = stack_pop().value;
OP(INSERT, NONE, 4, 2)
OP(GETPATH, NONE, 2, 1)
-OP(ASSIGN, VARIABLE, 3, 0)
OP(CALL_BUILTIN, CFUNC, -1, 1)
return BLOCK(a, gen_call("format", BLOCK(gen_lambda(gen_const(fmt)))));
}
-static block gen_update(block a, block op, int optype) {
- if (optype) {
- op = gen_binop(gen_noop(), op, optype);
- }
- return gen_assign(BLOCK(a, gen_op_simple(DUP), op));
+static block gen_update(block object, block val, int optype) {
+ block tmp = block_bind(gen_op_var_unbound(STOREV, "tmp"),
+ gen_noop(), OP_HAS_VARIABLE);
+ return BLOCK(gen_op_simple(DUP),
+ val,
+ tmp,
+ gen_call("_modify", BLOCK(gen_lambda(object),
+ gen_lambda(gen_binop(gen_noop(),
+ gen_op_var_bound(LOADV, tmp),
+ optype)))));
}
%}
} |
Exp '=' Exp {
- $$ = gen_assign(BLOCK(gen_op_simple(DUP), $3, gen_op_simple(SWAP), $1, gen_op_simple(SWAP)));
+ $$ = gen_call("_assign", BLOCK(gen_lambda($1), gen_lambda($3)));
} |
Exp "or" Exp {
} |
Exp "|=" Exp {
- $$ = gen_update($1, $3, 0);
+ $$ = gen_call("_modify", BLOCK(gen_lambda($1), gen_lambda($3)));
} |
Exp '|' Exp {
[-1,1,3]
[0.5, 1.5, 2.5]
+.foo += .foo
+{"foo":2}
+{"foo":4}
+
.[0].a |= {"old":., "new":(.+1)}
[{"a":1,"b":2}]
[{"a":{"old":1, "new":2},"b":2}]