1
0
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:
Stephen Dolan
2013-05-14 16:09:10 +01:00
parent 4d540b7102
commit 81be37b236
4 changed files with 56 additions and 0 deletions

View File

@@ -530,6 +530,18 @@ static block bind_bytecoded_builtins(block b) {
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);
}

View File

@@ -589,6 +589,22 @@ sections:
input: '[]'
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`
body: |

View File

@@ -266,6 +266,33 @@ jv jq_next(jq_state *jq) {
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
case LOADV: {
uint16_t level = *pc++;

View File

@@ -13,6 +13,7 @@ OP(JUMP_F,BRANCH, 1, 0)
OP(BACKTRACK, NONE, 0, 0)
OP(APPEND, VARIABLE,1, 0)
OP(INSERT, NONE, 4, 2)
OP(RANGE, VARIABLE, 1, 1)
OP(SUBEXP_BEGIN, NONE, 1, 2)
OP(SUBEXP_END, NONE, 2, 2)