Refactor assignment.
New version is much more elegant and probably slower. Uses library functions implemented in jq rather than dedicated opcodes.
This commit is contained in:
1 parent
465a4ec565
commit
d5fdf70434
7 files changed
+19
-53
No files matched your search
@@ -552,6 +552,9 @@ static const char* jq_builtins[] = {
|
||||
"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));",
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -317,22 +317,6 @@ block gen_fold(const char* varname, block init, block fold) {
|
||||
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"),
|
||||
|
||||
@@ -34,7 +34,6 @@ block gen_subexp(block a);
|
||||
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);
|
||||
|
||||
@@ -298,34 +298,6 @@ jv jq_next() {
|
||||
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;
|
||||
|
||||
@@ -16,7 +16,6 @@ OP(APPEND, NONE, 2, 1)
|
||||
OP(INSERT, NONE, 4, 2)
|
||||
|
||||
OP(GETPATH, NONE, 2, 1)
|
||||
OP(ASSIGN, VARIABLE, 3, 0)
|
||||
|
||||
OP(CALL_BUILTIN, CFUNC, -1, 1)
|
||||
|
||||
|
||||
@@ -164,11 +164,16 @@ static block gen_format(block a, jv fmt) {
|
||||
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)))));
|
||||
}
|
||||
|
||||
%}
|
||||
@@ -216,7 +221,7 @@ Term "as" '$' IDENT '|' Exp {
|
||||
} |
|
||||
|
||||
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 {
|
||||
@@ -236,7 +241,7 @@ Exp "//=" Exp {
|
||||
} |
|
||||
|
||||
Exp "|=" Exp {
|
||||
$$ = gen_update($1, $3, 0);
|
||||
$$ = gen_call("_modify", BLOCK(gen_lambda($1), gen_lambda($3)));
|
||||
} |
|
||||
|
||||
Exp '|' Exp {
|
||||
|
||||
Reference in new issue
Block a user