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:
Stephen Dolan committed 2012-12-29 16:43:36 +00:00
1 parent 465a4ec565
commit d5fdf70434
7 files changed
+19 -53

No files matched your search

+3
View File
@@ -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));",
}; };
-16
View File
@@ -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"),
-1
View File
@@ -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);
-28
View File
@@ -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;
-1
View File
@@ -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)
+12 -7
View File
@@ -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 {
+4
View File
@@ -411,6 +411,10 @@ null
[-1,1,3] [-1,1,3]
[0.5, 1.5, 2.5] [0.5, 1.5, 2.5]
.foo += .foo
{"foo":2}
{"foo":4}
.[0].a |= {"old":., "new":(.+1)} .[0].a |= {"old":., "new":(.+1)}
[{"a":1,"b":2}] [{"a":1,"b":2}]
[{"a":{"old":1, "new":2},"b":2}] [{"a":{"old":1, "new":2},"b":2}]