fix: make last(empty) yield no output values (#3179)

This commit is contained in:
itchyny authored and GitHub committed 2024-11-13 20:35:50 +09:00
1 parent 3c5707f7fb
commit a7b22539a4
6 files changed
+46 -4

No files matched your search

+4 -1
View File
@@ -3069,9 +3069,12 @@ sections:
Note that `nth(n; expr)` doesn't support negative values of `n`. Note that `nth(n; expr)` doesn't support negative values of `n`.
examples: examples:
- program: '[first(range(.)), last(range(.)), nth(./2; range(.))]' - program: '[first(range(.)), last(range(.)), nth(5; range(.))]'
input: '10' input: '10'
output: ['[0,9,5]'] output: ['[0,9,5]']
- program: '[first(empty), last(empty), nth(5; empty)]'
input: 'null'
output: ['[]']
- title: "`first`, `last`, `nth(n)`" - title: "`first`, `last`, `nth(n)`"
body: | body: |
Generated
+5 -1
View File
@@ -3475,9 +3475,13 @@ The \fBnth(n; expr)\fR function extracts the nth value output by \fBexpr\fR\. No
. .
.nf .nf
jq \'[first(range(\.)), last(range(\.)), nth(\./2; range(\.))]\' jq \'[first(range(\.)), last(range(\.)), nth(5; range(\.))]\'
10 10
=> [0,9,5] => [0,9,5]
jq \'[first(empty), last(empty), nth(5; empty)]\'
null
=> []
. .
.fi .fi
. .
+28
View File
@@ -1879,6 +1879,33 @@ BINOPS
#undef LIBM_DD #undef LIBM_DD
#undef LIBM_DA #undef LIBM_DA
// This is a hack to make last(g) yield no output values,
// if g yields no output values, without using boxing.
static block gen_last_1() {
block last_var = gen_op_var_fresh(STOREV, "last");
block is_empty_var = gen_op_var_fresh(STOREV, "is_empty");
block init = BLOCK(gen_op_simple(DUP),
gen_const(jv_null()),
last_var,
gen_op_simple(DUP),
gen_const(jv_true()),
is_empty_var);
block call_arg = BLOCK(gen_call("arg", gen_noop()),
gen_op_simple(DUP),
gen_op_bound(STOREV, last_var),
gen_const(jv_false()),
gen_op_bound(STOREV, is_empty_var),
gen_op_simple(BACKTRACK));
block if_empty = gen_op_simple(BACKTRACK);
return BLOCK(init,
gen_op_target(FORK, call_arg),
call_arg,
BLOCK(gen_op_bound(LOADVN, is_empty_var),
gen_op_target(JUMP_F, if_empty),
if_empty,
gen_op_bound(LOADVN, last_var)));
}
struct bytecoded_builtin { const char* name; block code; }; struct bytecoded_builtin { const char* name; block code; };
static block bind_bytecoded_builtins(block b) { static block bind_bytecoded_builtins(block b) {
block builtins = gen_noop(); block builtins = gen_noop();
@@ -1898,6 +1925,7 @@ static block bind_bytecoded_builtins(block b) {
{"path", BLOCK(gen_op_simple(PATH_BEGIN), {"path", BLOCK(gen_op_simple(PATH_BEGIN),
gen_call("arg", gen_noop()), gen_call("arg", gen_noop()),
gen_op_simple(PATH_END))}, gen_op_simple(PATH_END))},
{"last", gen_last_1()},
}; };
for (unsigned i=0; i<sizeof(builtin_def_1arg)/sizeof(builtin_def_1arg[0]); i++) { for (unsigned i=0; i<sizeof(builtin_def_1arg)/sizeof(builtin_def_1arg[0]); i++) {
builtins = BLOCK(builtins, gen_function(builtin_def_1arg[i].name, builtins = BLOCK(builtins, gen_function(builtin_def_1arg[i].name,
-1
View File
@@ -170,7 +170,6 @@ def all(condition): all(.[]; condition);
def any(condition): any(.[]; condition); def any(condition): any(.[]; condition);
def all: all(.[]; .); def all: all(.[]; .);
def any: any(.[]; .); def any: any(.[]; .);
def last(g): reduce g as $item (null; $item);
def nth($n; g): def nth($n; g):
if $n < 0 then error("nth doesn't support negative indices") if $n < 0 then error("nth doesn't support negative indices")
else first(skip($n; g)) end; else first(skip($n; g)) end;
+4
View File
@@ -362,6 +362,10 @@ null
10 10
[0,9] [0,9]
[first(range(.)), last(range(.))]
0
[]
[nth(0,5,9,10,15; range(.)), try nth(-1; range(.)) catch .] [nth(0,5,9,10,15; range(.)), try nth(-1; range(.)) catch .]
10 10
[0,5,9,"nth doesn't support negative indices"] [0,5,9,"nth doesn't support negative indices"]
+5 -1
View File
@@ -881,10 +881,14 @@ false
[0,1,2,3,4,5,6,7,8,9] [0,1,2,3,4,5,6,7,8,9]
[3,4,5,6,7,8,9] [3,4,5,6,7,8,9]
[first(range(.)), last(range(.)), nth(./2; range(.))] [first(range(.)), last(range(.)), nth(5; range(.))]
10 10
[0,9,5] [0,9,5]
[first(empty), last(empty), nth(5; empty)]
null
[]
[range(.)]|[first, last, nth(5)] [range(.)]|[first, last, nth(5)]
10 10
[0,9,5] [0,9,5]