mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Add the range function
This commit is contained in:
12
builtin.c
12
builtin.c
@@ -530,6 +530,18 @@ static block bind_bytecoded_builtins(block b) {
|
|||||||
builtin_def_1arg[i].code));
|
builtin_def_1arg[i].code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
block rangevar = block_bind(gen_op_var_unbound(STOREV, "rangevar"),
|
||||||
|
gen_noop(), OP_HAS_VARIABLE);
|
||||||
|
block init = BLOCK(gen_op_simple(DUP), gen_call("start", gen_noop()), rangevar);
|
||||||
|
block range = BLOCK(init,
|
||||||
|
gen_call("end", gen_noop()),
|
||||||
|
gen_op_var_bound(RANGE, rangevar));
|
||||||
|
builtins = BLOCK(builtins, gen_function("range",
|
||||||
|
BLOCK(gen_op_block_unbound(CLOSURE_PARAM, "start"),
|
||||||
|
gen_op_block_unbound(CLOSURE_PARAM, "end")),
|
||||||
|
range));
|
||||||
|
}
|
||||||
|
|
||||||
return block_bind(builtins, b, OP_IS_CALL_PSEUDO);
|
return block_bind(builtins, b, OP_IS_CALL_PSEUDO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -589,6 +589,22 @@ sections:
|
|||||||
input: '[]'
|
input: '[]'
|
||||||
output: ["null"]
|
output: ["null"]
|
||||||
|
|
||||||
|
- title: `range`
|
||||||
|
body: |
|
||||||
|
|
||||||
|
The `range` function produces a range of numbers. `range(4;10)`
|
||||||
|
produces 6 numbers, from 4 (inclusive) to 10 (exclusive). The numbers
|
||||||
|
are produced as separate outputs. Use `[range(4;10)]` to get a range as
|
||||||
|
an array.
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- program: 'range(2;4)'
|
||||||
|
input: 'null'
|
||||||
|
output: ['2', '3']
|
||||||
|
- program: '[range(2;4)]'
|
||||||
|
input: 'null'
|
||||||
|
output: ['[2,3]']
|
||||||
|
|
||||||
- title: `tonumber`
|
- title: `tonumber`
|
||||||
body: |
|
body: |
|
||||||
|
|
||||||
|
|||||||
27
execute.c
27
execute.c
@@ -266,6 +266,33 @@ jv jq_next(jq_state *jq) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ON_BACKTRACK(RANGE):
|
||||||
|
case RANGE: {
|
||||||
|
uint16_t level = *pc++;
|
||||||
|
uint16_t v = *pc++;
|
||||||
|
frame_ptr fp = frame_get_level(&jq->frame_stk, frame_current(&jq->frame_stk), level);
|
||||||
|
jv* var = frame_local_var(fp, v);
|
||||||
|
jv max = stack_pop(jq);
|
||||||
|
if (jv_get_kind(*var) != JV_KIND_NUMBER ||
|
||||||
|
jv_get_kind(max) != JV_KIND_NUMBER) {
|
||||||
|
print_error(jv_invalid_with_msg(jv_string_fmt("Range bounds must be numeric")));
|
||||||
|
jv_free(max);
|
||||||
|
goto do_backtrack;
|
||||||
|
} else if (jv_number_value(jv_copy(*var)) >= jv_number_value(jv_copy(max))) {
|
||||||
|
/* finished iterating */
|
||||||
|
goto do_backtrack;
|
||||||
|
} else {
|
||||||
|
jv curr = jv_copy(*var);
|
||||||
|
*var = jv_number(jv_number_value(*var) + 1);
|
||||||
|
|
||||||
|
stack_save(jq, pc - 3);
|
||||||
|
stack_push(jq, jv_copy(max));
|
||||||
|
stack_switch(jq);
|
||||||
|
stack_push(jq, curr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: loadv/storev may do too much copying/freeing
|
// FIXME: loadv/storev may do too much copying/freeing
|
||||||
case LOADV: {
|
case LOADV: {
|
||||||
uint16_t level = *pc++;
|
uint16_t level = *pc++;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ OP(JUMP_F,BRANCH, 1, 0)
|
|||||||
OP(BACKTRACK, NONE, 0, 0)
|
OP(BACKTRACK, NONE, 0, 0)
|
||||||
OP(APPEND, VARIABLE,1, 0)
|
OP(APPEND, VARIABLE,1, 0)
|
||||||
OP(INSERT, NONE, 4, 2)
|
OP(INSERT, NONE, 4, 2)
|
||||||
|
OP(RANGE, VARIABLE, 1, 1)
|
||||||
|
|
||||||
OP(SUBEXP_BEGIN, NONE, 1, 2)
|
OP(SUBEXP_BEGIN, NONE, 1, 2)
|
||||||
OP(SUBEXP_END, NONE, 2, 2)
|
OP(SUBEXP_END, NONE, 2, 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user