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 max_by(f): _max_by_impl(map([f]));",
|
||||||
"def min_by(f): _min_by_impl(map([f]));",
|
"def min_by(f): _min_by_impl(map([f]));",
|
||||||
"def del(f): delpaths([path(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));
|
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) {
|
block gen_definedor(block a, block b) {
|
||||||
// var found := false
|
// var found := false
|
||||||
block found_var = block_bind(gen_op_var_unbound(STOREV, "found"),
|
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_both(block a, block b);
|
||||||
block gen_collect(block expr);
|
block gen_collect(block expr);
|
||||||
block gen_fold(const char* varname, block init, block body);
|
block gen_fold(const char* varname, block init, block body);
|
||||||
block gen_assign(block expr);
|
|
||||||
block gen_definedor(block a, block b);
|
block gen_definedor(block a, block b);
|
||||||
block gen_condbranch(block iftrue, block iffalse);
|
block gen_condbranch(block iftrue, block iffalse);
|
||||||
block gen_and(block a, block b);
|
block gen_and(block a, block b);
|
||||||
|
|||||||
@@ -298,34 +298,6 @@ jv jq_next() {
|
|||||||
break;
|
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: {
|
case INDEX: {
|
||||||
stackval t = stack_pop();
|
stackval t = stack_pop();
|
||||||
jv k = stack_pop().value;
|
jv k = stack_pop().value;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ OP(APPEND, NONE, 2, 1)
|
|||||||
OP(INSERT, NONE, 4, 2)
|
OP(INSERT, NONE, 4, 2)
|
||||||
|
|
||||||
OP(GETPATH, NONE, 2, 1)
|
OP(GETPATH, NONE, 2, 1)
|
||||||
OP(ASSIGN, VARIABLE, 3, 0)
|
|
||||||
|
|
||||||
OP(CALL_BUILTIN, CFUNC, -1, 1)
|
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)))));
|
return BLOCK(a, gen_call("format", BLOCK(gen_lambda(gen_const(fmt)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static block gen_update(block a, block op, int optype) {
|
static block gen_update(block object, block val, int optype) {
|
||||||
if (optype) {
|
block tmp = block_bind(gen_op_var_unbound(STOREV, "tmp"),
|
||||||
op = gen_binop(gen_noop(), op, optype);
|
gen_noop(), OP_HAS_VARIABLE);
|
||||||
}
|
return BLOCK(gen_op_simple(DUP),
|
||||||
return gen_assign(BLOCK(a, gen_op_simple(DUP), op));
|
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 {
|
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 "or" Exp {
|
||||||
@@ -236,7 +241,7 @@ Exp "//=" Exp {
|
|||||||
} |
|
} |
|
||||||
|
|
||||||
Exp "|=" Exp {
|
Exp "|=" Exp {
|
||||||
$$ = gen_update($1, $3, 0);
|
$$ = gen_call("_modify", BLOCK(gen_lambda($1), gen_lambda($3)));
|
||||||
} |
|
} |
|
||||||
|
|
||||||
Exp '|' Exp {
|
Exp '|' Exp {
|
||||||
|
|||||||
Reference in new issue
Block a user