diff --git a/go.mod b/go.mod index 5a0ddc16d0..d56934853c 100644 --- a/go.mod +++ b/go.mod @@ -95,8 +95,8 @@ require ( github.com/gorilla/css v1.0.1 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/itchyny/gojq v0.12.9 // indirect - github.com/itchyny/timefmt-go v0.1.4 // indirect + github.com/itchyny/gojq v0.12.17 // indirect + github.com/itchyny/timefmt-go v0.1.6 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.14.3 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -109,7 +109,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.7 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect diff --git a/go.sum b/go.sum index 9ab2cb877d..9348759f37 100644 --- a/go.sum +++ b/go.sum @@ -157,10 +157,10 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/itchyny/gojq v0.12.9 h1:biKpbKwMxVYhCU1d6mR7qMr3f0Hn9F5k5YykCVb3gmM= -github.com/itchyny/gojq v0.12.9/go.mod h1:T4Ip7AETUXeGpD+436m+UEl3m3tokRgajd5pRfsR5oE= -github.com/itchyny/timefmt-go v0.1.4 h1:hFEfWVdwsEi+CY8xY2FtgWHGQaBaC3JeHd+cve0ynVM= -github.com/itchyny/timefmt-go v0.1.4/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= +github.com/itchyny/gojq v0.12.17 h1:8av8eGduDb5+rvEdaOO+zQUjA04MS0m3Ps8HiD+fceg= +github.com/itchyny/gojq v0.12.17/go.mod h1:WBrEMkgAfAGO1LUcGOckBl5O726KPp+OlkKug0I/FEY= +github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= +github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -251,8 +251,8 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -419,8 +419,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= diff --git a/vendor/github.com/itchyny/gojq/.dockerignore b/vendor/github.com/itchyny/gojq/.dockerignore index c8e02dc8f5..54095155cc 100644 --- a/vendor/github.com/itchyny/gojq/.dockerignore +++ b/vendor/github.com/itchyny/gojq/.dockerignore @@ -1,9 +1,16 @@ /gojq /goxz /CREDITS -/._* /y.output *.exe *.test *.out -/.github/ +*.md +*.y +**/*.jq +**/*.json +**/*.yaml +**/*_test.go +.github +_gojq +_tools diff --git a/vendor/github.com/itchyny/gojq/.gitattributes b/vendor/github.com/itchyny/gojq/.gitattributes index 9c2075be6e..797f395939 100644 --- a/vendor/github.com/itchyny/gojq/.gitattributes +++ b/vendor/github.com/itchyny/gojq/.gitattributes @@ -1,2 +1,3 @@ **/testdata/** binary -/builtin.go eol=lf +/builtin.go eol=lf linguist-generated=true +/parser.go eol=lf linguist-generated=true diff --git a/vendor/github.com/itchyny/gojq/.gitignore b/vendor/github.com/itchyny/gojq/.gitignore index e350f9308d..bbeb991f8c 100644 --- a/vendor/github.com/itchyny/gojq/.gitignore +++ b/vendor/github.com/itchyny/gojq/.gitignore @@ -1,7 +1,6 @@ /gojq /goxz /CREDITS -/._* /y.output *.exe *.test diff --git a/vendor/github.com/itchyny/gojq/CHANGELOG.md b/vendor/github.com/itchyny/gojq/CHANGELOG.md index 39e5a49aa6..a10c4858d1 100644 --- a/vendor/github.com/itchyny/gojq/CHANGELOG.md +++ b/vendor/github.com/itchyny/gojq/CHANGELOG.md @@ -1,4 +1,74 @@ # Changelog +## [v0.12.17](https://github.com/itchyny/gojq/compare/v0.12.16..v0.12.17) (2024-12-01) +* implement `add/1`, `skip/2` functions +* implement `--library-path` option as the alias of `-L` option +* fix `reduce` syntax to emit results for each initial value +* fix `last/1` to yield no values when the argument yields no values +* fix `limit/2` to emit an error on negative count +* fix `@uri` and `@urid` formats not to convert space between plus sign +* fix resolving search paths of import statements in the query +* improve time functions to accept fewer element arrays + +## [v0.12.16](https://github.com/itchyny/gojq/compare/v0.12.15..v0.12.16) (2024-06-01) +* fix offset of query parsing error on multi-byte characters +* fix tests of `exp10` and `atan2` failing on some platforms +* fix `debug/1` to be available only when `debug/0` is defined +* improve parser to allow binary operators as object values +* improve compiler to emit error if query is missing + +## [v0.12.15](https://github.com/itchyny/gojq/compare/v0.12.14..v0.12.15) (2024-04-01) +* implement `ltrim`, `rtrim`, and `trim` functions +* implement `gojq.ParseError` for getting the offset and token of query parsing error +* implement `gojq.HaltError` for detecting halt errors and stopping outer iteration +* fix object construction with duplicate keys (`{x:0,y:1} | {a:.x,a:.y}`) +* fix `halt` and `halt_error` functions to stop the command execution immediately +* fix variable scope of binding syntax (`"a" as $v | def f: $v; "b" as $v | f`) +* fix pre-defined variables to be available in initial modules (`$ARGS` in `~/.jq`) +* fix `ltrimstr` and `rtrimstr` functions to emit error on non-string input +* fix `nearbyint` and `rint` functions to round ties to even +* improve parser to allow `reduce`, `foreach`, `if`, `try`-`catch` syntax as object values +* remove `pow10` in favor of `exp10`, define `scalbn` and `scalbln` by `ldexp` + +## [v0.12.14](https://github.com/itchyny/gojq/compare/v0.12.13..v0.12.14) (2023-12-01) +* implement `abs`, `pick`, and `debug/1` functions +* implement `--raw-output0` option, and remove `--nul-output` (`-0`) option +* fix string multiplication by zero to emit an empty string +* fix zero divided by zero to emit an error, not `nan` +* fix modulo operator to emit `nan` if either side is `nan` +* fix `implode` function to emit replacement characters on invalid code points +* fix `stderr` function to output strings in raw format +* fix `error` function to throw an error even for `null` +* fix `walk` function on multiple outputs arguments +* fix `--from-file` option to work with `--args` and `--jsonargs` options +* fix the default module search path `../lib` relative to the executable +* improve query parser to support comment continuation with backslash +* improve `modulemeta` function to include defined function names in the module +* improve search path of `import` and `include` directives to support `$ORIGIN` expansion +* remove deprecated `leaf_paths` function + +## [v0.12.13](https://github.com/itchyny/gojq/compare/v0.12.12..v0.12.13) (2023-06-01) +* implement `@urid` format string to decode URI values +* fix functions returning arrays not to emit nil slices (`flatten`, `group_by`, + `unique`, `unique_by`, `nth`, `indices`, `path`, and `modulemeta.deps`) + +## [v0.12.12](https://github.com/itchyny/gojq/compare/v0.12.11..v0.12.12) (2023-03-01) +* fix assignment operator (`=`) with overlapping paths and multiple values (`[[]] | .. = ..`) +* fix crash on multiplying large numbers to an empty string (`9223372036854775807 * ""`) +* improve zsh completion file + +## [v0.12.11](https://github.com/itchyny/gojq/compare/v0.12.10..v0.12.11) (2022-12-24) +* fix crash on assignment operator (`=`) with multiple values (`. = (0,0)`) +* fix `isnormal` and `normals` functions against subnormal numbers + +## [v0.12.10](https://github.com/itchyny/gojq/compare/v0.12.9..v0.12.10) (2022-12-01) +* fix `break` in `try`-`catch` query (`label $x | try break $x catch .`) +* fix path value validation for `getpath` function (`path(getpath([[0]][0]))`) +* fix path value validation for custom iterator functions +* fix `walk` function with argument emitting multiple values (`[1],{x:1} | walk(.,0)`) +* fix `@csv`, `@tsv`, `@sh` to escape the null character (`["\u0000"] | @csv,@tsv,@sh`) +* improve performance of assignment operator (`=`), update-assignment operator (`|=`), + `map_values`, `del`, `delpaths`, `walk`, `ascii_downcase`, and `ascii_upcase` functions + ## [v0.12.9](https://github.com/itchyny/gojq/compare/v0.12.8..v0.12.9) (2022-09-01) * fix `fromjson` to emit error on unexpected trailing string * fix path analyzer on variable argument evaluation (`def f($x): .y; path(f(.x))`) @@ -216,7 +286,7 @@ ## [v0.7.0](https://github.com/itchyny/gojq/compare/v0.6.0..v0.7.0) (2019-12-22) * implement YAML input (`--yaml-input`) and output (`--yaml-output`) * fix pipe in object value -* fix precedence of if, try, reduce and foreach expressions +* fix precedence of `if`, `try`, `reduce` and `foreach` expressions * release from GitHub Actions ## [v0.6.0](https://github.com/itchyny/gojq/compare/v0.5.0..v0.6.0) (2019-08-26) diff --git a/vendor/github.com/itchyny/gojq/Dockerfile b/vendor/github.com/itchyny/gojq/Dockerfile index 284ece7762..96a14e99a5 100644 --- a/vendor/github.com/itchyny/gojq/Dockerfile +++ b/vendor/github.com/itchyny/gojq/Dockerfile @@ -1,8 +1,10 @@ -FROM golang:1.19 AS builder +FROM golang:1.23 AS builder WORKDIR /app +COPY go.* ./ +RUN go mod download COPY . . -ENV CGO_ENABLED 0 +ENV CGO_ENABLED=0 RUN make build FROM gcr.io/distroless/static:debug diff --git a/vendor/github.com/itchyny/gojq/LICENSE b/vendor/github.com/itchyny/gojq/LICENSE index e3fc027c0e..fe59004071 100644 --- a/vendor/github.com/itchyny/gojq/LICENSE +++ b/vendor/github.com/itchyny/gojq/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2019-2022 itchyny +Copyright (c) 2019-2024 itchyny Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/itchyny/gojq/Makefile b/vendor/github.com/itchyny/gojq/Makefile index 04c2d7a707..15ace7d738 100644 --- a/vendor/github.com/itchyny/gojq/Makefile +++ b/vendor/github.com/itchyny/gojq/Makefile @@ -33,15 +33,15 @@ $(GOBIN)/goyacc: .PHONY: install install: - go install -ldflags=$(BUILD_LDFLAGS) ./... + go install -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN) .PHONY: install-dev install-dev: parser.go builtin.go - go install -ldflags=$(BUILD_LDFLAGS) ./... + go install -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN) .PHONY: install-debug install-debug: parser.go builtin.go - go install -tags gojq_debug -ldflags=$(BUILD_LDFLAGS) ./... + go install -tags gojq_debug -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN) .PHONY: show-version show-version: $(GOBIN)/gobump @@ -89,9 +89,9 @@ clean: .PHONY: update update: export GOPROXY=direct update: - go get -u -d ./... && go mod tidy + go get -u ./... && go mod tidy go mod edit -modfile=go.dev.mod -droprequire=github.com/itchyny/{astgen,timefmt}-go - go get -u -d -modfile=go.dev.mod github.com/itchyny/{astgen,timefmt}-go && go generate + go get -u -modfile=go.dev.mod github.com/itchyny/{astgen,timefmt}-go && go generate .PHONY: bump bump: $(GOBIN)/gobump @@ -101,10 +101,3 @@ bump: $(GOBIN)/gobump git commit -am "bump up version to $(VERSION)" git tag "v$(VERSION)" git push --atomic origin main tag "v$(VERSION)" - -.PHONY: upload -upload: $(GOBIN)/ghr - ghr "v$(VERSION)" goxz - -$(GOBIN)/ghr: - go install github.com/tcnksm/ghr@latest diff --git a/vendor/github.com/itchyny/gojq/README.md b/vendor/github.com/itchyny/gojq/README.md index dacec5a931..7b34f93c34 100644 --- a/vendor/github.com/itchyny/gojq/README.md +++ b/vendor/github.com/itchyny/gojq/README.md @@ -1,11 +1,11 @@ # gojq -[![CI Status](https://github.com/itchyny/gojq/workflows/CI/badge.svg)](https://github.com/itchyny/gojq/actions) +[![CI Status](https://github.com/itchyny/gojq/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/itchyny/gojq/actions?query=branch:main) [![Go Report Card](https://goreportcard.com/badge/github.com/itchyny/gojq)](https://goreportcard.com/report/github.com/itchyny/gojq) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/gojq/blob/main/LICENSE) [![release](https://img.shields.io/github/release/itchyny/gojq/all.svg)](https://github.com/itchyny/gojq/releases) [![pkg.go.dev](https://pkg.go.dev/badge/github.com/itchyny/gojq)](https://pkg.go.dev/github.com/itchyny/gojq) -### Pure Go implementation of [jq](https://github.com/stedolan/jq) +### Pure Go implementation of [jq](https://github.com/jqlang/jq) This is an implementation of jq command written in Go language. You can also embed gojq as a library to your Go products. @@ -77,10 +77,9 @@ docker run -i --rm ghcr.io/itchyny/gojq - gojq implements nice error messages for invalid query and JSON input. The error message of jq is sometimes difficult to tell where to fix the query. - gojq does not keep the order of object keys. I understand this might cause problems for some scripts but basically, we should not rely on the order of object keys. Due to this limitation, gojq does not have `keys_unsorted` function and `--sort-keys` (`-S`) option. I would implement when ordered map is implemented in the standard library of Go but I'm less motivated. - gojq supports arbitrary-precision integer calculation while jq does not; jq loses the precision of large integers when calculation is involved. Note that even with gojq, all mathematical functions, including `floor` and `round`, convert integers to floating-point numbers; only addition, subtraction, multiplication, modulo, and division operators (when divisible) keep the integer precision. To calculate floor division of integers without losing the precision, use `def idivide($n): (. - . % $n) / $n;`. To round down floating-point numbers to integers, use `def ifloor: floor | tostring | tonumber;`, but note that this function does not work with large floating-point numbers and also loses the precision of large integers. -- gojq fixes various bugs of jq. gojq correctly deletes elements of arrays by `|= empty` ([jq#2051](https://github.com/stedolan/jq/issues/2051)). gojq fixes `try`/`catch` handling ([jq#1859](https://github.com/stedolan/jq/issues/1859), [jq#1885](https://github.com/stedolan/jq/issues/1885), [jq#2140](https://github.com/stedolan/jq/issues/2140)). gojq fixes `nth/2` to output nothing when the count is equal to or larger than the stream size ([jq#1867](https://github.com/stedolan/jq/issues/1867)). gojq consistently counts by characters (not by bytes) in `index`, `rindex`, and `indices` functions; `"12345" | .[index("3"):]` results in `"345"` ([jq#1430](https://github.com/stedolan/jq/issues/1430), [jq#1624](https://github.com/stedolan/jq/issues/1624)). gojq handles overlapping occurrence differently in `rindex` and `indices`; `"ababa" | [rindex("aba"), indices("aba")]` results in `[2,[0,2]]` ([jq#2433](https://github.com/stedolan/jq/issues/2433)). gojq supports string indexing; `"abcde"[2]` ([jq#1520](https://github.com/stedolan/jq/issues/1520)). gojq accepts indexing query `.e0` ([jq#1526](https://github.com/stedolan/jq/issues/1526), [jq#1651](https://github.com/stedolan/jq/issues/1651)), and allows `gsub` to handle patterns including `"^"` ([jq#2148](https://github.com/stedolan/jq/issues/2148)). gojq improves variable lexer to allow using keywords for variable names, especially in binding patterns, also disallows spaces after `$` ([jq#526](https://github.com/stedolan/jq/issues/526)). gojq fixes handling files with no newline characters at the end ([jq#2374](https://github.com/stedolan/jq/issues/2374)). -- gojq implements `@uri` to escape all the reserved characters defined in RFC 3986, Sec. 2.2 ([jq#1506](https://github.com/stedolan/jq/issues/1506)), and fixes `@base64d` to allow binary string as the decoded string ([jq#1931](https://github.com/stedolan/jq/issues/1931)). gojq improves time formatting and parsing; deals with `%f` in `strftime` and `strptime` ([jq#1409](https://github.com/stedolan/jq/issues/1409)), parses timezone offsets with `fromdate` and `fromdateiso8601` ([jq#1053](https://github.com/stedolan/jq/issues/1053)), supports timezone name/offset with `%Z`/`%z` in `strptime` ([jq#929](https://github.com/stedolan/jq/issues/929), [jq#2195](https://github.com/stedolan/jq/issues/2195)), and looks up correct timezone during daylight saving time on formatting with `%Z` ([jq#1912](https://github.com/stedolan/jq/issues/1912)). gojq supports nanoseconds in date and time functions. -- gojq does not support some functions intentionally; `get_jq_origin`, `get_prog_origin`, `get_search_list` (unstable, not listed in jq document), `input_line_number`, `$__loc__` (performance issue), `recurse_down` (deprecated in jq). gojq does not support some flags; `--ascii-output, -a` (performance issue), `--seq` (not used commonly), `--sort-keys, -S` (sorts by default because `map[string]interface{}` does not keep the order), `--unbuffered` (unbuffered by default). gojq does not parse JSON extensions supported by jq; `NaN`, `Infinity`, and `[000]`. gojq normalizes floating-point numbers to fit to double-precision floating-point numbers. gojq does not support some regular expression flags (regular expression engine differences). gojq does not support BOM (`encoding/json` does not support this). gojq disallows using keywords for function names (declaration of `def true: .;` is a confusing query). -- gojq supports reading from YAML input (`--yaml-input`) while jq does not. gojq also supports YAML output (`--yaml-output`). +- gojq behaves differently than jq in some features, hoping that jq will fix the behaviors in the future. gojq consistently counts by characters (not by bytes) in `index`, `rindex`, and `indices` functions; `"12345" | .[index("3"):]` results in `"345"` ([jq#1430](https://github.com/jqlang/jq/issues/1430), [jq#1624](https://github.com/jqlang/jq/issues/1624)). gojq supports string indexing; `"abcde"[2]` ([jq#1520](https://github.com/jqlang/jq/issues/1520)). gojq fixes handling files with no newline characters at the end ([jq#2374](https://github.com/jqlang/jq/issues/2374)). gojq consistently truncates down floating-point number indices both in indexing (`[0] | .[0.5]` results in `0`), and slicing (`[0,1,2] | .[0.5:1.5]` results in `[0]`). gojq parses unary operators with higher precedence than variable binding (`[-1 as $x | 1,$x]` results in `[1,-1]` not `[-1,-1]`) ([jq#3053](https://github.com/jqlang/jq/pull/3053)). gojq fixes `@base64d` to allow binary string as the decoded string ([jq#1931](https://github.com/jqlang/jq/issues/1931)). gojq improves time formatting and parsing; deals with `%f` in `strftime` and `strptime` ([jq#1409](https://github.com/jqlang/jq/issues/1409)), parses timezone offsets with `fromdate` and `fromdateiso8601` ([jq#1053](https://github.com/jqlang/jq/issues/1053)), supports timezone name/offset with `%Z`/`%z` in `strptime` ([jq#929](https://github.com/jqlang/jq/issues/929), [jq#2195](https://github.com/jqlang/jq/issues/2195)), and looks up correct timezone during daylight saving time on formatting with `%Z` ([jq#1912](https://github.com/jqlang/jq/issues/1912)). gojq supports nanoseconds in date and time functions. +- gojq does not support some functions intentionally; `get_jq_origin`, `get_prog_origin`, `get_search_list` (unstable, not listed in jq document), `input_line_number`, `$__loc__` (performance issue). gojq does not support some flags; `--ascii-output, -a` (performance issue), `--seq` (not used commonly), `--sort-keys, -S` (sorts by default because `map[string]any` does not keep the order), `--unbuffered` (unbuffered by default). gojq does not parse JSON extensions supported by jq; `NaN`, `Infinity`, and `[000]`. gojq normalizes floating-point numbers to fit to double-precision floating-point numbers. gojq does not support some regular expression metacharacters, backreferences, look-around assertions, and some flags (regular expression engine differences). gojq does not support BOM (`encoding/json` does not support this). gojq disallows using keywords for function names (`def true: .; true` is a confusing query), and module name prefixes in function declarations (using module prefixes like `def m::f: .;` is undocumented). +- gojq supports reading from YAML input (`--yaml-input`) while jq does not. gojq also supports YAML output (`--yaml-output`). gojq supports `@urid` format string ([jq#798](https://github.com/jqlang/jq/issues/798), [jq#2261](https://github.com/jqlang/jq/issues/2261)). ### Color configuration The gojq command automatically disables coloring output when the output is not a tty. @@ -109,7 +108,7 @@ func main() { if err != nil { log.Fatalln(err) } - input := map[string]interface{}{"foo": []interface{}{1, 2, 3}} + input := map[string]any{"foo": []any{1, 2, 3}} iter := query.Run(input) // or query.RunWithContext for { v, ok := iter.Next() @@ -117,6 +116,9 @@ func main() { break } if err, ok := v.(error); ok { + if err, ok := err.(*gojq.HaltError); ok && err.Value() == nil { + break + } log.Fatalln(err) } fmt.Printf("%#v\n", v) @@ -125,12 +127,18 @@ func main() { ``` - Firstly, use [`gojq.Parse(string) (*Query, error)`](https://pkg.go.dev/github.com/itchyny/gojq#Parse) to get the query from a string. + - Use [`gojq.ParseError`](https://pkg.go.dev/github.com/itchyny/gojq#ParseError) to get the error position and token of the parsing error. - Secondly, get the result iterator - using [`query.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Query.Run) or [`query.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Query.RunWithContext) - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query. But for arguments of `code.Run`, do not give values sharing same data between multiple calls. - - In either case, you cannot use custom type values as the query input. The type should be `[]interface{}` for an array and `map[string]interface{}` for a map (just like decoded to an `interface{}` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `interface{}` and use it as the query input. -- Thirdly, iterate through the results using [`iter.Next() (interface{}, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates. - - The return type is not `(interface{}, error)` because iterators can emit multiple errors and you can continue after an error. It is difficult for the iterator to tell the termination in this situation. + - In either case, you cannot use custom type values as the query input. The type should be `[]any` for an array and `map[string]any` for a map (just like decoded to an `any` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `any` and use it as the query input. +- Thirdly, iterate through the results using [`iter.Next() (any, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates. + - The return type is not `(any, error)` because the iterator may emit multiple errors. The `jq` and `gojq` commands stop the iteration on the first error, but the library user can choose to stop the iteration on errors, or to continue until it terminates. + - In any case, it is recommended to stop the iteration on [`gojq.HaltError`](https://pkg.go.dev/github.com/itchyny/gojq#HaltError), which is emitted by `halt` and `halt_error` functions, although these functions are rarely used. + The error implements [`gojq.ValueError`](https://pkg.go.dev/github.com/itchyny/gojq#ValueError), and if the error value is `nil`, stop the iteration without handling the error. + Technically speaking, we can fix the iterator to terminate on the halting error, but it does not terminate at the moment. + The `halt` function in jq not only stops the iteration, but also terminates the command execution, even if there are still input values. + So, gojq leaves it up to the library user how to handle the halting error. - Note that the result iterator may emit infinite number of values; `repeat(0)` and `range(infinite)`. It may stuck with no output value; `def f: f; f`. Use `RunWithContext` when you want to limit the execution time. [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) allows to configure the following compiler options. @@ -146,7 +154,7 @@ func main() { Report bug at [Issues・itchyny/gojq - GitHub](https://github.com/itchyny/gojq/issues). ## Author -itchyny (https://github.com/itchyny) +itchyny () ## License This software is released under the MIT License, see LICENSE. diff --git a/vendor/github.com/itchyny/gojq/_gojq b/vendor/github.com/itchyny/gojq/_gojq index 4c94718ad8..2dc0033695 100644 --- a/vendor/github.com/itchyny/gojq/_gojq +++ b/vendor/github.com/itchyny/gojq/_gojq @@ -2,31 +2,42 @@ _gojq() { - _arguments -C \ - '(-c --compact-output)'{-c,--compact-output}'[compact output]' \ - '(-r --raw-output)'{-r,--raw-output}'[output raw strings]' \ - '(-j --join-output)'{-j,--join-output}'[stop printing a newline after each output]' \ - '(-0 --nul-output)'{-0,--nul-output}'[print NUL after each output]' \ - '(-C --color-output)'{-C,--color-output}'[colorize output even if piped]' \ - '(-M --monochrome-output)'{-M,--monochrome-output}'[stop colorizing output]' \ - '(--yaml-output)'--yaml-output'[output by YAML]' \ - '(--indent)'--indent'[number of spaces for indentation]:indentation count' \ - '(--tab)'--tab'[use tabs for indentation]' \ + _arguments -s -S \ + '(-r --raw-output --raw-output0 -j --join-output)'{-r,--raw-output}'[output raw strings]' \ + '(-r --raw-output -j --join-output)--raw-output0[implies -r with NUL character delimiter]' \ + '(-r --raw-output --raw-output0 -j --join-output)'{-j,--join-output}'[implies -r with no newline delimiter]' \ + '(-c --compact-output --indent --tab --yaml-output)'{-c,--compact-output}'[output without pretty-printing]' \ + '(-c --compact-output --tab --yaml-output)--indent[number of spaces for indentation]:indentation count:(2 4 8)' \ + '(-c --compact-output --indent --yaml-output)--tab[use tabs for indentation]' \ + '(-c --compact-output --indent --tab )--yaml-output[output in YAML format]' \ + '(-C --color-output -M --monochrome-output)'{-C,--color-output}'[output with colors even if piped]' \ + '(-C --color-output -M --monochrome-output)'{-M,--monochrome-output}'[output without colors]' \ '(-n --null-input)'{-n,--null-input}'[use null as input value]' \ - '(-R --raw-input)'{-R,--raw-input}'[read input as raw strings]' \ + '(-R --raw-input --stream --yaml-input)'{-R,--raw-input}'[read input as raw strings]' \ + '(-R --raw-input --yaml-input)--stream[parse input in stream fashion]' \ + '(-R --raw-input --stream )--yaml-input[read input as YAML format]' \ '(-s --slurp)'{-s,--slurp}'[read all inputs into an array]' \ - '(--stream)'--stream'[parse input in stream fashion]' \ - '(--yaml-input)'--yaml-input'[read input as YAML]' \ - '(-f --from-file)'{-f,--from-file}'[load query from file]:filename of jq query:_files' \ - '(-L)'-L'[directory to search modules from]:module directory:_directories' \ - '(--arg)'--arg'[set variable to string value]:variable name:' \ - '(--argjson)'--argjson'[set variable to JSON value]:variable name:' \ - '(--slurpfile)'--slurpfile'[set variable to the JSON contents of the file]:variable name:' \ - '(--rawfile)'--rawfile'[set variable to the contents of the file]:variable name:' \ - '(--args)'--args'[consume remaining arguments as positional string values]' \ - '(--jsonargs)'--jsonargs'[consume remaining arguments as positional JSON values]' \ + '(-f --from-file 1)'{-f,--from-file}'[load query from file]:filename of jq query:_files' \ + '*'{-L,--library-path}'[directory to search modules from]:module directory:_directories' \ + '*--arg[set a string value to a variable]:variable name: :string value' \ + '*--argjson[set a JSON value to a variable]:variable name: :JSON value' \ + '*--slurpfile[set the JSON contents of a file to a variable]:variable name: :JSON file:_files' \ + '*--rawfile[set the contents of a file to a variable]:variable name: :file:_files' \ + '*--args[consume remaining arguments as positional string values]' \ + '*--jsonargs[consume remaining arguments as positional JSON values]' \ '(-e --exit-status)'{-e,--exit-status}'[exit 1 when the last value is false or null]' \ - '(-v --version)'{-v,--version}'[print version]' \ - '(-h --help)'{-h,--help}'[print help]' \ - && ret=0 + '(- 1 *)'{-v,--version}'[display version information]' \ + '(- 1 *)'{-h,--help}'[display help information]' \ + '1: :_guard "^-([[:alpha:]0]#|-*)" "jq query"' \ + '*: :_gojq_args' +} + +_gojq_args() { + if (($words[(I)--args] > $words[(I)--jsonargs])); then + _message 'string value' + elif (($words[(I)--args] < $words[(I)--jsonargs])); then + _message 'JSON value' + else + _arguments '*:input file:_files' + fi } diff --git a/vendor/github.com/itchyny/gojq/builtin.go b/vendor/github.com/itchyny/gojq/builtin.go index a59795d458..8ae4666cba 100644 --- a/vendor/github.com/itchyny/gojq/builtin.go +++ b/vendor/github.com/itchyny/gojq/builtin.go @@ -4,67 +4,67 @@ package gojq func init() { builtinFuncDefs = map[string][]*FuncDef{ - "IN": []*FuncDef{&FuncDef{Name: "IN", Args: []string{"s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Left: &Query{Func: "s"}, Op: OpEq, Right: &Query{Func: "."}}, &Query{Func: "."}}}}}}, &FuncDef{Name: "IN", Args: []string{"src", "s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Left: &Query{Func: "src"}, Op: OpEq, Right: &Query{Func: "s"}}, &Query{Func: "."}}}}}}}, - "INDEX": []*FuncDef{&FuncDef{Name: "INDEX", Args: []string{"stream", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "stream"}}, Pattern: &Pattern{Name: "$row"}, Start: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Left: &Query{Func: "$row"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "idx_expr"}, Op: OpPipe, Right: &Query{Func: "tostring"}}}}}}, Op: OpAssign, Right: &Query{Func: "$row"}}}}}}, &FuncDef{Name: "INDEX", Args: []string{"idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "INDEX", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "idx_expr"}}}}}}}, - "JOIN": []*FuncDef{&FuncDef{Name: "JOIN", Args: []string{"$idx", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}}}}, &FuncDef{Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}, &FuncDef{Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr", "join_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "join_expr"}}}}}, - "_assign": []*FuncDef{&FuncDef{Name: "_assign", Args: []string{"ps", "$v"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: "ps"}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Func: "."}, Update: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Func: "$p"}, &Query{Func: "$v"}}}}}}}}}}, - "_modify": []*FuncDef{&FuncDef{Name: "_modify", Args: []string{"ps", "f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: "ps"}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}, Update: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpAdd, Right: &Query{Func: "$p"}}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$q"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Func: "$q"}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{&Query{Func: "$q"}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}}}}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$p"}}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}}}}}}}}}, - "all": []*FuncDef{&FuncDef{Name: "all", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{&Query{Func: "."}}}}}}, &FuncDef{Name: "all", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "y"}}}}}}, &FuncDef{Name: "all", Args: []string{"g", "y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{&Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "y"}, Op: OpPipe, Right: &Query{Func: "not"}}}}}}}}}}}}}, - "any": []*FuncDef{&FuncDef{Name: "any", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Func: "."}}}}}}, &FuncDef{Name: "any", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "y"}}}}}}, &FuncDef{Name: "any", Args: []string{"g", "y"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{&Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "y"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "not"}}}}, - "arrays": []*FuncDef{&FuncDef{Name: "arrays", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}}}}}}}, - "ascii_downcase": []*FuncDef{&FuncDef{Name: "ascii_downcase", Body: &Query{Left: &Query{Func: "explode"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeNumber, Number: "65"}}, Op: OpLe, Right: &Query{Func: "."}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "90"}}}}, Then: &Query{Left: &Query{Func: "."}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "32"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "implode"}}}}}, - "ascii_upcase": []*FuncDef{&FuncDef{Name: "ascii_upcase", Body: &Query{Left: &Query{Func: "explode"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeNumber, Number: "97"}}, Op: OpLe, Right: &Query{Func: "."}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "122"}}}}, Then: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "32"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "implode"}}}}}, - "booleans": []*FuncDef{&FuncDef{Name: "booleans", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "boolean"}}}}}}}}}}, - "capture": []*FuncDef{&FuncDef{Name: "capture", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "capture", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "capture", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Func: "_capture"}}}}, - "combinations": []*FuncDef{&FuncDef{Name: "combinations", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$x"}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}}}}}}}}}}}, &FuncDef{Name: "combinations", Args: []string{"n"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "limit", Args: []*Query{&Query{Func: "n"}, &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{&Query{Func: "."}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}, - "del": []*FuncDef{&FuncDef{Name: "del", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: "f"}}}}}}}}}}}}}}, - "finites": []*FuncDef{&FuncDef{Name: "finites", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "isfinite"}}}}}}}, - "first": []*FuncDef{&FuncDef{Name: "first", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}, &FuncDef{Name: "first", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}}, - "fromdate": []*FuncDef{&FuncDef{Name: "fromdate", Body: &Query{Func: "fromdateiso8601"}}}, - "fromdateiso8601": []*FuncDef{&FuncDef{Name: "fromdateiso8601", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strptime", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%S%z"}}}}}}}, Op: OpPipe, Right: &Query{Func: "mktime"}}}}, - "fromstream": []*FuncDef{&FuncDef{Name: "fromstream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "x", Val: &ObjectVal{Queries: []*Query{&Query{Func: "null"}}}}, &ObjectKeyVal{Key: "e", Val: &ObjectVal{Queries: []*Query{&Query{Func: "false"}}}}}}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$init"}}, Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}, Pattern: &Pattern{Name: "$i"}, Start: &Query{Func: "$init"}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Func: "$init"}, Else: &Query{Func: "."}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$i"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "2"}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "x"}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "x"}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}}, - "group_by": []*FuncDef{&FuncDef{Name: "group_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_group_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "gsub": []*FuncDef{&FuncDef{Name: "gsub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "str"}, &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, &FuncDef{Name: "gsub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "str"}, &Query{Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}}}, - "in": []*FuncDef{&FuncDef{Name: "in", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{&Query{Func: "$x"}}}}}}}}}}}}}, - "inputs": []*FuncDef{&FuncDef{Name: "inputs", Body: &Query{Term: &Term{Type: TermTypeTry, Try: &Try{Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{&Query{Func: "input"}}}}}, Catch: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "break"}}}}, Then: &Query{Func: "empty"}, Else: &Query{Func: "error"}}}}}}}}}, - "inside": []*FuncDef{&FuncDef{Name: "inside", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "contains", Args: []*Query{&Query{Func: "$x"}}}}}}}}}}}}}, - "isempty": []*FuncDef{&FuncDef{Name: "isempty", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "false"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}, Op: OpComma, Right: &Query{Func: "true"}}}}}}}, - "iterables": []*FuncDef{&FuncDef{Name: "iterables", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}}, - "last": []*FuncDef{&FuncDef{Name: "last", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}, &FuncDef{Name: "last", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "null"}, Update: &Query{Func: "$item"}}}}}}, - "leaf_paths": []*FuncDef{&FuncDef{Name: "leaf_paths", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "paths", Args: []*Query{&Query{Func: "scalars"}}}}}}}, - "limit": []*FuncDef{&FuncDef{Name: "limit", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Else: &Query{Func: "empty"}}}}}}}}}}}, Elif: []*IfElif{&IfElif{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "empty"}}}, Else: &Query{Func: "g"}}}}}}, - "map": []*FuncDef{&FuncDef{Name: "map", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}}, - "map_values": []*FuncDef{&FuncDef{Name: "map_values", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Op: OpModify, Right: &Query{Func: "f"}}}}, - "match": []*FuncDef{&FuncDef{Name: "match", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "match", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}, &Query{Func: "false"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}}}}, - "max_by": []*FuncDef{&FuncDef{Name: "max_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_max_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "min_by": []*FuncDef{&FuncDef{Name: "min_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_min_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "normals": []*FuncDef{&FuncDef{Name: "normals", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "isnormal"}}}}}}}, - "not": []*FuncDef{&FuncDef{Name: "not", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "."}, Then: &Query{Func: "false"}, Else: &Query{Func: "true"}}}}}}, - "nth": []*FuncDef{&FuncDef{Name: "nth", Args: []string{"$n"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}}}}}, &FuncDef{Name: "nth", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "nth doesn't support negative indices"}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Left: &Query{Func: "$n"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}}}, - "nulls": []*FuncDef{&FuncDef{Name: "nulls", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Func: "null"}}}}}}}}, - "numbers": []*FuncDef{&FuncDef{Name: "numbers", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "number"}}}}}}}}}}, - "objects": []*FuncDef{&FuncDef{Name: "objects", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}, - "paths": []*FuncDef{&FuncDef{Name: "paths", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: ".."}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}, &FuncDef{Name: "paths", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "paths"}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$p"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{&Query{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}, Op: OpPipe, Right: &Query{Func: "$p"}}}}}}}}}, - "range": []*FuncDef{&FuncDef{Name: "range", Args: []string{"$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{&Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, &Query{Func: "$end"}, &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, &FuncDef{Name: "range", Args: []string{"$start", "$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{&Query{Func: "$start"}, &Query{Func: "$end"}, &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, &FuncDef{Name: "range", Args: []string{"$start", "$end", "$step"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{&Query{Func: "$start"}, &Query{Func: "$end"}, &Query{Func: "$step"}}}}}}}, - "recurse": []*FuncDef{&FuncDef{Name: "recurse", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "recurse", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Optional: true}}}}}}}}}, &FuncDef{Name: "recurse", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}, Func: "r"}}, &FuncDef{Name: "recurse", Args: []string{"f", "cond"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "cond"}}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}}, Func: "r"}}}, - "repeat": []*FuncDef{&FuncDef{Name: "repeat", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_repeat", Body: &Query{Left: &Query{Func: "f"}, Op: OpComma, Right: &Query{Func: "_repeat"}}}}, Func: "_repeat"}}}, - "scalars": []*FuncDef{&FuncDef{Name: "scalars", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}}, - "scan": []*FuncDef{&FuncDef{Name: "scan", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "scan", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "scan", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Index: &Index{Name: "string"}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}}, - "select": []*FuncDef{&FuncDef{Name: "select", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "f"}, Then: &Query{Func: "."}, Else: &Query{Func: "empty"}}}}}}, - "sort_by": []*FuncDef{&FuncDef{Name: "sort_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_sort_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "splits": []*FuncDef{&FuncDef{Name: "splits", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "splits", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "split", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}}}}, - "strings": []*FuncDef{&FuncDef{Name: "strings", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}}}}}}, - "sub": []*FuncDef{&FuncDef{Name: "sub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "str"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "sub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$str"}}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_sub", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}, &Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$r"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "string", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$r"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "_capture"}, Op: OpPipe, Right: &Query{Func: "str"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "offset"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "length"}}}}}}, End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}}, &ObjectKeyVal{Key: "offset", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "offset"}}}}}}}}, &ObjectKeyVal{Key: "matches", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{&Suffix{Index: &Index{End: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}, IsSlice: true}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}, Else: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{&Suffix{Index: &Index{End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}}, Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "string", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{}}}}}}, &ObjectKeyVal{Key: "matches", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}, - "test": []*FuncDef{&FuncDef{Name: "test", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "test", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "test", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}, &Query{Func: "true"}}}}}}}, - "todate": []*FuncDef{&FuncDef{Name: "todate", Body: &Query{Func: "todateiso8601"}}}, - "todateiso8601": []*FuncDef{&FuncDef{Name: "todateiso8601", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strftime", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%SZ"}}}}}}}}}, - "tostream": []*FuncDef{&FuncDef{Name: "tostream", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{FuncDefs: []*FuncDef{&FuncDef{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Optional: true}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}, Op: OpComma, Right: &Query{Func: "."}}}}, Func: "r"}}}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$p"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{&Query{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Optional: true}}}}}}}, Pattern: &Pattern{Name: "$q"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpComma, Right: &Query{Func: "."}}}}}, Update: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpAdd, Right: &Query{Func: "$q"}}}}}}}}}}}}}}}}, - "truncate_stream": []*FuncDef{&FuncDef{Name: "truncate_stream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$n"}}, Body: &Query{Left: &Query{Func: "null"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Func: "$n"}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpModify, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}, IsSlice: true}}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}, - "unique_by": []*FuncDef{&FuncDef{Name: "unique_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_unique_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "until": []*FuncDef{&FuncDef{Name: "until", Args: []string{"cond", "next"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_until", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Func: "."}, Else: &Query{Left: &Query{Func: "next"}, Op: OpPipe, Right: &Query{Func: "_until"}}}}}}}, Func: "_until"}}}, - "values": []*FuncDef{&FuncDef{Name: "values", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Func: "null"}}}}}}}}, - "walk": []*FuncDef{&FuncDef{Name: "walk", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_walk", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map_values", Args: []*Query{&Query{Func: "_walk"}}}}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}, Func: "_walk"}}}, - "while": []*FuncDef{&FuncDef{Name: "while", Args: []string{"cond", "update"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_while", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "update"}, Op: OpPipe, Right: &Query{Func: "_while"}}}}}, Else: &Query{Func: "empty"}}}}}}, Func: "_while"}}}, - "with_entries": []*FuncDef{&FuncDef{Name: "with_entries", Args: []string{"f"}, Body: &Query{Left: &Query{Func: "to_entries"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Func: "f"}}}}}, Op: OpPipe, Right: &Query{Func: "from_entries"}}}}}, + "IN": {{Name: "IN", Args: []string{"s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Func: "s"}, Op: OpEq, Right: &Query{Func: "."}}, {Func: "."}}}}}}, {Name: "IN", Args: []string{"src", "s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Func: "src"}, Op: OpEq, Right: &Query{Func: "s"}}, {Func: "."}}}}}}}, + "INDEX": {{Name: "INDEX", Args: []string{"stream", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Func: "stream"}, Pattern: &Pattern{Name: "$row"}, Start: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Left: &Query{Func: "$row"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "idx_expr"}, Op: OpPipe, Right: &Query{Func: "tostring"}}}}}}, Op: OpAssign, Right: &Query{Func: "$row"}}}}}}, {Name: "INDEX", Args: []string{"idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "INDEX", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "idx_expr"}}}}}}}, + "JOIN": {{Name: "JOIN", Args: []string{"$idx", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}}}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr", "join_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "join_expr"}}}}}, + "_assign": {}, + "_modify": {}, + "add": {{Name: "add", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}, Op: OpPipe, Right: &Query{Func: "add"}}}}, + "all": {{Name: "all", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Func: "."}}}}}}, {Name: "all", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "y"}}}}}}, {Name: "all", Args: []string{"g", "y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "y"}, Op: OpPipe, Right: &Query{Func: "not"}}}}}}}}}}}}}, + "any": {{Name: "any", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Func: "."}}}}}}, {Name: "any", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "y"}}}}}}, {Name: "any", Args: []string{"g", "y"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "y"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "not"}}}}, + "arrays": {{Name: "arrays", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}}}}}}}, + "booleans": {{Name: "booleans", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "boolean"}}}}}}}}}}, + "capture": {{Name: "capture", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "capture", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "capture", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Func: "_capture"}}}}, + "combinations": {{Name: "combinations", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, SuffixList: []*Suffix{{Iter: true}, {Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$x"}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}}}}}}}}}}}, {Name: "combinations", Args: []string{"n"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "limit", Args: []*Query{{Func: "n"}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Func: "."}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}, + "del": {{Name: "del", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: "f"}}}}}}}}}}}}}}, + "finites": {{Name: "finites", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "isfinite"}}}}}}}, + "first": {{Name: "first", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}, {Name: "first", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}}, + "fromdate": {{Name: "fromdate", Body: &Query{Func: "fromdateiso8601"}}}, + "fromdateiso8601": {{Name: "fromdateiso8601", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strptime", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%S%z"}}}}}}}, Op: OpPipe, Right: &Query{Func: "mktime"}}}}, + "fromstream": {{Name: "fromstream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Func: "f"}, Pattern: &Pattern{Name: "$pv"}, Start: &Query{Func: "null"}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Func: "null"}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$pv"}, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Array: []*Pattern{{Name: "$p"}, {Name: "$v"}}}}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$pv"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "2"}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "v"}}}}}}, Op: OpAdd, Right: &Query{Func: "$p"}}, {Func: "$v"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Func: "$p"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Func: "$p"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}}}}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "v"}}}, Else: &Query{Func: "empty"}}}}}}}}}, + "group_by": {{Name: "group_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_group_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, + "gsub": {{Name: "gsub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, {Name: "gsub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}}}, + "in": {{Name: "in", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{{Func: "$x"}}}}}}}}}}}}}, + "inputs": {{Name: "inputs", Body: &Query{Term: &Term{Type: TermTypeTry, Try: &Try{Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Func: "input"}}}}}, Catch: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "break"}}}}, Then: &Query{Func: "empty"}, Else: &Query{Func: "error"}}}}}}}}}, + "inside": {{Name: "inside", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "contains", Args: []*Query{{Func: "$x"}}}}}}}}}}}}}, + "isempty": {{Name: "isempty", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "false"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}, Op: OpComma, Right: &Query{Func: "true"}}}}}}}, + "iterables": {{Name: "iterables", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}}, + "last": {{Name: "last", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}, + "limit": {{Name: "limit", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Func: "g"}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Else: &Query{Func: "empty"}}}}}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "empty"}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "limit doesn't support negative count"}}}}}}}}}}}}, + "map": {{Name: "map", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}}, + "map_values": {{Name: "map_values", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpModify, Right: &Query{Func: "f"}}}}, + "match": {{Name: "match", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "match", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}, {Func: "false"}}}, SuffixList: []*Suffix{{Iter: true}}}}}}, + "max_by": {{Name: "max_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_max_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, + "min_by": {{Name: "min_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_min_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, + "normals": {{Name: "normals", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "isnormal"}}}}}}}, + "not": {{Name: "not", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "."}, Then: &Query{Func: "false"}, Else: &Query{Func: "true"}}}}}}, + "nth": {{Name: "nth", Args: []string{"$n"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}}}}}, {Name: "nth", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "first", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "skip", Args: []*Query{{Func: "$n"}, {Func: "g"}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "nth doesn't support negative index"}}}}}}}}}}}}, + "nulls": {{Name: "nulls", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Func: "null"}}}}}}}}, + "numbers": {{Name: "numbers", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "number"}}}}}}}}}}, + "objects": {{Name: "objects", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}, + "paths": {{Name: "paths", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: ".."}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}, {Name: "paths", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Left: &Query{Func: ".."}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "f"}}}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}}, + "pick": {{Name: "pick", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$v"}}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: "f"}}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Func: "null"}, Update: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Func: "$p"}, {Left: &Query{Func: "$v"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Func: "$p"}}}}}}}}}}}}}}}}}}}}, + "range": {{Name: "range", Args: []string{"$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Term: &Term{Type: TermTypeNumber, Number: "0"}}, {Func: "$end"}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Func: "$start"}, {Func: "$end"}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end", "$step"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Func: "$start"}, {Func: "$end"}, {Func: "$step"}}}}}}}, + "recurse": {{Name: "recurse", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "recurse", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}}}, {Name: "recurse", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}, Func: "r"}}, {Name: "recurse", Args: []string{"f", "cond"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "cond"}}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}}, Func: "r"}}}, + "repeat": {{Name: "repeat", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_repeat", Body: &Query{Left: &Query{Func: "f"}, Op: OpComma, Right: &Query{Func: "_repeat"}}}}, Func: "_repeat"}}}, + "scalars": {{Name: "scalars", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}}, + "scan": {{Name: "scan", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "scan", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "scan", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}, Else: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{{Iter: true}, {Index: &Index{Name: "string"}}}}}}}}}}}}}}, + "select": {{Name: "select", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "f"}, Then: &Query{Func: "."}, Else: &Query{Func: "empty"}}}}}}, + "skip": {{Name: "skip", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Func: "g"}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "$item"}, Else: &Query{Func: "empty"}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "g"}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "skip doesn't support negative count"}}}}}}}}}}}}, + "sort_by": {{Name: "sort_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_sort_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, + "splits": {{Name: "splits", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "splits", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "split", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}, SuffixList: []*Suffix{{Iter: true}}}}}}, + "strings": {{Name: "strings", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}}}}}}, + "sub": {{Name: "sub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Func: "null"}}}}}}, {Name: "sub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$str"}}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_sub", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{{Index: &Index{End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}, {Bind: &Bind{Patterns: []*Pattern{{Name: "$r"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "string", Val: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$r"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "_capture"}, Op: OpPipe, Right: &Query{Func: "str"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "offset"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "length"}}}}}}, End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}, {Key: "offset", Val: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "offset"}}}}}}, {Key: "matches", Val: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{{Index: &Index{End: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}, IsSlice: true}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}}}}, Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "string", Val: &Query{Term: &Term{Type: TermTypeString, Str: &String{}}}}, {Key: "matches", Val: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}, + "test": {{Name: "test", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "test", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "test", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}, {Func: "true"}}}}}}}, + "todate": {{Name: "todate", Body: &Query{Func: "todateiso8601"}}}, + "todateiso8601": {{Name: "todateiso8601", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strftime", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%SZ"}}}}}}}}}, + "tostream": {{Name: "tostream", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}, Op: OpComma, Right: &Query{Func: "."}}}}, Func: "r"}}}, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$p"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}}, Pattern: &Pattern{Name: "$q"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpComma, Right: &Query{Func: "."}}}}}, Update: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpAdd, Right: &Query{Func: "$q"}}}}}}}}}}}}}}}}, + "truncate_stream": {{Name: "truncate_stream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$n"}}, Body: &Query{Left: &Query{Func: "null"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Func: "$n"}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpModify, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}, IsSlice: true}}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}, + "unique_by": {{Name: "unique_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_unique_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, + "until": {{Name: "until", Args: []string{"cond", "next"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_until", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Func: "."}, Else: &Query{Left: &Query{Func: "next"}, Op: OpPipe, Right: &Query{Func: "_until"}}}}}}}, Func: "_until"}}}, + "values": {{Name: "values", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Func: "null"}}}}}}}}, + "walk": {{Name: "walk", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_walk", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Func: "_walk"}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map_values", Args: []*Query{{Func: "_walk"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}, Func: "_walk"}}}, + "while": {{Name: "while", Args: []string{"cond", "update"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_while", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "update"}, Op: OpPipe, Right: &Query{Func: "_while"}}}}}, Else: &Query{Func: "empty"}}}}}}, Func: "_while"}}}, + "with_entries": {{Name: "with_entries", Args: []string{"f"}, Body: &Query{Left: &Query{Func: "to_entries"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Func: "f"}}}}}, Op: OpPipe, Right: &Query{Func: "from_entries"}}}}}, } } diff --git a/vendor/github.com/itchyny/gojq/builtin.jq b/vendor/github.com/itchyny/gojq/builtin.jq index 491f57f367..987e419212 100644 --- a/vendor/github.com/itchyny/gojq/builtin.jq +++ b/vendor/github.com/itchyny/gojq/builtin.jq @@ -20,6 +20,7 @@ def range($end): _range(0; $end; 1); def range($start; $end): _range($start; $end; 1); def range($start; $end; $step): _range($start; $end; $step); +def add(f): [f] | add; def min_by(f): _min_by(map([f])); def max_by(f): _max_by(map([f])); def sort_by(f): _sort_by(map([f])); @@ -37,23 +38,27 @@ def strings: select(type == "string"); def nulls: select(. == null); def values: select(. != null); def scalars: select(type | . != "array" and . != "object"); -def leaf_paths: paths(scalars); def inside(xs): . as $x | xs | contains($x); -def combinations: if length == 0 then [] else .[0][] as $x | [$x] + (.[1:] | combinations) end; +def combinations: + if length == 0 then + [] + else + .[0][] as $x | [$x] + (.[1:] | combinations) + end; def combinations(n): [limit(n; repeat(.))] | combinations; -def ascii_downcase: - explode | map(if 65 <= . and . <= 90 then . + 32 end) | implode; -def ascii_upcase: - explode | map(if 97 <= . and . <= 122 then . - 32 end) | implode; def walk(f): - def _walk: if type | . == "array" or . == "object" then map_values(_walk) end | f; + def _walk: + if type == "array" then + map(_walk) + elif type == "object" then + map_values(_walk) + end | f; _walk; def first: .[0]; def first(g): label $out | g | ., break $out; def last: .[-1]; -def last(g): reduce g as $item (null; $item); def isempty(g): label $out | (g | false, break $out), true; def all: all(.); def all(y): all(.[]; y); @@ -63,50 +68,64 @@ def any(y): any(.[]; y); def any(g; y): isempty(g | select(y)) | not; def limit($n; g): if $n > 0 then - label $out - | foreach g as $item - ($n; . - 1; $item, if . <= 0 then break $out else empty end) + label $out | + foreach g as $item ( + $n; + . - 1; + $item, if . <= 0 then break $out else empty end + ) elif $n == 0 then empty else + error("limit doesn't support negative count") + end; +def skip($n; g): + if $n > 0 then + foreach g as $item ( + $n; + . - 1; + if . < 0 then $item else empty end + ) + elif $n == 0 then g + else + error("skip doesn't support negative count") end; def nth($n): .[$n]; def nth($n; g): - if $n < 0 then - error("nth doesn't support negative indices") + if $n >= 0 then + first(skip($n; g)) else - label $out - | foreach g as $item - ($n + 1; . - 1; if . <= 0 then $item, break $out else empty end) + error("nth doesn't support negative index") end; def truncate_stream(f): - . as $n | null | f | if .[0] | length > $n then .[0] |= .[$n:] else empty end; + . as $n | null | f | + if .[0] | length > $n then .[0] |= .[$n:] else empty end; def fromstream(f): - { x: null, e: false } as $init - | foreach f as $i - ( $init; - if .e then $init else . end - | if $i | length == 2 - then setpath(["e"]; $i[0] | length==0) | setpath(["x"] + $i[0]; $i[1]) - else setpath(["e"]; $i[0] | length==1) end; - if .e then .x else empty end); + foreach f as $pv ( + null; + if .e then null end | + $pv as [$p, $v] | + if $pv | length == 2 then + setpath(["v"] + $p; $v) | + setpath(["e"]; $p | length == 0) + else + setpath(["e"]; $p | length == 1) + end; + if .e then .v else empty end + ); def tostream: - path(def r: (.[]? | r), .; r) as $p - | getpath($p) - | reduce path(.[]?) as $q ([$p, .]; [$p + $q]); + path(def r: (.[]? | r), .; r) as $p | + getpath($p) | + reduce path(.[]?) as $q ([$p, .]; [$p + $q]); -def _assign(ps; $v): - reduce path(ps) as $p (.; setpath($p; $v)); -def _modify(ps; f): - reduce path(ps) as $p - ([., []]; label $out | (([0] + $p) as $q | setpath($q; getpath($q) | f) | ., break $out), setpath([1]; .[1] + [$p])) - | . as $x | $x[0] | delpaths($x[1]); def map_values(f): .[] |= f; def del(f): delpaths([path(f)]); def paths: path(..) | select(. != []); -def paths(f): paths as $p | select(getpath($p) | f) | $p; +def paths(f): path(.. | select(f)) | select(. != []); +def pick(f): . as $v | + reduce path(f) as $p (null; setpath($p; $v | getpath($p))); def fromdateiso8601: strptime("%Y-%m-%dT%H:%M:%S%z") | mktime; def todateiso8601: strftime("%Y-%m-%dT%H:%M:%SZ"); @@ -114,33 +133,36 @@ def fromdate: fromdateiso8601; def todate: todateiso8601; def match($re): match($re; null); -def match($re; $flags): _match($re; $flags; false) | .[]; +def match($re; $flags): _match($re; $flags; false)[]; def test($re): test($re; null); def test($re; $flags): _match($re; $flags; true); def capture($re): capture($re; null); def capture($re; $flags): match($re; $flags) | _capture; def scan($re): scan($re; null); def scan($re; $flags): - match($re; $flags + "g") - | if .captures|length > 0 then [.captures[].string] else .string end; + match($re; $flags + "g") | + if .captures == [] then + .string + else + [.captures[].string] + end; def splits($re): splits($re; null); -def splits($re; $flags): split($re; $flags) | .[]; +def splits($re; $flags): split($re; $flags)[]; def sub($re; str): sub($re; str; null); def sub($re; str; $flags): - . as $str - | def _sub: - if .matches|length > 0 - then - .matches[-1] as $r - | { - string: (($r | _capture | str) + $str[$r.offset+$r.length:.offset] + .string), - offset: $r.offset, - matches: .matches[:-1], - } - | _sub - else - $str[:.offset] + .string - end; + . as $str | + def _sub: + if .matches == [] then + $str[:.offset] + .string + else + .matches[-1] as $r | + { + string: ($r | _capture | str) + $str[$r.offset+$r.length:.offset] + .string, + offset: $r.offset, + matches: .matches[:-1], + } | + _sub + end; { string: "", matches: [match($re; $flags)] } | _sub; def gsub($re; str): sub($re; str; "g"); def gsub($re; str; $flags): sub($re; str; $flags + "g"); @@ -152,8 +174,9 @@ def inputs: if . == "break" then empty else error end; def INDEX(stream; idx_expr): - reduce stream as $row ({}; .[$row|idx_expr|tostring] = $row); -def INDEX(idx_expr): INDEX(.[]; idx_expr); + reduce stream as $row ({}; .[$row | idx_expr | tostring] = $row); +def INDEX(idx_expr): + INDEX(.[]; idx_expr); def JOIN($idx; idx_expr): [.[] | [., $idx[idx_expr]]]; def JOIN($idx; stream; idx_expr): diff --git a/vendor/github.com/itchyny/gojq/code.go b/vendor/github.com/itchyny/gojq/code.go index efac134f7a..33505bde05 100644 --- a/vendor/github.com/itchyny/gojq/code.go +++ b/vendor/github.com/itchyny/gojq/code.go @@ -1,7 +1,7 @@ package gojq type code struct { - v interface{} + v any op opcode } diff --git a/vendor/github.com/itchyny/gojq/compare.go b/vendor/github.com/itchyny/gojq/compare.go index 89f0cdf71f..9791e9dc1c 100644 --- a/vendor/github.com/itchyny/gojq/compare.go +++ b/vendor/github.com/itchyny/gojq/compare.go @@ -8,14 +8,10 @@ import ( // Compare l and r, and returns jq-flavored comparison value. // The result will be 0 if l == r, -1 if l < r, and +1 if l > r. // This comparison is used by built-in operators and functions. -func Compare(l, r interface{}) int { - return compare(l, r) -} - -func compare(l, r interface{}) int { +func Compare(l, r any) int { return binopTypeSwitch(l, r, compareInt, - func(l, r float64) interface{} { + func(l, r float64) any { switch { case l < r || math.IsNaN(l): return -1 @@ -25,10 +21,10 @@ func compare(l, r interface{}) int { return 1 } }, - func(l, r *big.Int) interface{} { + func(l, r *big.Int) any { return l.Cmp(r) }, - func(l, r string) interface{} { + func(l, r string) any { switch { case l < r: return -1 @@ -38,37 +34,33 @@ func compare(l, r interface{}) int { return 1 } }, - func(l, r []interface{}) interface{} { - n := len(l) - if len(r) < n { - n = len(r) - } - for i := 0; i < n; i++ { - if cmp := compare(l[i], r[i]); cmp != 0 { + func(l, r []any) any { + for i, n := 0, min(len(l), len(r)); i < n; i++ { + if cmp := Compare(l[i], r[i]); cmp != 0 { return cmp } } return compareInt(len(l), len(r)) }, - func(l, r map[string]interface{}) interface{} { + func(l, r map[string]any) any { lk, rk := funcKeys(l), funcKeys(r) - if cmp := compare(lk, rk); cmp != 0 { + if cmp := Compare(lk, rk); cmp != 0 { return cmp } - for _, k := range lk.([]interface{}) { - if cmp := compare(l[k.(string)], r[k.(string)]); cmp != 0 { + for _, k := range lk.([]any) { + if cmp := Compare(l[k.(string)], r[k.(string)]); cmp != 0 { return cmp } } return 0 }, - func(l, r interface{}) interface{} { + func(l, r any) any { return compareInt(typeIndex(l), typeIndex(r)) }, ).(int) } -func compareInt(l, r int) interface{} { +func compareInt(l, r int) any { switch { case l < r: return -1 @@ -79,7 +71,7 @@ func compareInt(l, r int) interface{} { } } -func typeIndex(v interface{}) int { +func typeIndex(v any) int { switch v := v.(type) { default: return 0 @@ -92,9 +84,9 @@ func typeIndex(v interface{}) int { return 3 case string: return 4 - case []interface{}: + case []any: return 5 - case map[string]interface{}: + case map[string]any: return 6 } } diff --git a/vendor/github.com/itchyny/gojq/compiler.go b/vendor/github.com/itchyny/gojq/compiler.go index 098b44e6fa..cea452e3f1 100644 --- a/vendor/github.com/itchyny/gojq/compiler.go +++ b/vendor/github.com/itchyny/gojq/compiler.go @@ -35,12 +35,12 @@ type Code struct { // // It is safe to call this method in goroutines, to reuse a compiled [*Code]. // But for arguments, do not give values sharing same data between goroutines. -func (c *Code) Run(v interface{}, values ...interface{}) Iter { +func (c *Code) Run(v any, values ...any) Iter { return c.RunWithContext(context.Background(), v, values...) } // RunWithContext runs the code with context. -func (c *Code) RunWithContext(ctx context.Context, v interface{}, values ...interface{}) Iter { +func (c *Code) RunWithContext(ctx context.Context, v any, values ...any) Iter { if len(values) > len(c.variables) { return NewIter(&tooManyVariableValuesError{}) } else if len(values) < len(c.variables) { @@ -84,6 +84,13 @@ func Compile(q *Query, options ...CompilerOption) (*Code, error) { setscope := c.lazy(func() *code { return &code{op: opscope, v: [3]int{scope.id, scope.variablecnt, 0}} }) + for _, name := range c.variables { + if !newLexer(name).validVarName() { + return nil, &variableNameError{name} + } + c.appendCodeInfo(name) + c.append(&code{op: opstore, v: c.pushVariable(name)}) + } if c.moduleLoader != nil { if moduleLoader, ok := c.moduleLoader.(interface { LoadInitModules() ([]*Query, error) @@ -113,13 +120,6 @@ func Compile(q *Query, options ...CompilerOption) (*Code, error) { } func (c *compiler) compile(q *Query) error { - for _, name := range c.variables { - if !newLexer(name).validVarName() { - return &variableNameError{name} - } - c.appendCodeInfo(name) - c.append(&code{op: opstore, v: c.pushVariable(name)}) - } for _, i := range q.Imports { if err := c.compileImport(i); err != nil { return err @@ -144,15 +144,15 @@ func (c *compiler) compileImport(i *Import) error { return fmt.Errorf("cannot load module: %q", path) } if strings.HasPrefix(alias, "$") { - var vals interface{} + var vals any if moduleLoader, ok := c.moduleLoader.(interface { - LoadJSONWithMeta(string, map[string]interface{}) (interface{}, error) + LoadJSONWithMeta(string, map[string]any) (any, error) }); ok { if vals, err = moduleLoader.LoadJSONWithMeta(path, i.Meta.ToValue()); err != nil { return err } } else if moduleLoader, ok := c.moduleLoader.(interface { - LoadJSON(string) (interface{}, error) + LoadJSON(string) (any, error) }); ok { if vals, err = moduleLoader.LoadJSON(path); err != nil { return err @@ -169,7 +169,7 @@ func (c *compiler) compileImport(i *Import) error { } var q *Query if moduleLoader, ok := c.moduleLoader.(interface { - LoadModuleWithMeta(string, map[string]interface{}) (*Query, error) + LoadModuleWithMeta(string, map[string]any) (*Query, error) }); ok { if q, err = moduleLoader.LoadModuleWithMeta(path, i.Meta.ToValue()); err != nil { return err @@ -279,6 +279,21 @@ func (c *compiler) lookupBuiltin(name string, argcnt int) *funcinfo { return nil } +func (c *compiler) appendBuiltin(name string, argcnt int) func() { + setjump := c.lazy(func() *code { + return &code{op: opjump, v: len(c.codes)} + }) + c.appendCodeInfo(name) + c.builtinScope.funcs = append( + c.builtinScope.funcs, + &funcinfo{name, len(c.codes), argcnt}, + ) + return func() { + setjump() + c.appendCodeInfo("end of " + name) + } +} + func (c *compiler) newScope() *scopeinfo { i := c.scopecnt // do not use len(c.scopes) because it pops c.scopecnt++ @@ -383,6 +398,8 @@ func (c *compiler) compileQuery(e *Query) error { return c.compileTerm(e.Term) } switch e.Op { + case Operator(0): + return errors.New(`missing query (try ".")`) case OpPipe: if err := c.compileQuery(e.Left); err != nil { return err @@ -483,7 +500,7 @@ func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error { } c.append(&code{op: oppush, v: xs}) c.append(&code{op: opload, v: v}) - c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["setpath"].callback, 2, "setpath"}}) + c.append(&code{op: opcall, v: [3]any{internalFuncs["setpath"].callback, 2, "setpath"}}) return nil } fallthrough @@ -523,6 +540,7 @@ func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error { } func (c *compiler) compileBind(e *Term, b *Bind) error { + defer c.newScopeDepth()() c.append(&code{op: opdup}) c.append(&code{op: opexpbegin}) if err := c.compileTerm(e); err != nil { @@ -610,7 +628,7 @@ func (c *compiler) compilePattern(vs [][2]int, p *Pattern) ([][2]int, error) { c.append(&code{op: opload, v: v}) c.append(&code{op: oppush, v: nil}) // ref: compileCall - c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}}) + c.append(&code{op: opcall, v: [3]any{internalFuncs["_index"].callback, 2, "_index"}}) } if name != "" { if kv.Val != nil { @@ -708,9 +726,6 @@ func (c *compiler) compileTry(e *Try) error { func (c *compiler) compileReduce(e *Reduce) error { c.appendCodeInfo(e) defer c.newScopeDepth()() - setfork := c.lazy(func() *code { - return &code{op: opfork, v: len(c.codes)} - }) c.append(&code{op: opdup}) v := c.newVariable() f := c.newScopeDepth() @@ -719,7 +734,10 @@ func (c *compiler) compileReduce(e *Reduce) error { } f() c.append(&code{op: opstore, v: v}) - if err := c.compileTerm(e.Term); err != nil { + setfork := c.lazy(func() *code { + return &code{op: opfork, v: len(c.codes)} + }) + if err := c.compileQuery(e.Query); err != nil { return err } if _, err := c.compilePattern(nil, e.Pattern); err != nil { @@ -750,7 +768,7 @@ func (c *compiler) compileForeach(e *Foreach) error { } f() c.append(&code{op: opstore, v: v}) - if err := c.compileTerm(e.Term); err != nil { + if err := c.compileQuery(e.Query); err != nil { return err } if _, err := c.compilePattern(nil, e.Pattern); err != nil { @@ -774,9 +792,7 @@ func (c *compiler) compileForeach(e *Foreach) error { func (c *compiler) compileLabel(e *Label) error { c.appendCodeInfo(e) v := c.pushVariable("$%" + e.Ident[1:]) - defer c.lazy(func() *code { - return &code{op: opforklabel, v: v} - })() + c.append(&code{op: opforklabel, v: v}) return c.compileQuery(e.Body) } @@ -787,16 +803,16 @@ func (c *compiler) compileBreak(label string) error { } c.append(&code{op: oppop}) c.append(&code{op: opload, v: v}) - c.append(&code{op: opcall, v: [3]interface{}{ - func(v interface{}, _ []interface{}) interface{} { - return &breakError{label, v} - }, - 0, - "_break", - }}) + c.append(&code{op: opcall, v: [3]any{funcBreak(label), 0, "_break"}}) return nil } +func funcBreak(label string) func(any, []any) any { + return func(v any, _ []any) any { + return &breakError{label, v} + } +} + func (c *compiler) compileTerm(e *Term) error { if len(e.SuffixList) > 0 { s := e.SuffixList[len(e.SuffixList)-1] @@ -894,11 +910,11 @@ func (c *compiler) compileFunc(e *Func) error { } return nil } else if e.Name == "$ENV" || e.Name == "env" { - env := make(map[string]interface{}) + env := make(map[string]any) if c.environLoader != nil { for _, kv := range c.environLoader() { - if i := strings.IndexByte(kv, '='); i > 0 { - env[kv[:i]] = kv[i+1:] + if k, v, ok := strings.Cut(kv, "="); ok && k != "" { + env[k] = v } } } @@ -921,14 +937,26 @@ func (c *compiler) compileFunc(e *Func) error { return c.compileCallPc(f, e.Args) } if fds, ok := builtinFuncDefs[e.Name]; ok { + var compiled bool for _, fd := range fds { if len(fd.Args) == len(e.Args) { if err := c.compileFuncDef(fd, true); err != nil { return err } + compiled = true break } } + if !compiled { + switch e.Name { + case "_assign": + c.compileAssign() + case "_modify": + c.compileModify() + case "last": + c.compileLast() + } + } if f := c.lookupBuiltin(e.Name, len(e.Args)); f != nil { return c.compileCallPc(f, e.Args) } @@ -947,38 +975,54 @@ func (c *compiler) compileFunc(e *Func) error { return nil case "builtins": return c.compileCallInternal( - [3]interface{}{c.funcBuiltins, 0, e.Name}, + [3]any{c.funcBuiltins, 0, e.Name}, e.Args, true, - false, + -1, ) case "input": if c.inputIter == nil { return &inputNotAllowedError{} } return c.compileCallInternal( - [3]interface{}{c.funcInput, 0, e.Name}, + [3]any{c.funcInput, 0, e.Name}, e.Args, true, - false, + -1, ) case "modulemeta": return c.compileCallInternal( - [3]interface{}{c.funcModulemeta, 0, e.Name}, + [3]any{c.funcModulemeta, 0, e.Name}, e.Args, true, - false, + -1, ) + case "debug": + setfork := c.lazy(func() *code { + return &code{op: opfork, v: len(c.codes)} + }) + if err := c.compileQuery(e.Args[0]); err != nil { + return err + } + if err := c.compileFunc(&Func{Name: "debug"}); err != nil { + if _, ok := err.(*funcNotFoundError); ok { + err = &funcNotFoundError{e} + } + return err + } + c.append(&code{op: opbacktrack}) + setfork() + return nil default: return c.compileCall(e.Name, e.Args) } } if fn, ok := c.customFuncs[e.Name]; ok && fn.accept(len(e.Args)) { if err := c.compileCallInternal( - [3]interface{}{fn.callback, len(e.Args), e.Name}, + [3]any{fn.callback, len(e.Args), e.Name}, e.Args, true, - false, + -1, ); err != nil { return err } @@ -990,7 +1034,144 @@ func (c *compiler) compileFunc(e *Func) error { return &funcNotFoundError{e} } -func (c *compiler) funcBuiltins(interface{}, []interface{}) interface{} { +// Appends the compiled code for the assignment operator (`=`) to maximize +// performance. Originally the operator was implemented as follows. +// +// def _assign(p; $x): reduce path(p) as $q (.; setpath($q; $x)); +// +// To overcome the difficulty of reducing allocations on `setpath`, we use the +// `allocator` type and track the allocated addresses during the reduction. +func (c *compiler) compileAssign() { + defer c.appendBuiltin("_assign", 2)() + scope := c.newScope() + v, p := [2]int{scope.id, 0}, [2]int{scope.id, 1} + x, a := [2]int{scope.id, 2}, [2]int{scope.id, 3} + // Cannot reuse v, p due to backtracking in x. + w, q := [2]int{scope.id, 4}, [2]int{scope.id, 5} + c.appends( + &code{op: opscope, v: [3]int{scope.id, 6, 2}}, + &code{op: opstore, v: v}, // def _assign(p; $x): + &code{op: opstore, v: p}, + &code{op: opstore, v: x}, + &code{op: opload, v: v}, + &code{op: opexpbegin}, + &code{op: opload, v: x}, + &code{op: opcallpc}, + &code{op: opstore, v: x}, + &code{op: opexpend}, + &code{op: oppush, v: nil}, + &code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}}, + &code{op: opstore, v: a}, + &code{op: opload, v: v}, + &code{op: opfork, v: len(c.codes) + 30}, // reduce [L1] + &code{op: opdup}, + &code{op: opstore, v: w}, + &code{op: oppathbegin}, // path(p) + &code{op: opload, v: p}, + &code{op: opcallpc}, + &code{op: opload, v: w}, + &code{op: oppathend}, + &code{op: opstore, v: q}, // as $q (.; + &code{op: opload, v: a}, // setpath($q; $x) + &code{op: opload, v: x}, + &code{op: opload, v: q}, + &code{op: opload, v: w}, + &code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}}, + &code{op: opstore, v: w}, + &code{op: opbacktrack}, // ); + &code{op: oppop}, // [L1] + &code{op: opload, v: w}, + &code{op: opret}, + ) +} + +// Appends the compiled code for the update-assignment operator (`|=`) to +// maximize performance. We use the `allocator` type, just like `_assign/2`. +func (c *compiler) compileModify() { + defer c.appendBuiltin("_modify", 2)() + scope := c.newScope() + v, p := [2]int{scope.id, 0}, [2]int{scope.id, 1} + f, d := [2]int{scope.id, 2}, [2]int{scope.id, 3} + a, l := [2]int{scope.id, 4}, [2]int{scope.id, 5} + c.appends( + &code{op: opscope, v: [3]int{scope.id, 6, 2}}, + &code{op: opstore, v: v}, // def _modify(p; f): + &code{op: opstore, v: p}, + &code{op: opstore, v: f}, + &code{op: oppush, v: []any{}}, + &code{op: opstore, v: d}, + &code{op: oppush, v: nil}, + &code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}}, + &code{op: opstore, v: a}, + &code{op: opload, v: v}, + &code{op: opfork, v: len(c.codes) + 39}, // reduce [L1] + &code{op: oppathbegin}, // path(p) + &code{op: opload, v: p}, + &code{op: opcallpc}, + &code{op: opload, v: v}, + &code{op: oppathend}, + &code{op: opstore, v: p}, // as $p (.; + &code{op: opforklabel, v: l}, // label $l | + &code{op: opload, v: v}, // + &code{op: opfork, v: len(c.codes) + 36}, // [L2] + &code{op: oppop}, // (getpath($p) | + &code{op: opload, v: a}, + &code{op: opload, v: p}, + &code{op: opload, v: v}, + &code{op: opcall, v: [3]any{internalFuncs["getpath"].callback, 1, "getpath"}}, + &code{op: opload, v: f}, // f) + &code{op: opcallpc}, + &code{op: opload, v: p}, // setpath($p; ...) + &code{op: opload, v: v}, + &code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}}, + &code{op: opstore, v: v}, + &code{op: opload, v: v}, // ., break $l + &code{op: opfork, v: len(c.codes) + 34}, // [L4] + &code{op: opjump, v: len(c.codes) + 38}, // [L3] + &code{op: opload, v: l}, // [L4] + &code{op: opcall, v: [3]any{funcBreak(""), 0, "_break"}}, + &code{op: opload, v: p}, // append $p to $d [L2] + &code{op: opappend, v: d}, // + &code{op: opbacktrack}, // ) | [L3] + &code{op: oppop}, // delpaths($d); [L1] + &code{op: opload, v: a}, + &code{op: opload, v: d}, + &code{op: opload, v: v}, + &code{op: opcall, v: [3]any{funcDelpathsWithAllocator, 2, "_delpaths"}}, + &code{op: opret}, + ) +} + +// Appends the compiled code for the `last/1` function to +// maximize performance avoiding unnecessary boxing. +func (c *compiler) compileLast() { + defer c.appendBuiltin("last", 1)() + scope := c.newScope() + v, g, x := [2]int{scope.id, 0}, [2]int{scope.id, 1}, [2]int{scope.id, 2} + c.appends( + &code{op: opscope, v: [3]int{scope.id, 3, 1}}, + &code{op: opstore, v: v}, + &code{op: opstore, v: g}, + &code{op: oppush, v: true}, // $x = true + &code{op: opstore, v: x}, + &code{op: opload, v: v}, + &code{op: opfork, v: len(c.codes) + 13}, // reduce [L1] + &code{op: opload, v: g}, // g + &code{op: opcallpc}, + &code{op: opstore, v: v}, // as $v ( + &code{op: oppush, v: false}, // $x = false + &code{op: opstore, v: x}, + &code{op: opbacktrack}, // ); + &code{op: oppop}, // [L1] + &code{op: opload, v: x}, // if $x then $v else empty end + &code{op: opjumpifnot, v: len(c.codes) + 17}, + &code{op: opbacktrack}, + &code{op: opload, v: v}, + &code{op: opret}, + ) +} + +func (c *compiler) funcBuiltins(any, []any) any { type funcNameArity struct { name string arity int @@ -1025,14 +1206,14 @@ func (c *compiler) funcBuiltins(interface{}, []interface{}) interface{} { return xs[i].name < xs[j].name || xs[i].name == xs[j].name && xs[i].arity < xs[j].arity }) - ys := make([]interface{}, len(xs)) + ys := make([]any, len(xs)) for i, x := range xs { ys[i] = x.name + "/" + strconv.Itoa(x.arity) } return ys } -func (c *compiler) funcInput(interface{}, []interface{}) interface{} { +func (c *compiler) funcInput(any, []any) any { v, ok := c.inputIter.Next() if !ok { return errors.New("break") @@ -1040,10 +1221,10 @@ func (c *compiler) funcInput(interface{}, []interface{}) interface{} { return normalizeNumbers(v) } -func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} { +func (c *compiler) funcModulemeta(v any, _ []any) any { s, ok := v.(string) if !ok { - return &funcTypeError{"modulemeta", v} + return &func0TypeError{"modulemeta", v} } if c.moduleLoader == nil { return fmt.Errorf("cannot load module: %q", s) @@ -1051,7 +1232,7 @@ func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} { var q *Query var err error if moduleLoader, ok := c.moduleLoader.(interface { - LoadModuleWithMeta(string, map[string]interface{}) (*Query, error) + LoadModuleWithMeta(string, map[string]any) (*Query, error) }); ok { if q, err = moduleLoader.LoadModuleWithMeta(s, nil); err != nil { return err @@ -1065,43 +1246,60 @@ func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} { } meta := q.Meta.ToValue() if meta == nil { - meta = make(map[string]interface{}) + meta = make(map[string]any) } - var deps []interface{} - for _, i := range q.Imports { + meta["defs"] = listModuleDefs(q) + meta["deps"] = listModuleDeps(q) + return meta +} + +func listModuleDefs(q *Query) []any { + type funcNameArity struct { + name string + arity int + } + var xs []*funcNameArity + for _, fd := range q.FuncDefs { + if fd.Name[0] != '_' { + xs = append(xs, &funcNameArity{fd.Name, len(fd.Args)}) + } + } + sort.Slice(xs, func(i, j int) bool { + return xs[i].name < xs[j].name || + xs[i].name == xs[j].name && xs[i].arity < xs[j].arity + }) + defs := make([]any, len(xs)) + for i, x := range xs { + defs[i] = x.name + "/" + strconv.Itoa(x.arity) + } + return defs +} + +func listModuleDeps(q *Query) []any { + deps := make([]any, len(q.Imports)) + for j, i := range q.Imports { v := i.Meta.ToValue() if v == nil { - v = make(map[string]interface{}) - } else { - for k := range v { - // dirty hack to remove the internal fields - if strings.HasPrefix(k, "$$") { - delete(v, k) - } - } + v = make(map[string]any) } - if i.ImportPath == "" { - v["relpath"] = i.IncludePath - } else { - v["relpath"] = i.ImportPath - } - if err != nil { - return err + relpath := i.ImportPath + if relpath == "" { + relpath = i.IncludePath } + v["relpath"] = relpath if i.ImportAlias != "" { v["as"] = strings.TrimPrefix(i.ImportAlias, "$") } v["is_data"] = strings.HasPrefix(i.ImportAlias, "$") - deps = append(deps, v) + deps[j] = v } - meta["deps"] = deps - return meta + return deps } func (c *compiler) compileObject(e *Object) error { c.appendCodeInfo(e) if len(e.KeyVals) == 0 { - c.append(&code{op: opconst, v: map[string]interface{}{}}) + c.append(&code{op: opconst, v: map[string]any{}}) return nil } defer c.newScopeDepth()() @@ -1126,7 +1324,7 @@ func (c *compiler) compileObject(e *Object) error { return nil } } - w := make(map[string]interface{}, l) + w := make(map[string]any, l) for i := 0; i < l; i++ { w[c.codes[pc+i*3].v.(string)] = c.codes[pc+i*3+2].v } @@ -1169,7 +1367,7 @@ func (c *compiler) compileObjectKeyVal(v [2]int, kv *ObjectKeyVal) error { c.append(&code{op: opload, v: v}) c.append(&code{op: oppush, v: nil}) // ref: compileCall - c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}}) + c.append(&code{op: opcall, v: [3]any{internalFuncs["_index"].callback, 2, "_index"}}) } } } else if kv.KeyQuery != nil { @@ -1182,10 +1380,8 @@ func (c *compiler) compileObjectKeyVal(v [2]int, kv *ObjectKeyVal) error { } if kv.Val != nil { c.append(&code{op: opload, v: v}) - for _, e := range kv.Val.Queries { - if err := c.compileQuery(e); err != nil { - return err - } + if err := c.compileQuery(kv.Val); err != nil { + return err } } return nil @@ -1194,10 +1390,10 @@ func (c *compiler) compileObjectKeyVal(v [2]int, kv *ObjectKeyVal) error { func (c *compiler) compileArray(e *Array) error { c.appendCodeInfo(e) if e.Query == nil { - c.append(&code{op: opconst, v: []interface{}{}}) + c.append(&code{op: opconst, v: []any{}}) return nil } - c.append(&code{op: oppush, v: []interface{}{}}) + c.append(&code{op: oppush, v: []any{}}) arr := c.newVariable() c.append(&code{op: opstore, v: arr}) pc := len(c.codes) @@ -1228,7 +1424,7 @@ func (c *compiler) compileArray(e *Array) error { return nil } } - v := make([]interface{}, l) + v := make([]any, l) for i := 0; i < l; i++ { v[i] = c.codes[pc+i*2+l].v } @@ -1256,12 +1452,12 @@ func (c *compiler) compileUnary(e *Unary) error { } } -func (c *compiler) compileFormat(fmt string, str *String) error { - f := formatToFunc(fmt) +func (c *compiler) compileFormat(format string, str *String) error { + f := formatToFunc(format) if f == nil { f = &Func{ Name: "format", - Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: fmt[1:]}}}}, + Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: format[1:]}}}}, } } if str == nil { @@ -1270,8 +1466,8 @@ func (c *compiler) compileFormat(fmt string, str *String) error { return c.compileString(str, f) } -func formatToFunc(fmt string) *Func { - switch fmt { +func formatToFunc(format string) *Func { + switch format { case "@text": return &Func{Name: "tostring"} case "@json": @@ -1280,6 +1476,8 @@ func formatToFunc(fmt string) *Func { return &Func{Name: "_tohtml"} case "@uri": return &Func{Name: "_touri"} + case "@urid": + return &Func{Name: "_tourid"} case "@csv": return &Func{Name: "_tocsv"} case "@tsv": @@ -1347,11 +1545,20 @@ func (c *compiler) compileTermSuffix(e *Term, s *Suffix) error { func (c *compiler) compileCall(name string, args []*Query) error { fn := internalFuncs[name] + var indexing int + switch name { + case "_index", "_slice": + indexing = 1 + case "getpath": + indexing = 0 + default: + indexing = -1 + } if err := c.compileCallInternal( - [3]interface{}{fn.callback, len(args), name}, + [3]any{fn.callback, len(args), name}, args, true, - name == "_index" || name == "_slice", + indexing, ); err != nil { return err } @@ -1362,18 +1569,19 @@ func (c *compiler) compileCall(name string, args []*Query) error { } func (c *compiler) compileCallPc(fn *funcinfo, args []*Query) error { - return c.compileCallInternal(fn.pc, args, false, false) + return c.compileCallInternal(fn.pc, args, false, -1) } func (c *compiler) compileCallInternal( - fn interface{}, args []*Query, internal, indexing bool) error { + fn any, args []*Query, internal bool, indexing int, +) error { if len(args) == 0 { c.append(&code{op: opcall, v: fn}) return nil } v := c.newVariable() c.append(&code{op: opstore, v: v}) - if indexing { + if indexing >= 0 { c.append(&code{op: opexpbegin}) } for i := len(args) - 1; i >= 0; i-- { @@ -1412,7 +1620,7 @@ func (c *compiler) compileCallInternal( } else { c.append(&code{op: oppushpc, v: pc}) } - if indexing && i == 1 { + if i == indexing { if c.codes[len(c.codes)-2].op == opexpbegin { c.codes[len(c.codes)-2] = c.codes[len(c.codes)-1] c.codes = c.codes[:len(c.codes)-1] @@ -1421,7 +1629,7 @@ func (c *compiler) compileCallInternal( } } } - if indexing { + if indexing > 0 { c.append(&code{op: oppush, v: nil}) } else { c.append(&code{op: opload, v: v}) @@ -1434,6 +1642,10 @@ func (c *compiler) append(code *code) { c.codes = append(c.codes, code) } +func (c *compiler) appends(codes ...*code) { + c.codes = append(c.codes, codes...) +} + func (c *compiler) lazy(f func() *code) func() { i := len(c.codes) c.codes = append(c.codes, nil) diff --git a/vendor/github.com/itchyny/gojq/debug.go b/vendor/github.com/itchyny/gojq/debug.go index c353ac800c..709914b717 100644 --- a/vendor/github.com/itchyny/gojq/debug.go +++ b/vendor/github.com/itchyny/gojq/debug.go @@ -1,5 +1,4 @@ //go:build gojq_debug -// +build gojq_debug package gojq @@ -32,7 +31,7 @@ type codeinfo struct { pc int } -func (c *compiler) appendCodeInfo(x interface{}) { +func (c *compiler) appendCodeInfo(x any) { if !debug { return } @@ -103,7 +102,7 @@ func (env *env) debugCodes() { s = "\t## " + name } } - fmt.Fprintf(debugOut, "\t%d\t%s%s%s\n", i, formatOp(c.op, false), debugOperand(c), s) + fmt.Fprintf(debugOut, "\t%d\t%-*s%s%s\n", i, 25, c.op, debugOperand(c), s) } fmt.Fprintln(debugOut, "\t"+strings.Repeat("-", 40)+"+") } @@ -114,7 +113,11 @@ func (env *env) debugState(pc int, backtrack bool) { } var sb strings.Builder c := env.codes[pc] - fmt.Fprintf(&sb, "\t%d\t%s%s\t|", pc, formatOp(c.op, backtrack), debugOperand(c)) + op := c.op.String() + if backtrack { + op += " " + } + fmt.Fprintf(&sb, "\t%d\t%-*s%s\t|", pc, 25, op, debugOperand(c)) var xs []int for i := env.stack.index; i >= 0; i = env.stack.data[i].next { xs = append(xs, i) @@ -149,13 +152,6 @@ func (env *env) debugState(pc int, backtrack bool) { fmt.Fprintln(debugOut, sb.String()) } -func formatOp(c opcode, backtrack bool) string { - if backtrack { - return c.String() + " " + strings.Repeat(" ", 13-len(c.String())) - } - return c.String() + strings.Repeat(" ", 25-len(c.String())) -} - func (env *env) debugForks(pc int, op string) { if !debug { return @@ -173,7 +169,7 @@ func (env *env) debugForks(pc int, op string) { sb.WriteByte('>') } } - fmt.Fprintf(debugOut, "\t-\t%s%s%d\t|\t%s\n", op, strings.Repeat(" ", 22), pc, sb.String()) + fmt.Fprintf(debugOut, "\t-\t%-*s%d\t|\t%s\n", 25, op, pc, sb.String()) } func debugOperand(c *code) string { @@ -182,7 +178,7 @@ func debugOperand(c *code) string { switch v := c.v.(type) { case int: return strconv.Itoa(v) - case [3]interface{}: + case [3]any: return fmt.Sprintf("%s/%d", v[2], v[1]) default: panic(c) @@ -192,7 +188,7 @@ func debugOperand(c *code) string { } } -func debugValue(v interface{}) string { +func debugValue(v any) string { switch v := v.(type) { case Iter: return fmt.Sprintf("gojq.Iter(%#v)", v) @@ -202,8 +198,10 @@ func debugValue(v interface{}) string { return fmt.Sprintf("[%d,%d]", v[0], v[1]) case [3]int: return fmt.Sprintf("[%d,%d,%d]", v[0], v[1], v[2]) - case [3]interface{}: + case [3]any: return fmt.Sprintf("[%v,%v,%v]", v[0], v[1], v[2]) + case allocator: + return fmt.Sprintf("%v", v) default: return Preview(v) } diff --git a/vendor/github.com/itchyny/gojq/encoder.go b/vendor/github.com/itchyny/gojq/encoder.go index d61456cd59..518904d71c 100644 --- a/vendor/github.com/itchyny/gojq/encoder.go +++ b/vendor/github.com/itchyny/gojq/encoder.go @@ -15,19 +15,19 @@ import ( // Marshal returns the jq-flavored JSON encoding of v. // // This method accepts only limited types (nil, bool, int, float64, *big.Int, -// string, []interface{}, and map[string]interface{}) because these are the -// possible types a gojq iterator can emit. This method marshals NaN to null, -// truncates infinities to (+|-) math.MaxFloat64, uses \b and \f in strings, -// and does not escape '<', '>', '&', '\u2028', and '\u2029'. These behaviors -// are based on the marshaler of jq command, and different from json.Marshal in -// the Go standard library. Note that the result is not safe to embed in HTML. -func Marshal(v interface{}) ([]byte, error) { +// string, []any, and map[string]any) because these are the possible types a +// gojq iterator can emit. This method marshals NaN to null, truncates +// infinities to (+|-) math.MaxFloat64, uses \b and \f in strings, and does not +// escape '<', '>', '&', '\u2028', and '\u2029'. These behaviors are based on +// the marshaler of jq command, and different from json.Marshal in the Go +// standard library. Note that the result is not safe to embed in HTML. +func Marshal(v any) ([]byte, error) { var b bytes.Buffer (&encoder{w: &b}).encode(v) return b.Bytes(), nil } -func jsonMarshal(v interface{}) string { +func jsonMarshal(v any) string { var sb strings.Builder (&encoder{w: &sb}).encode(v) return sb.String() @@ -46,7 +46,7 @@ type encoder struct { buf [64]byte } -func (e *encoder) encode(v interface{}) { +func (e *encoder) encode(v any) { switch v := v.(type) { case nil: e.w.WriteString("null") @@ -64,10 +64,10 @@ func (e *encoder) encode(v interface{}) { e.w.Write(v.Append(e.buf[:0], 10)) case string: e.encodeString(v) - case []interface{}: + case []any: e.encodeArray(v) - case map[string]interface{}: - e.encodeMap(v) + case map[string]any: + e.encodeObject(v) default: panic(fmt.Sprintf("invalid type: %[1]T (%[1]v)", v)) } @@ -79,17 +79,13 @@ func (e *encoder) encodeFloat64(f float64) { e.w.WriteString("null") return } - if f >= math.MaxFloat64 { - f = math.MaxFloat64 - } else if f <= -math.MaxFloat64 { - f = -math.MaxFloat64 - } - fmt := byte('f') + f = min(max(f, -math.MaxFloat64), math.MaxFloat64) + format := byte('f') if x := math.Abs(f); x != 0 && x < 1e-6 || x >= 1e21 { - fmt = 'e' + format = 'e' } - buf := strconv.AppendFloat(e.buf[:0], f, fmt, -1, 64) - if fmt == 'e' { + buf := strconv.AppendFloat(e.buf[:0], f, format, -1, 64) + if format == 'e' { // clean up e-09 to e-9 if n := len(buf); n >= 4 && buf[n-4] == 'e' && buf[n-3] == '-' && buf[n-2] == '0' { buf[n-2] = buf[n-1] @@ -155,7 +151,7 @@ func (e *encoder) encodeString(s string) { e.w.WriteByte('"') } -func (e *encoder) encodeArray(vs []interface{}) { +func (e *encoder) encodeArray(vs []any) { e.w.WriteByte('[') for i, v := range vs { if i > 0 { @@ -166,11 +162,11 @@ func (e *encoder) encodeArray(vs []interface{}) { e.w.WriteByte(']') } -func (e *encoder) encodeMap(vs map[string]interface{}) { +func (e *encoder) encodeObject(vs map[string]any) { e.w.WriteByte('{') type keyVal struct { key string - val interface{} + val any } kvs := make([]keyVal, len(vs)) var i int diff --git a/vendor/github.com/itchyny/gojq/env.go b/vendor/github.com/itchyny/gojq/env.go index dd1859c494..bf058eda83 100644 --- a/vendor/github.com/itchyny/gojq/env.go +++ b/vendor/github.com/itchyny/gojq/env.go @@ -7,7 +7,7 @@ type env struct { stack *stack paths *stack scopes *scopeStack - values []interface{} + values []any codes []*code codeinfos []codeinfo forks []fork @@ -15,7 +15,7 @@ type env struct { offset int expdepth int label int - args [32]interface{} // len(env.args) > maxarity + args [32]any // len(env.args) > maxarity ctx context.Context } diff --git a/vendor/github.com/itchyny/gojq/error.go b/vendor/github.com/itchyny/gojq/error.go index e128b54385..18b06b1ccf 100644 --- a/vendor/github.com/itchyny/gojq/error.go +++ b/vendor/github.com/itchyny/gojq/error.go @@ -8,11 +8,11 @@ import "strconv" // Refer to [WithFunction] to add a custom internal function. type ValueError interface { error - Value() interface{} + Value() any } type expectedObjectError struct { - v interface{} + v any } func (err *expectedObjectError) Error() string { @@ -20,31 +20,31 @@ func (err *expectedObjectError) Error() string { } type expectedArrayError struct { - v interface{} + v any } func (err *expectedArrayError) Error() string { return "expected an array but got: " + typeErrorPreview(err.v) } -type expectedStringError struct { - v interface{} +type iteratorError struct { + v any } -func (err *expectedStringError) Error() string { - return "expected a string but got: " + typeErrorPreview(err.v) +func (err *iteratorError) Error() string { + return "cannot iterate over: " + typeErrorPreview(err.v) } -type iteratorError struct { - v interface{} +type arrayIndexNegativeError struct { + v int } -func (err *iteratorError) Error() string { - return "cannot iterate over: " + typeErrorPreview(err.v) +func (err *arrayIndexNegativeError) Error() string { + return "array index should not be negative: " + Preview(err.v) } type arrayIndexTooLargeError struct { - v interface{} + v any } func (err *arrayIndexTooLargeError) Error() string { @@ -52,7 +52,7 @@ func (err *arrayIndexTooLargeError) Error() string { } type objectKeyNotStringError struct { - v interface{} + v any } func (err *objectKeyNotStringError) Error() string { @@ -60,7 +60,7 @@ func (err *objectKeyNotStringError) Error() string { } type arrayIndexNotNumberError struct { - v interface{} + v any } func (err *arrayIndexNotNumberError) Error() string { @@ -68,7 +68,7 @@ func (err *arrayIndexNotNumberError) Error() string { } type stringIndexNotNumberError struct { - v interface{} + v any } func (err *stringIndexNotNumberError) Error() string { @@ -76,20 +76,17 @@ func (err *stringIndexNotNumberError) Error() string { } type expectedStartEndError struct { - v interface{} + v any } func (err *expectedStartEndError) Error() string { return `expected "start" and "end" for slicing but got: ` + typeErrorPreview(err.v) } -type lengthMismatchError struct { - name string - v, x []interface{} -} +type lengthMismatchError struct{} -func (err *lengthMismatchError) Error() string { - return "length mismatch in " + err.name + ": " + typeErrorPreview(err.v) + ", " + typeErrorPreview(err.x) +func (*lengthMismatchError) Error() string { + return "length mismatch" } type inputNotAllowedError struct{} @@ -106,19 +103,66 @@ func (err *funcNotFoundError) Error() string { return "function not defined: " + err.f.Name + "/" + strconv.Itoa(len(err.f.Args)) } -type funcTypeError struct { +type func0TypeError struct { name string - v interface{} + v any } -func (err *funcTypeError) Error() string { +func (err *func0TypeError) Error() string { return err.name + " cannot be applied to: " + typeErrorPreview(err.v) } +type func1TypeError struct { + name string + v, w any +} + +func (err *func1TypeError) Error() string { + return err.name + "(" + Preview(err.w) + ") cannot be applied to: " + typeErrorPreview(err.v) +} + +type func2TypeError struct { + name string + v, w, x any +} + +func (err *func2TypeError) Error() string { + return err.name + "(" + Preview(err.w) + "; " + Preview(err.x) + ") cannot be applied to: " + typeErrorPreview(err.v) +} + +type func0WrapError struct { + name string + v any + err error +} + +func (err *func0WrapError) Error() string { + return err.name + " cannot be applied to " + Preview(err.v) + ": " + err.err.Error() +} + +type func1WrapError struct { + name string + v, w any + err error +} + +func (err *func1WrapError) Error() string { + return err.name + "(" + Preview(err.w) + ") cannot be applied to " + Preview(err.v) + ": " + err.err.Error() +} + +type func2WrapError struct { + name string + v, w, x any + err error +} + +func (err *func2WrapError) Error() string { + return err.name + "(" + Preview(err.w) + "; " + Preview(err.x) + ") cannot be applied to " + Preview(err.v) + ": " + err.err.Error() +} + type exitCodeError struct { - value interface{} + value any code int - halt bool } func (err *exitCodeError) Error() string { @@ -128,11 +172,7 @@ func (err *exitCodeError) Error() string { return "error: " + jsonMarshal(err.value) } -func (err *exitCodeError) IsEmptyError() bool { - return err.value == nil -} - -func (err *exitCodeError) Value() interface{} { +func (err *exitCodeError) Value() any { return err.value } @@ -140,24 +180,28 @@ func (err *exitCodeError) ExitCode() int { return err.code } -func (err *exitCodeError) IsHaltError() bool { - return err.halt -} - -type containsTypeError struct { - l, r interface{} -} +// HaltError is an error emitted by halt and halt_error functions. +// It implements [ValueError], and if the value is nil, discard the error +// and stop the iteration. Consider a query like "1, halt, 2"; +// the first value is 1, and the second value is a HaltError with nil value. +// You might think the iterator should not emit an error this case, but it +// should so that we can recognize the halt error to stop the outer loop +// of iterating input values; echo 1 2 3 | gojq "., halt". +type HaltError exitCodeError -func (err *containsTypeError) Error() string { - return "cannot check contains(" + Preview(err.r) + "): " + typeErrorPreview(err.l) +func (err *HaltError) Error() string { + return "halt " + (*exitCodeError)(err).Error() } -type hasKeyTypeError struct { - l, r interface{} +// Value returns the value of the error. This implements [ValueError], +// but halt error is not catchable by try-catch. +func (err *HaltError) Value() any { + return (*exitCodeError)(err).Value() } -func (err *hasKeyTypeError) Error() string { - return "cannot check whether " + typeErrorPreview(err.l) + " has a key: " + typeErrorPreview(err.r) +// ExitCode returns the exit code of the error. +func (err *HaltError) ExitCode() int { + return (*exitCodeError)(err).ExitCode() } type flattenDepthError struct { @@ -165,20 +209,26 @@ type flattenDepthError struct { } func (err *flattenDepthError) Error() string { - return "flatten depth must not be negative: " + typeErrorPreview(err.v) + return "flatten depth should not be negative: " + Preview(err.v) } type joinTypeError struct { - v interface{} + v any } func (err *joinTypeError) Error() string { - return "cannot join: " + typeErrorPreview(err.v) + return "join cannot be applied to an array including: " + typeErrorPreview(err.v) +} + +type timeArrayError struct{} + +func (*timeArrayError) Error() string { + return "expected an array of 8 numbers" } type unaryTypeError struct { name string - v interface{} + v any } func (err *unaryTypeError) Error() string { @@ -187,7 +237,7 @@ func (err *unaryTypeError) Error() string { type binopTypeError struct { name string - l, r interface{} + l, r any } func (err *binopTypeError) Error() string { @@ -195,7 +245,7 @@ func (err *binopTypeError) Error() string { } type zeroDivisionError struct { - l, r interface{} + l, r any } func (err *zeroDivisionError) Error() string { @@ -203,7 +253,7 @@ func (err *zeroDivisionError) Error() string { } type zeroModuloError struct { - l, r interface{} + l, r any } func (err *zeroModuloError) Error() string { @@ -220,7 +270,7 @@ func (err *formatNotFoundError) Error() string { type formatRowError struct { typ string - v interface{} + v any } func (err *formatRowError) Error() string { @@ -229,7 +279,7 @@ func (err *formatRowError) Error() string { type tooManyVariableValuesError struct{} -func (err *tooManyVariableValuesError) Error() string { +func (*tooManyVariableValuesError) Error() string { return "too many variable values provided" } @@ -259,14 +309,14 @@ func (err *variableNameError) Error() string { type breakError struct { n string - v interface{} + v any } func (err *breakError) Error() string { return "label not defined: " + err.n } -func (err *breakError) ExitCode() int { +func (*breakError) ExitCode() int { return 3 } @@ -279,7 +329,7 @@ func (err *tryEndError) Error() string { } type invalidPathError struct { - v interface{} + v any } func (err *invalidPathError) Error() string { @@ -287,21 +337,13 @@ func (err *invalidPathError) Error() string { } type invalidPathIterError struct { - v interface{} + v any } func (err *invalidPathIterError) Error() string { return "invalid path on iterating against: " + typeErrorPreview(err.v) } -type getpathError struct { - v, path interface{} -} - -func (err *getpathError) Error() string { - return "cannot getpath with " + Preview(err.path) + " against: " + typeErrorPreview(err.v) -} - type queryParseError struct { fname, contents string err error @@ -328,7 +370,7 @@ func (err *jsonParseError) Error() string { return "invalid json: " + err.fname + ": " + err.err.Error() } -func typeErrorPreview(v interface{}) string { +func typeErrorPreview(v any) string { switch v.(type) { case nil: return "null" diff --git a/vendor/github.com/itchyny/gojq/execute.go b/vendor/github.com/itchyny/gojq/execute.go index 695481cffe..344d8a3c57 100644 --- a/vendor/github.com/itchyny/gojq/execute.go +++ b/vendor/github.com/itchyny/gojq/execute.go @@ -7,7 +7,7 @@ import ( "sort" ) -func (env *env) execute(bc *Code, v interface{}, vars ...interface{}) Iter { +func (env *env) execute(bc *Code, v any, vars ...any) Iter { env.codes = bc.codes env.codeinfos = bc.codeinfos env.push(v) @@ -18,7 +18,7 @@ func (env *env) execute(bc *Code, v interface{}, vars ...interface{}) Iter { return env } -func (env *env) Next() (interface{}, bool) { +func (env *env) Next() (any, bool) { var err error pc, callpc, index := env.pc, len(env.codes)-1, -1 backtrack, hasCtx := env.backtrack, env.ctx != context.Background() @@ -58,7 +58,7 @@ loop: break loop } n := code.v.(int) - m := make(map[string]interface{}, n) + m := make(map[string]any, n) for i := 0; i < n; i++ { v, k := env.pop(), env.pop() s, ok := k.(string) @@ -66,12 +66,14 @@ loop: err = &objectKeyNotStringError{k} break loop } - m[s] = v + if _, ok := m[s]; !ok { + m[s] = v + } } env.push(m) case opappend: i := env.index(code.v.([2]int)) - env.values[i] = append(env.values[i].([]interface{}), env.pop()) + env.values[i] = append(env.values[i].([]any), env.pop()) case opfork: if backtrack { if err != nil { @@ -86,21 +88,15 @@ loop: if err == nil { break loop } - switch er := err.(type) { + switch e := err.(type) { case *tryEndError: - err = er.err + err = e.err + break loop + case *breakError, *HaltError: break loop case ValueError: - if er, ok := er.(*exitCodeError); ok && er.halt { - break loop - } - if v := er.Value(); v != nil { - env.pop() - env.push(v) - } else { - err = nil - break loop - } + env.pop() + env.push(e.Value()) default: env.pop() env.push(err.Error()) @@ -155,7 +151,7 @@ loop: } p, v := code.v, env.pop() if code.op == opindexarray && v != nil { - if _, ok := v.([]interface{}); !ok { + if _, ok := v.([]any); !ok { err = &expectedArrayError{v} break loop } @@ -181,17 +177,15 @@ loop: case int: pc, callpc, index = v, pc, env.scopes.index goto loop - case [3]interface{}: + case [3]any: argcnt := v[1].(int) x, args := env.pop(), env.args[:argcnt] for i := 0; i < argcnt; i++ { args[i] = env.pop() } - w := v[0].(func(interface{}, []interface{}) interface{})(x, args) + w := v[0].(func(any, []any) any)(x, args) if e, ok := w.(error); ok { - if er, ok := e.(*exitCodeError); !ok || er.value != nil || er.halt { - err = e - } + err = e break loop } env.push(w) @@ -209,7 +203,7 @@ loop: break loop } env.paths.push(pathValue{ - path: map[string]interface{}{"start": args[2], "end": args[1]}, + path: map[string]any{"start": args[2], "end": args[1]}, value: w, }) case "getpath": @@ -217,7 +211,7 @@ loop: err = &invalidPathError{x} break loop } - for _, p := range args[0].([]interface{}) { + for _, p := range args[0].([]any) { env.paths.push(pathValue{path: p, value: w}) } } @@ -255,7 +249,7 @@ loop: env.scopes.push(scope{xs[0], env.offset, callpc, saveindex, outerindex}) env.offset += xs[1] if env.offset > len(env.values) { - vs := make([]interface{}, env.offset*2) + vs := make([]any, env.offset*2) copy(vs, env.values) env.values = vs } @@ -276,7 +270,7 @@ loop: switch v := env.pop().(type) { case []pathValue: xs = v - case []interface{}: + case []any: if !env.paths.empty() && env.expdepth == 0 && !env.pathIntact(v) { err = &invalidPathIterError{v} break loop @@ -288,7 +282,7 @@ loop: for i, v := range v { xs[i] = pathValue{path: i, value: v} } - case map[string]interface{}: + case map[string]any: if !env.paths.empty() && env.expdepth == 0 && !env.pathIntact(v) { err = &invalidPathIterError{v} break loop @@ -306,10 +300,6 @@ loop: return xs[i].path.(string) < xs[j].path.(string) }) case Iter: - if !env.paths.empty() && env.expdepth == 0 { - err = &invalidPathIterError{v} - break loop - } if w, ok := v.Next(); ok { env.push(v) env.pushfork(pc) @@ -369,11 +359,11 @@ loop: return nil, false } -func (env *env) push(v interface{}) { +func (env *env) push(v any) { env.stack.push(v) } -func (env *env) pop() interface{} { +func (env *env) pop() any { return env.stack.pop() } @@ -417,15 +407,15 @@ func (env *env) index(v [2]int) int { } type pathValue struct { - path, value interface{} + path, value any } -func (env *env) pathIntact(v interface{}) bool { +func (env *env) pathIntact(v any) bool { w := env.paths.top().(pathValue).value switch v := v.(type) { - case []interface{}, map[string]interface{}: + case []any, map[string]any: switch w.(type) { - case []interface{}, map[string]interface{}: + case []any, map[string]any: v, w := reflect.ValueOf(v), reflect.ValueOf(w) return v.Pointer() == w.Pointer() && v.Len() == w.Len() } @@ -437,8 +427,8 @@ func (env *env) pathIntact(v interface{}) bool { return v == w } -func (env *env) poppaths() []interface{} { - var xs []interface{} +func (env *env) poppaths() []any { + xs := []any{} for { p := env.paths.pop().(pathValue) if p.path == nil { diff --git a/vendor/github.com/itchyny/gojq/func.go b/vendor/github.com/itchyny/gojq/func.go index 3c3d3d1394..dcfaa5d505 100644 --- a/vendor/github.com/itchyny/gojq/func.go +++ b/vendor/github.com/itchyny/gojq/func.go @@ -3,16 +3,19 @@ package gojq import ( "encoding/base64" "encoding/json" + "errors" "fmt" "io" "math" "math/big" "net/url" + "reflect" "regexp" "sort" "strconv" "strings" "time" + "unicode" "unicode/utf8" "github.com/itchyny/timefmt-go" @@ -31,7 +34,7 @@ const ( type function struct { argcount int iter bool - callback func(interface{}, []interface{}) interface{} + callback func(any, []any) any } func (fn function) accept(cnt int) bool { @@ -48,6 +51,8 @@ func init() { "builtins": argFunc0(nil), "input": argFunc0(nil), "modulemeta": argFunc0(nil), + "debug": argFunc1(nil), + "abs": argFunc0(funcAbs), "length": argFunc0(funcLength), "utf8bytelength": argFunc0(funcUtf8ByteLength), "keys": argFunc0(funcKeys), @@ -67,14 +72,20 @@ func init() { "endswith": argFunc1(funcEndsWith), "ltrimstr": argFunc1(funcLtrimstr), "rtrimstr": argFunc1(funcRtrimstr), + "ltrim": argFunc0(funcLtrim), + "rtrim": argFunc0(funcRtrim), + "trim": argFunc0(funcTrim), "explode": argFunc0(funcExplode), "implode": argFunc0(funcImplode), "split": {argcount1 | argcount2, false, funcSplit}, + "ascii_downcase": argFunc0(funcASCIIDowncase), + "ascii_upcase": argFunc0(funcASCIIUpcase), "tojson": argFunc0(funcToJSON), "fromjson": argFunc0(funcFromJSON), "format": argFunc1(funcFormat), "_tohtml": argFunc0(funcToHTML), "_touri": argFunc0(funcToURI), + "_tourid": argFunc0(funcToURId), "_tocsv": argFunc0(funcToCSV), "_totsv": argFunc0(funcToTSV), "_tosh": argFunc0(funcToSh), @@ -122,8 +133,8 @@ func init() { "atanh": mathFunc("atanh", math.Atanh), "floor": mathFunc("floor", math.Floor), "round": mathFunc("round", math.Round), - "nearbyint": mathFunc("nearbyint", math.Round), - "rint": mathFunc("rint", math.Round), + "nearbyint": mathFunc("nearbyint", math.RoundToEven), + "rint": mathFunc("rint", math.RoundToEven), "ceil": mathFunc("ceil", math.Ceil), "trunc": mathFunc("trunc", math.Trunc), "significand": mathFunc("significand", funcSignificand), @@ -159,15 +170,14 @@ func init() { "fmod": mathFunc2("fmod", math.Mod), "hypot": mathFunc2("hypot", math.Hypot), "jn": mathFunc2("jn", funcJn), - "ldexp": mathFunc2("ldexp", funcLdexp), "nextafter": mathFunc2("nextafter", math.Nextafter), "nexttoward": mathFunc2("nexttoward", math.Nextafter), "remainder": mathFunc2("remainder", math.Remainder), - "scalb": mathFunc2("scalb", funcScalb), - "scalbln": mathFunc2("scalbln", funcScalbln), + "ldexp": mathFunc2("ldexp", funcLdexp), + "scalb": mathFunc2("scalb", funcLdexp), + "scalbln": mathFunc2("scalbln", funcLdexp), "yn": mathFunc2("yn", funcYn), "pow": mathFunc2("pow", math.Pow), - "pow10": mathFunc("pow10", funcExp10), "fma": mathFunc3("fma", math.FMA), "infinite": argFunc0(funcInfinite), "isfinite": argFunc0(funcIsfinite), @@ -195,81 +205,100 @@ func init() { } } -func argFunc0(f func(interface{}) interface{}) function { +func argFunc0(f func(any) any) function { return function{ - argcount0, false, func(v interface{}, _ []interface{}) interface{} { + argcount0, false, func(v any, _ []any) any { return f(v) }, } } -func argFunc1(f func(_, _ interface{}) interface{}) function { +func argFunc1(f func(_, _ any) any) function { return function{ - argcount1, false, func(v interface{}, args []interface{}) interface{} { + argcount1, false, func(v any, args []any) any { return f(v, args[0]) }, } } -func argFunc2(f func(_, _, _ interface{}) interface{}) function { +func argFunc2(f func(_, _, _ any) any) function { return function{ - argcount2, false, func(v interface{}, args []interface{}) interface{} { + argcount2, false, func(v any, args []any) any { return f(v, args[0], args[1]) }, } } -func argFunc3(f func(_, _, _, _ interface{}) interface{}) function { +func argFunc3(f func(_, _, _, _ any) any) function { return function{ - argcount3, false, func(v interface{}, args []interface{}) interface{} { + argcount3, false, func(v any, args []any) any { return f(v, args[0], args[1], args[2]) }, } } func mathFunc(name string, f func(float64) float64) function { - return argFunc0(func(v interface{}) interface{} { + return argFunc0(func(v any) any { x, ok := toFloat(v) if !ok { - return &funcTypeError{name, v} + return &func0TypeError{name, v} } return f(x) }) } func mathFunc2(name string, f func(_, _ float64) float64) function { - return argFunc2(func(_, x, y interface{}) interface{} { + return argFunc2(func(_, x, y any) any { l, ok := toFloat(x) if !ok { - return &funcTypeError{name, x} + return &func0TypeError{name, x} } r, ok := toFloat(y) if !ok { - return &funcTypeError{name, y} + return &func0TypeError{name, y} } return f(l, r) }) } func mathFunc3(name string, f func(_, _, _ float64) float64) function { - return argFunc3(func(_, a, b, c interface{}) interface{} { + return argFunc3(func(_, a, b, c any) any { x, ok := toFloat(a) if !ok { - return &funcTypeError{name, a} + return &func0TypeError{name, a} } y, ok := toFloat(b) if !ok { - return &funcTypeError{name, b} + return &func0TypeError{name, b} } z, ok := toFloat(c) if !ok { - return &funcTypeError{name, c} + return &func0TypeError{name, c} } return f(x, y, z) }) } -func funcLength(v interface{}) interface{} { +func funcAbs(v any) any { + switch v := v.(type) { + case int: + if v >= 0 { + return v + } + return -v + case float64: + return math.Abs(v) + case *big.Int: + if v.Sign() >= 0 { + return v + } + return new(big.Int).Abs(v) + default: + return &func0TypeError{"abs", v} + } +} + +func funcLength(v any) any { switch v := v.(type) { case nil: return 0 @@ -287,43 +316,43 @@ func funcLength(v interface{}) interface{} { return new(big.Int).Abs(v) case string: return len([]rune(v)) - case []interface{}: + case []any: return len(v) - case map[string]interface{}: + case map[string]any: return len(v) default: - return &funcTypeError{"length", v} + return &func0TypeError{"length", v} } } -func funcUtf8ByteLength(v interface{}) interface{} { +func funcUtf8ByteLength(v any) any { s, ok := v.(string) if !ok { - return &funcTypeError{"utf8bytelength", v} + return &func0TypeError{"utf8bytelength", v} } return len(s) } -func funcKeys(v interface{}) interface{} { +func funcKeys(v any) any { switch v := v.(type) { - case []interface{}: - w := make([]interface{}, len(v)) + case []any: + w := make([]any, len(v)) for i := range v { w[i] = i } return w - case map[string]interface{}: - w := make([]interface{}, len(v)) + case map[string]any: + w := make([]any, len(v)) for i, k := range keys(v) { w[i] = k } return w default: - return &funcTypeError{"keys", v} + return &func0TypeError{"keys", v} } } -func keys(v map[string]interface{}) []string { +func keys(v map[string]any) []string { w := make([]string, len(v)) var i int for k := range v { @@ -334,12 +363,12 @@ func keys(v map[string]interface{}) []string { return w } -func values(v interface{}) ([]interface{}, bool) { +func values(v any) ([]any, bool) { switch v := v.(type) { - case []interface{}: + case []any: return v, true - case map[string]interface{}: - vs := make([]interface{}, len(v)) + case map[string]any: + vs := make([]any, len(v)) for i, k := range keys(v) { vs[i] = v[k] } @@ -349,13 +378,13 @@ func values(v interface{}) ([]interface{}, bool) { } } -func funcHas(v, x interface{}) interface{} { +func funcHas(v, x any) any { switch v := v.(type) { - case []interface{}: + case []any: if x, ok := toInt(x); ok { return 0 <= x && x < len(v) } - case map[string]interface{}: + case map[string]any: if x, ok := x.(string); ok { _, ok := v[x] return ok @@ -363,52 +392,52 @@ func funcHas(v, x interface{}) interface{} { case nil: return false } - return &hasKeyTypeError{v, x} + return &func1TypeError{"has", v, x} } -func funcToEntries(v interface{}) interface{} { +func funcToEntries(v any) any { switch v := v.(type) { - case []interface{}: - w := make([]interface{}, len(v)) + case []any: + w := make([]any, len(v)) for i, x := range v { - w[i] = map[string]interface{}{"key": i, "value": x} + w[i] = map[string]any{"key": i, "value": x} } return w - case map[string]interface{}: - w := make([]interface{}, len(v)) + case map[string]any: + w := make([]any, len(v)) for i, k := range keys(v) { - w[i] = map[string]interface{}{"key": k, "value": v[k]} + w[i] = map[string]any{"key": k, "value": v[k]} } return w default: - return &funcTypeError{"to_entries", v} + return &func0TypeError{"to_entries", v} } } -func funcFromEntries(v interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcFromEntries(v any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"from_entries", v} + return &func0TypeError{"from_entries", v} } - w := make(map[string]interface{}, len(vs)) + w := make(map[string]any, len(vs)) for _, v := range vs { switch v := v.(type) { - case map[string]interface{}: + case map[string]any: var ( key string - value interface{} + value any ok bool ) for _, k := range [4]string{"key", "Key", "name", "Name"} { if k := v[k]; k != nil && k != false { if key, ok = k.(string); !ok { - return &objectKeyNotStringError{k} + return &func0WrapError{"from_entries", vs, &objectKeyNotStringError{k}} } break } } if !ok { - return &objectKeyNotStringError{nil} + return &func0WrapError{"from_entries", vs, &objectKeyNotStringError{nil}} } for _, k := range [2]string{"value", "Value"} { if value, ok = v[k]; ok { @@ -417,16 +446,16 @@ func funcFromEntries(v interface{}) interface{} { } w[key] = value default: - return &funcTypeError{"from_entries", v} + return &func0TypeError{"from_entries", v} } } return w } -func funcAdd(v interface{}) interface{} { +func funcAdd(v any) any { vs, ok := values(v) if !ok { - return &funcTypeError{"add", v} + return &func0TypeError{"add", v} } v = nil for _, x := range vs { @@ -444,27 +473,27 @@ func funcAdd(v interface{}) interface{} { w.WriteString(x) continue } - case []interface{}: + case []any: switch w := v.(type) { case nil: - s := make([]interface{}, len(x)) + s := make([]any, len(x)) copy(s, x) v = s continue - case []interface{}: + case []any: v = append(w, x...) continue } - case map[string]interface{}: + case map[string]any: switch w := v.(type) { case nil: - m := make(map[string]interface{}, len(x)) + m := make(map[string]any, len(x)) for k, e := range x { m[k] = e } v = m continue - case map[string]interface{}: + case map[string]any: for k, e := range x { w[k] = e } @@ -485,54 +514,54 @@ func funcAdd(v interface{}) interface{} { return v } -func funcToNumber(v interface{}) interface{} { +func funcToNumber(v any) any { switch v := v.(type) { case int, float64, *big.Int: return v case string: if !newLexer(v).validNumber() { - return fmt.Errorf("invalid number: %q", v) + return &func0WrapError{"tonumber", v, errors.New("invalid number")} } return toNumber(v) default: - return &funcTypeError{"tonumber", v} + return &func0TypeError{"tonumber", v} } } -func toNumber(v string) interface{} { +func toNumber(v string) any { return normalizeNumber(json.Number(v)) } -func funcToString(v interface{}) interface{} { +func funcToString(v any) any { if s, ok := v.(string); ok { return s } return funcToJSON(v) } -func funcType(v interface{}) interface{} { +func funcType(v any) any { return TypeOf(v) } -func funcReverse(v interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcReverse(v any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"reverse", v} + return &func0TypeError{"reverse", v} } - ws := make([]interface{}, len(vs)) + ws := make([]any, len(vs)) for i, v := range vs { ws[len(ws)-i-1] = v } return ws } -func funcContains(v, x interface{}) interface{} { +func funcContains(v, x any) any { return binopTypeSwitch(v, x, - func(l, r int) interface{} { return l == r }, - func(l, r float64) interface{} { return l == r }, - func(l, r *big.Int) interface{} { return l.Cmp(r) == 0 }, - func(l, r string) interface{} { return strings.Contains(l, r) }, - func(l, r []interface{}) interface{} { + func(l, r int) any { return l == r }, + func(l, r float64) any { return l == r }, + func(l, r *big.Int) any { return l.Cmp(r) == 0 }, + func(l, r string) any { return strings.Contains(l, r) }, + func(l, r []any) any { R: for _, r := range r { for _, l := range l { @@ -544,7 +573,7 @@ func funcContains(v, x interface{}) interface{} { } return true }, - func(l, r map[string]interface{}) interface{} { + func(l, r map[string]any) any { if len(l) < len(r) { return false } @@ -555,39 +584,39 @@ func funcContains(v, x interface{}) interface{} { } return true }, - func(l, r interface{}) interface{} { + func(l, r any) any { if l == r { return true } - return &containsTypeError{l, r} + return &func1TypeError{"contains", l, r} }, ) } -func funcIndices(v, x interface{}) interface{} { - return indexFunc(v, x, indices) +func funcIndices(v, x any) any { + return indexFunc("indices", v, x, indices) } -func indices(vs, xs []interface{}) interface{} { - var rs []interface{} +func indices(vs, xs []any) any { + rs := []any{} if len(xs) == 0 { return rs } for i := 0; i <= len(vs)-len(xs); i++ { - if compare(vs[i:i+len(xs)], xs) == 0 { + if Compare(vs[i:i+len(xs)], xs) == 0 { rs = append(rs, i) } } return rs } -func funcIndex(v, x interface{}) interface{} { - return indexFunc(v, x, func(vs, xs []interface{}) interface{} { +func funcIndex(v, x any) any { + return indexFunc("index", v, x, func(vs, xs []any) any { if len(xs) == 0 { return nil } for i := 0; i <= len(vs)-len(xs); i++ { - if compare(vs[i:i+len(xs)], xs) == 0 { + if Compare(vs[i:i+len(xs)], xs) == 0 { return i } } @@ -595,13 +624,13 @@ func funcIndex(v, x interface{}) interface{} { }) } -func funcRindex(v, x interface{}) interface{} { - return indexFunc(v, x, func(vs, xs []interface{}) interface{} { +func funcRindex(v, x any) any { + return indexFunc("rindex", v, x, func(vs, xs []any) any { if len(xs) == 0 { return nil } for i := len(vs) - len(xs); i >= 0; i-- { - if compare(vs[i:i+len(xs)], xs) == 0 { + if Compare(vs[i:i+len(xs)], xs) == 0 { return i } } @@ -609,85 +638,109 @@ func funcRindex(v, x interface{}) interface{} { }) } -func indexFunc(v, x interface{}, f func(_, _ []interface{}) interface{}) interface{} { +func indexFunc(name string, v, x any, f func(_, _ []any) any) any { switch v := v.(type) { case nil: return nil - case []interface{}: + case []any: switch x := x.(type) { - case []interface{}: + case []any: return f(v, x) default: - return f(v, []interface{}{x}) + return f(v, []any{x}) } case string: if x, ok := x.(string); ok { return f(explode(v), explode(x)) } - return &expectedStringError{x} + return &func1TypeError{name, v, x} default: - return &expectedArrayError{v} + return &func1TypeError{name, v, x} } } -func funcStartsWith(v, x interface{}) interface{} { +func funcStartsWith(v, x any) any { s, ok := v.(string) if !ok { - return &funcTypeError{"startswith", v} + return &func1TypeError{"startswith", v, x} } t, ok := x.(string) if !ok { - return &funcTypeError{"startswith", x} + return &func1TypeError{"startswith", v, x} } return strings.HasPrefix(s, t) } -func funcEndsWith(v, x interface{}) interface{} { +func funcEndsWith(v, x any) any { s, ok := v.(string) if !ok { - return &funcTypeError{"endswith", v} + return &func1TypeError{"endswith", v, x} } t, ok := x.(string) if !ok { - return &funcTypeError{"endswith", x} + return &func1TypeError{"endswith", v, x} } return strings.HasSuffix(s, t) } -func funcLtrimstr(v, x interface{}) interface{} { +func funcLtrimstr(v, x any) any { s, ok := v.(string) if !ok { - return v + return &func1TypeError{"ltrimstr", v, x} } t, ok := x.(string) if !ok { - return v + return &func1TypeError{"ltrimstr", v, x} } return strings.TrimPrefix(s, t) } -func funcRtrimstr(v, x interface{}) interface{} { +func funcRtrimstr(v, x any) any { s, ok := v.(string) if !ok { - return v + return &func1TypeError{"rtrimstr", v, x} } t, ok := x.(string) if !ok { - return v + return &func1TypeError{"rtrimstr", v, x} } return strings.TrimSuffix(s, t) } -func funcExplode(v interface{}) interface{} { +func funcLtrim(v any) any { s, ok := v.(string) if !ok { - return &funcTypeError{"explode", v} + return &func0TypeError{"ltrim", v} + } + return strings.TrimLeftFunc(s, unicode.IsSpace) +} + +func funcRtrim(v any) any { + s, ok := v.(string) + if !ok { + return &func0TypeError{"rtrim", v} + } + return strings.TrimRightFunc(s, unicode.IsSpace) +} + +func funcTrim(v any) any { + s, ok := v.(string) + if !ok { + return &func0TypeError{"trim", v} + } + return strings.TrimSpace(s) +} + +func funcExplode(v any) any { + s, ok := v.(string) + if !ok { + return &func0TypeError{"explode", v} } return explode(s) } -func explode(s string) []interface{} { - xs := make([]interface{}, len([]rune(s))) +func explode(s string) []any { + xs := make([]any, len([]rune(s))) var i int for _, r := range s { xs[i] = int(r) @@ -696,31 +749,35 @@ func explode(s string) []interface{} { return xs } -func funcImplode(v interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcImplode(v any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"implode", v} + return &func0TypeError{"implode", v} } var sb strings.Builder sb.Grow(len(vs)) for _, v := range vs { - if r, ok := toInt(v); ok && 0 <= r && r <= utf8.MaxRune { - sb.WriteRune(rune(r)) + if r, ok := toInt(v); ok { + if 0 <= r && r <= utf8.MaxRune { + sb.WriteRune(rune(r)) + } else { + sb.WriteRune(utf8.RuneError) + } } else { - return &funcTypeError{"implode", vs} + return &func0TypeError{"implode", vs} } } return sb.String() } -func funcSplit(v interface{}, args []interface{}) interface{} { +func funcSplit(v any, args []any) any { s, ok := v.(string) if !ok { - return &funcTypeError{"split", v} + return &func0TypeError{"split", v} } x, ok := args[0].(string) if !ok { - return &funcTypeError{"split", x} + return &func0TypeError{"split", x} } var ss []string if len(args) == 1 { @@ -730,7 +787,7 @@ func funcSplit(v interface{}, args []interface{}) interface{} { if args[1] != nil { v, ok := args[1].(string) if !ok { - return &funcTypeError{"split", args[1]} + return &func0TypeError{"split", args[1]} } flags = v } @@ -740,43 +797,69 @@ func funcSplit(v interface{}, args []interface{}) interface{} { } ss = r.Split(s, -1) } - xs := make([]interface{}, len(ss)) + xs := make([]any, len(ss)) for i, s := range ss { xs[i] = s } return xs } -func funcToJSON(v interface{}) interface{} { +func funcASCIIDowncase(v any) any { + s, ok := v.(string) + if !ok { + return &func0TypeError{"ascii_downcase", v} + } + return strings.Map(func(r rune) rune { + if 'A' <= r && r <= 'Z' { + return r + ('a' - 'A') + } + return r + }, s) +} + +func funcASCIIUpcase(v any) any { + s, ok := v.(string) + if !ok { + return &func0TypeError{"ascii_upcase", v} + } + return strings.Map(func(r rune) rune { + if 'a' <= r && r <= 'z' { + return r - ('a' - 'A') + } + return r + }, s) +} + +func funcToJSON(v any) any { return jsonMarshal(v) } -func funcFromJSON(v interface{}) interface{} { +func funcFromJSON(v any) any { s, ok := v.(string) if !ok { - return &funcTypeError{"fromjson", v} + return &func0TypeError{"fromjson", v} } - var w interface{} + var w any dec := json.NewDecoder(strings.NewReader(s)) dec.UseNumber() if err := dec.Decode(&w); err != nil { - return err + return &func0WrapError{"fromjson", v, err} } if _, err := dec.Token(); err != io.EOF { - return &funcTypeError{"fromjson", v} + return &func0TypeError{"fromjson", v} } return normalizeNumbers(w) } -func funcFormat(v, x interface{}) interface{} { +func funcFormat(v, x any) any { s, ok := x.(string) if !ok { - return &funcTypeError{"format", x} + return &func0TypeError{"format", x} } - fmt := "@" + s - f := formatToFunc(fmt) + format := "@" + s + f := formatToFunc(format) if f == nil { - return &formatNotFoundError{fmt} + return &formatNotFoundError{format} } return internalFuncs[f.Name].callback(v, nil) } @@ -789,7 +872,7 @@ var htmlEscaper = strings.NewReplacer( `"`, """, ) -func funcToHTML(v interface{}) interface{} { +func funcToHTML(v any) any { switch x := funcToString(v).(type) { case string: return htmlEscaper.Replace(x) @@ -798,18 +881,36 @@ func funcToHTML(v interface{}) interface{} { } } -func funcToURI(v interface{}) interface{} { +func funcToURI(v any) any { switch x := funcToString(v).(type) { case string: - return url.QueryEscape(x) + return strings.ReplaceAll(url.QueryEscape(x), "+", "%20") default: return x } } -func funcToCSV(v interface{}) interface{} { +func funcToURId(v any) any { + switch x := funcToString(v).(type) { + case string: + x, err := url.QueryUnescape(strings.ReplaceAll(x, "+", "%2B")) + if err != nil { + return &func0WrapError{"@urid", v, err} + } + return x + default: + return x + } +} + +var csvEscaper = strings.NewReplacer( + `"`, `""`, + "\x00", `\0`, +) + +func funcToCSV(v any) any { return formatJoin("csv", v, ",", func(s string) string { - return `"` + strings.ReplaceAll(s, `"`, `""`) + `"` + return `"` + csvEscaper.Replace(s) + `"` }) } @@ -818,30 +919,36 @@ var tsvEscaper = strings.NewReplacer( "\r", `\r`, "\n", `\n`, "\\", `\\`, + "\x00", `\0`, ) -func funcToTSV(v interface{}) interface{} { +func funcToTSV(v any) any { return formatJoin("tsv", v, "\t", tsvEscaper.Replace) } -func funcToSh(v interface{}) interface{} { - if _, ok := v.([]interface{}); !ok { - v = []interface{}{v} +var shEscaper = strings.NewReplacer( + "'", `'\''`, + "\x00", `\0`, +) + +func funcToSh(v any) any { + if _, ok := v.([]any); !ok { + v = []any{v} } return formatJoin("sh", v, " ", func(s string) string { - return "'" + strings.ReplaceAll(s, "'", `'\''`) + "'" + return "'" + shEscaper.Replace(s) + "'" }) } -func formatJoin(typ string, v interface{}, sep string, escape func(string) string) interface{} { - vs, ok := v.([]interface{}) +func formatJoin(typ string, v any, sep string, escape func(string) string) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"@" + typ, v} + return &func0TypeError{"@" + typ, v} } ss := make([]string, len(vs)) for i, v := range vs { switch v := v.(type) { - case []interface{}, map[string]interface{}: + case []any, map[string]any: return &formatRowError{typ, v} case string: ss[i] = escape(v) @@ -854,7 +961,7 @@ func formatJoin(typ string, v interface{}, sep string, escape func(string) strin return strings.Join(ss, sep) } -func funcToBase64(v interface{}) interface{} { +func funcToBase64(v any) any { switch x := funcToString(v).(type) { case string: return base64.StdEncoding.EncodeToString([]byte(x)) @@ -863,7 +970,7 @@ func funcToBase64(v interface{}) interface{} { } } -func funcToBase64d(v interface{}) interface{} { +func funcToBase64d(v any) any { switch x := funcToString(v).(type) { case string: if i := strings.IndexRune(x, base64.StdPadding); i >= 0 { @@ -871,7 +978,7 @@ func funcToBase64d(v interface{}) interface{} { } y, err := base64.RawStdEncoding.DecodeString(x) if err != nil { - return err + return &func0WrapError{"@base64d", v, err} } return string(y) default: @@ -879,13 +986,13 @@ func funcToBase64d(v interface{}) interface{} { } } -func funcIndex2(_, v, x interface{}) interface{} { +func funcIndex2(_, v, x any) any { switch x := x.(type) { case string: switch v := v.(type) { case nil: return nil - case map[string]interface{}: + case map[string]any: return v[x] default: return &expectedObjectError{v} @@ -895,23 +1002,23 @@ func funcIndex2(_, v, x interface{}) interface{} { switch v := v.(type) { case nil: return nil - case []interface{}: + case []any: return index(v, i) case string: return indexString(v, i) default: return &expectedArrayError{v} } - case []interface{}: + case []any: switch v := v.(type) { case nil: return nil - case []interface{}: + case []any: return indices(v, x) default: return &expectedArrayError{v} } - case map[string]interface{}: + case map[string]any: if v == nil { return nil } @@ -926,7 +1033,7 @@ func funcIndex2(_, v, x interface{}) interface{} { return funcSlice(nil, v, end, start) default: switch v.(type) { - case []interface{}: + case []any: return &arrayIndexNotNumberError{x} case string: return &stringIndexNotNumberError{x} @@ -936,7 +1043,7 @@ func funcIndex2(_, v, x interface{}) interface{} { } } -func index(vs []interface{}, i int) interface{} { +func index(vs []any, i int) any { i = clampIndex(i, -1, len(vs)) if 0 <= i && i < len(vs) { return vs[i] @@ -944,7 +1051,7 @@ func index(vs []interface{}, i int) interface{} { return nil } -func indexString(s string, i int) interface{} { +func indexString(s string, i int) any { l := len([]rune(s)) i = clampIndex(i, -1, l) if 0 <= i && i < l { @@ -957,11 +1064,11 @@ func indexString(s string, i int) interface{} { return nil } -func funcSlice(_, v, e, s interface{}) (r interface{}) { +func funcSlice(_, v, e, s any) (r any) { switch v := v.(type) { case nil: return nil - case []interface{}: + case []any: return slice(v, e, s) case string: return sliceString(v, e, s) @@ -970,7 +1077,7 @@ func funcSlice(_, v, e, s interface{}) (r interface{}) { } } -func slice(vs []interface{}, e, s interface{}) interface{} { +func slice(vs []any, e, s any) any { var start, end int if s != nil { if i, ok := toInt(s); ok { @@ -991,7 +1098,7 @@ func slice(vs []interface{}, e, s interface{}) interface{} { return vs[start:end] } -func sliceString(v string, e, s interface{}) interface{} { +func sliceString(v string, e, s any) any { var start, end int l := len([]rune(v)) if s != nil { @@ -1046,10 +1153,10 @@ func clampIndex(i, min, max int) int { } } -func funcFlatten(v interface{}, args []interface{}) interface{} { +func funcFlatten(v any, args []any) any { vs, ok := values(v) if !ok { - return &funcTypeError{"flatten", v} + return &func0TypeError{"flatten", v} } var depth float64 if len(args) == 0 { @@ -1057,18 +1164,18 @@ func funcFlatten(v interface{}, args []interface{}) interface{} { } else { depth, ok = toFloat(args[0]) if !ok { - return &funcTypeError{"flatten", args[0]} + return &func0TypeError{"flatten", args[0]} } if depth < 0 { return &flattenDepthError{depth} } } - return flatten(nil, vs, depth) + return flatten([]any{}, vs, depth) } -func flatten(xs, vs []interface{}, depth float64) []interface{} { +func flatten(xs, vs []any, depth float64) []any { for _, v := range vs { - if vs, ok := v.([]interface{}); ok && depth != 0 { + if vs, ok := v.([]any); ok && depth != 0 { xs = flatten(xs, vs, depth-1) } else { xs = append(xs, v) @@ -1078,11 +1185,11 @@ func flatten(xs, vs []interface{}, depth float64) []interface{} { } type rangeIter struct { - value, end, step interface{} + value, end, step any } -func (iter *rangeIter) Next() (interface{}, bool) { - if compare(iter.step, 0)*compare(iter.value, iter.end) >= 0 { +func (iter *rangeIter) Next() (any, bool) { + if Compare(iter.step, 0)*Compare(iter.value, iter.end) >= 0 { return nil, false } v := iter.value @@ -1090,70 +1197,70 @@ func (iter *rangeIter) Next() (interface{}, bool) { return v, true } -func funcRange(_ interface{}, xs []interface{}) interface{} { +func funcRange(_ any, xs []any) any { for _, x := range xs { switch x.(type) { case int, float64, *big.Int: default: - return &funcTypeError{"range", x} + return &func0TypeError{"range", x} } } return &rangeIter{xs[0], xs[1], xs[2]} } -func funcMin(v interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcMin(v any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"min", v} + return &func0TypeError{"min", v} } return minMaxBy(vs, vs, true) } -func funcMinBy(v, x interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcMinBy(v, x any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"min_by", v} + return &func1TypeError{"min_by", v, x} } - xs, ok := x.([]interface{}) + xs, ok := x.([]any) if !ok { - return &funcTypeError{"min_by", x} + return &func1TypeError{"min_by", v, x} } if len(vs) != len(xs) { - return &lengthMismatchError{"min_by", vs, xs} + return &func1WrapError{"min_by", v, x, &lengthMismatchError{}} } return minMaxBy(vs, xs, true) } -func funcMax(v interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcMax(v any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"max", v} + return &func0TypeError{"max", v} } return minMaxBy(vs, vs, false) } -func funcMaxBy(v, x interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcMaxBy(v, x any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"max_by", v} + return &func1TypeError{"max_by", v, x} } - xs, ok := x.([]interface{}) + xs, ok := x.([]any) if !ok { - return &funcTypeError{"max_by", x} + return &func1TypeError{"max_by", v, x} } if len(vs) != len(xs) { - return &lengthMismatchError{"max_by", vs, xs} + return &func1WrapError{"max_by", v, x, &lengthMismatchError{}} } return minMaxBy(vs, xs, false) } -func minMaxBy(vs, xs []interface{}, isMin bool) interface{} { +func minMaxBy(vs, xs []any, isMin bool) any { if len(vs) == 0 { return nil } i, j, x := 0, 0, xs[0] for i++; i < len(xs); i++ { - if compare(x, xs[i]) > 0 == isMin { + if Compare(x, xs[i]) > 0 == isMin { j, x = i, xs[i] } } @@ -1161,102 +1268,105 @@ func minMaxBy(vs, xs []interface{}, isMin bool) interface{} { } type sortItem struct { - value, key interface{} + value, key any } -func sortItems(name string, v, x interface{}) ([]*sortItem, error) { - vs, ok := v.([]interface{}) +func sortItems(name string, v, x any) ([]*sortItem, error) { + vs, ok := v.([]any) if !ok { - return nil, &funcTypeError{name, v} + if strings.HasSuffix(name, "_by") { + return nil, &func1TypeError{name, v, x} + } + return nil, &func0TypeError{name, v} } - xs, ok := x.([]interface{}) + xs, ok := x.([]any) if !ok { - return nil, &funcTypeError{name, x} + return nil, &func1TypeError{name, v, x} } if len(vs) != len(xs) { - return nil, &lengthMismatchError{name, vs, xs} + return nil, &func1WrapError{name, v, x, &lengthMismatchError{}} } items := make([]*sortItem, len(vs)) for i, v := range vs { items[i] = &sortItem{v, xs[i]} } sort.SliceStable(items, func(i, j int) bool { - return compare(items[i].key, items[j].key) < 0 + return Compare(items[i].key, items[j].key) < 0 }) return items, nil } -func funcSort(v interface{}) interface{} { +func funcSort(v any) any { return sortBy("sort", v, v) } -func funcSortBy(v, x interface{}) interface{} { +func funcSortBy(v, x any) any { return sortBy("sort_by", v, x) } -func sortBy(name string, v, x interface{}) interface{} { +func sortBy(name string, v, x any) any { items, err := sortItems(name, v, x) if err != nil { return err } - rs := make([]interface{}, len(items)) + rs := make([]any, len(items)) for i, x := range items { rs[i] = x.value } return rs } -func funcGroupBy(v, x interface{}) interface{} { +func funcGroupBy(v, x any) any { items, err := sortItems("group_by", v, x) if err != nil { return err } - var rs []interface{} - var last interface{} + rs := []any{} + var last any for i, r := range items { - if i == 0 || compare(last, r.key) != 0 { - rs, last = append(rs, []interface{}{r.value}), r.key + if i == 0 || Compare(last, r.key) != 0 { + rs, last = append(rs, []any{r.value}), r.key } else { - rs[len(rs)-1] = append(rs[len(rs)-1].([]interface{}), r.value) + rs[len(rs)-1] = append(rs[len(rs)-1].([]any), r.value) } } return rs } -func funcUnique(v interface{}) interface{} { +func funcUnique(v any) any { return uniqueBy("unique", v, v) } -func funcUniqueBy(v, x interface{}) interface{} { +func funcUniqueBy(v, x any) any { return uniqueBy("unique_by", v, x) } -func uniqueBy(name string, v, x interface{}) interface{} { +func uniqueBy(name string, v, x any) any { items, err := sortItems(name, v, x) if err != nil { return err } - var rs []interface{} - var last interface{} + rs := []any{} + var last any for i, r := range items { - if i == 0 || compare(last, r.key) != 0 { + if i == 0 || Compare(last, r.key) != 0 { rs, last = append(rs, r.value), r.key } } return rs } -func funcJoin(v, x interface{}) interface{} { +func funcJoin(v, x any) any { vs, ok := values(v) if !ok { - return &funcTypeError{"join", v} + return &func1TypeError{"join", v, x} } if len(vs) == 0 { return "" } sep, ok := x.(string) if len(vs) > 1 && !ok { - return &funcTypeError{"join", x} + return &func1TypeError{"join", v, x} } ss := make([]string, len(vs)) for i, v := range vs { @@ -1290,22 +1400,22 @@ func funcExp10(v float64) float64 { return math.Pow(10, v) } -func funcFrexp(v interface{}) interface{} { +func funcFrexp(v any) any { x, ok := toFloat(v) if !ok { - return &funcTypeError{"frexp", v} + return &func0TypeError{"frexp", v} } f, e := math.Frexp(x) - return []interface{}{f, e} + return []any{f, e} } -func funcModf(v interface{}) interface{} { +func funcModf(v any) any { x, ok := toFloat(v) if !ok { - return &funcTypeError{"modf", v} + return &func0TypeError{"modf", v} } i, f := math.Modf(x) - return []interface{}{f, i} + return []any{f, i} } func funcLgamma(v float64) float64 { @@ -1329,90 +1439,137 @@ func funcLdexp(l, r float64) float64 { return math.Ldexp(l, int(r)) } -func funcScalb(l, r float64) float64 { - return l * math.Pow(2, r) -} - -func funcScalbln(l, r float64) float64 { - return l * math.Pow(2, r) -} - func funcYn(l, r float64) float64 { return math.Yn(int(l), r) } -func funcInfinite(interface{}) interface{} { +func funcInfinite(any) any { return math.Inf(1) } -func funcIsfinite(v interface{}) interface{} { +func funcIsfinite(v any) any { x, ok := toFloat(v) return ok && !math.IsInf(x, 0) } -func funcIsinfinite(v interface{}) interface{} { +func funcIsinfinite(v any) any { x, ok := toFloat(v) return ok && math.IsInf(x, 0) } -func funcNan(interface{}) interface{} { +func funcNan(any) any { return math.NaN() } -func funcIsnan(v interface{}) interface{} { +func funcIsnan(v any) any { x, ok := toFloat(v) if !ok { if v == nil { return false } - return &funcTypeError{"isnan", v} + return &func0TypeError{"isnan", v} } return math.IsNaN(x) } -func funcIsnormal(v interface{}) interface{} { - x, ok := toFloat(v) - return ok && !math.IsNaN(x) && !math.IsInf(x, 0) && x != 0.0 +func funcIsnormal(v any) any { + if v, ok := toFloat(v); ok { + e := math.Float64bits(v) & 0x7ff0000000000000 >> 52 + return 0 < e && e < 0x7ff + } + return false } -func funcSetpath(v, p, n interface{}) interface{} { - path, ok := p.([]interface{}) - if !ok { - return &funcTypeError{"setpath", p} +// An `allocator` creates new maps and slices, stores the allocated addresses. +// This allocator is used to reduce allocations on assignment operator (`=`), +// update-assignment operator (`|=`), and the `map_values`, `del`, `delpaths` +// functions. +type allocator map[uintptr]struct{} + +func funcAllocator(any, []any) any { + return allocator{} +} + +func (a allocator) allocated(v any) bool { + _, ok := a[reflect.ValueOf(v).Pointer()] + return ok +} + +func (a allocator) makeObject(l int) map[string]any { + v := make(map[string]any, l) + if a != nil { + a[reflect.ValueOf(v).Pointer()] = struct{}{} } - var err error - if v, err = update(v, path, n); err != nil { - if err, ok := err.(*funcTypeError); ok { - err.name = "setpath" - } - return err + return v +} + +func (a allocator) makeArray(l, c int) []any { + v := make([]any, l, max(l, c)) + if a != nil { + a[reflect.ValueOf(v).Pointer()] = struct{}{} } return v } -func funcDelpaths(v, p interface{}) interface{} { - paths, ok := p.([]interface{}) +func funcSetpath(v, p, n any) any { + // There is no need to use an allocator on a single update. + return setpath(v, p, n, nil) +} + +// Used in compiler#compileAssign and compiler#compileModify. +func funcSetpathWithAllocator(v any, args []any) any { + return setpath(v, args[0], args[1], args[2].(allocator)) +} + +func setpath(v, p, n any, a allocator) any { + path, ok := p.([]any) if !ok { - return &funcTypeError{"delpaths", p} + return &func1TypeError{"setpath", v, p} + } + u, err := update(v, path, n, a) + if err != nil { + return &func2WrapError{"setpath", v, p, n, err} + } + return u +} + +func funcDelpaths(v, p any) any { + return delpaths(v, p, allocator{}) +} + +// Used in compiler#compileAssign and compiler#compileModify. +func funcDelpathsWithAllocator(v any, args []any) any { + return delpaths(v, args[0], args[1].(allocator)) +} + +func delpaths(v, p any, a allocator) any { + paths, ok := p.([]any) + if !ok { + return &func1TypeError{"delpaths", v, p} + } + if len(paths) == 0 { + return v } // Fills the paths with an empty value and then delete them. We cannot delete // in each loop because array indices should not change. For example, // jq -n "[0, 1, 2, 3] | delpaths([[1], [2]])" #=> [0, 3]. var empty struct{} var err error - for _, p := range paths { - path, ok := p.([]interface{}) + u := v + for _, q := range paths { + path, ok := q.([]any) if !ok { - return &funcTypeError{"delpaths", p} + return &func1WrapError{"delpaths", v, p, &expectedArrayError{q}} } - if v, err = update(v, path, empty); err != nil { - return err + u, err = update(u, path, empty, a) + if err != nil { + return &func1WrapError{"delpaths", v, p, err} } } - return deleteEmpty(v) + return deleteEmpty(u) } -func update(v interface{}, path []interface{}, n interface{}) (interface{}, error) { +func update(v any, path []any, n any, a allocator) (any, error) { if len(path) == 0 { return n, nil } @@ -1420,9 +1577,9 @@ func update(v interface{}, path []interface{}, n interface{}) (interface{}, erro case string: switch v := v.(type) { case nil: - return updateObject(nil, p, path[1:], n) - case map[string]interface{}: - return updateObject(v, p, path[1:], n) + return updateObject(nil, p, path[1:], n, a) + case map[string]any: + return updateObject(v, p, path[1:], n, a) case struct{}: return v, nil default: @@ -1432,20 +1589,20 @@ func update(v interface{}, path []interface{}, n interface{}) (interface{}, erro i, _ := toInt(p) switch v := v.(type) { case nil: - return updateArrayIndex(nil, i, path[1:], n) - case []interface{}: - return updateArrayIndex(v, i, path[1:], n) + return updateArrayIndex(nil, i, path[1:], n, a) + case []any: + return updateArrayIndex(v, i, path[1:], n, a) case struct{}: return v, nil default: return nil, &expectedArrayError{v} } - case map[string]interface{}: + case map[string]any: switch v := v.(type) { case nil: - return updateArraySlice(nil, p, path[1:], n) - case []interface{}: - return updateArraySlice(v, p, path[1:], n) + return updateArraySlice(nil, p, path[1:], n, a) + case []any: + return updateArraySlice(v, p, path[1:], n, a) case struct{}: return v, nil default: @@ -1453,7 +1610,7 @@ func update(v interface{}, path []interface{}, n interface{}) (interface{}, erro } default: switch v.(type) { - case []interface{}: + case []any: return nil, &arrayIndexNotNumberError{p} default: return nil, &objectKeyNotStringError{p} @@ -1461,16 +1618,20 @@ func update(v interface{}, path []interface{}, n interface{}) (interface{}, erro } } -func updateObject(v map[string]interface{}, k string, path []interface{}, n interface{}) (interface{}, error) { +func updateObject(v map[string]any, k string, path []any, n any, a allocator) (any, error) { x, ok := v[k] if !ok && n == struct{}{} { return v, nil } - u, err := update(x, path, n) + u, err := update(x, path, n, a) if err != nil { return nil, err } - w := make(map[string]interface{}, len(v)+1) + if a.allocated(v) { + v[k] = u + return v, nil + } + w := a.makeObject(len(v) + 1) for k, v := range v { w[k] = v } @@ -1478,13 +1639,13 @@ func updateObject(v map[string]interface{}, k string, path []interface{}, n inte return w, nil } -func updateArrayIndex(v []interface{}, i int, path []interface{}, n interface{}) (interface{}, error) { - var x interface{} +func updateArrayIndex(v []any, i int, path []any, n any, a allocator) (any, error) { + var x any if j := clampIndex(i, -1, len(v)); j < 0 { if n == struct{}{} { return v, nil } - return nil, &funcTypeError{v: i} + return nil, &arrayIndexNegativeError{i} } else if j < len(v) { i = j x = v[i] @@ -1496,21 +1657,31 @@ func updateArrayIndex(v []interface{}, i int, path []interface{}, n interface{}) return nil, &arrayIndexTooLargeError{i} } } - u, err := update(x, path, n) + u, err := update(x, path, n, a) if err != nil { return nil, err } - l := len(v) + l, c := len(v), cap(v) + if a.allocated(v) { + if i < c { + if i >= l { + v = v[:i+1] + } + v[i] = u + return v, nil + } + c *= 2 + } if i >= l { l = i + 1 } - w := make([]interface{}, l) + w := a.makeArray(l, c) copy(w, v) w[i] = u return w, nil } -func updateArraySlice(v []interface{}, m map[string]interface{}, path []interface{}, n interface{}) (interface{}, error) { +func updateArraySlice(v []any, m map[string]any, path []any, n any, a allocator) (any, error) { s, ok := m["start"] if !ok { return nil, &expectedStartEndError{m} @@ -1531,20 +1702,30 @@ func updateArraySlice(v []interface{}, m map[string]interface{}, path []interfac if start == end && n == struct{}{} { return v, nil } - u, err := update(v[start:end], path, n) + u, err := update(v[start:end], path, n, a) if err != nil { return nil, err } switch u := u.(type) { - case []interface{}: - w := make([]interface{}, len(v)-(end-start)+len(u)) - copy(w, v[:start]) + case []any: + var w []any + if len(u) == end-start && a.allocated(v) { + w = v + } else { + w = a.makeArray(len(v)-(end-start)+len(u), 0) + copy(w, v[:start]) + copy(w[start+len(u):], v[end:]) + } copy(w[start:], u) - copy(w[start+len(u):], v[end:]) return w, nil case struct{}: - w := make([]interface{}, len(v)) - copy(w, v) + var w []any + if a.allocated(v) { + w = v + } else { + w = a.makeArray(len(v), 0) + copy(w, v) + } for i := start; i < end; i++ { w[i] = u } @@ -1554,11 +1735,11 @@ func updateArraySlice(v []interface{}, m map[string]interface{}, path []interfac } } -func deleteEmpty(v interface{}) interface{} { +func deleteEmpty(v any) any { switch v := v.(type) { case struct{}: return nil - case map[string]interface{}: + case map[string]any: for k, w := range v { if w == struct{}{} { delete(v, k) @@ -1567,7 +1748,7 @@ func deleteEmpty(v interface{}) interface{} { } } return v - case []interface{}: + case []any: var j int for _, w := range v { if w != struct{}{} { @@ -1584,90 +1765,90 @@ func deleteEmpty(v interface{}) interface{} { } } -func funcGetpath(v, p interface{}) interface{} { - keys, ok := p.([]interface{}) +func funcGetpath(v, p any) any { + path, ok := p.([]any) if !ok { - return &funcTypeError{"getpath", p} + return &func1TypeError{"getpath", v, p} } u := v - for _, x := range keys { + for _, x := range path { switch v.(type) { - case nil, []interface{}, map[string]interface{}: + case nil, []any, map[string]any: v = funcIndex2(nil, v, x) - if _, ok := v.(error); ok { - return &getpathError{u, p} + if err, ok := v.(error); ok { + return &func1WrapError{"getpath", u, p, err} } default: - return &getpathError{u, p} + return &func1TypeError{"getpath", u, p} } } return v } -func funcTranspose(v interface{}) interface{} { - vss, ok := v.([]interface{}) +func funcTranspose(v any) any { + vss, ok := v.([]any) if !ok { - return &funcTypeError{"transpose", v} + return &func0TypeError{"transpose", v} } if len(vss) == 0 { - return []interface{}{} + return []any{} } var l int for _, vs := range vss { - vs, ok := vs.([]interface{}) + vs, ok := vs.([]any) if !ok { - return &funcTypeError{"transpose", v} + return &func0TypeError{"transpose", v} } if k := len(vs); l < k { l = k } } - wss := make([][]interface{}, l) - xs := make([]interface{}, l) + wss := make([][]any, l) + xs := make([]any, l) for i, k := 0, len(vss); i < l; i++ { - s := make([]interface{}, k) + s := make([]any, k) wss[i] = s xs[i] = s } for i, vs := range vss { - for j, v := range vs.([]interface{}) { + for j, v := range vs.([]any) { wss[j][i] = v } } return xs } -func funcBsearch(v, t interface{}) interface{} { - vs, ok := v.([]interface{}) +func funcBsearch(v, t any) any { + vs, ok := v.([]any) if !ok { - return &funcTypeError{"bsearch", v} + return &func1TypeError{"bsearch", v, t} } i := sort.Search(len(vs), func(i int) bool { - return compare(vs[i], t) >= 0 + return Compare(vs[i], t) >= 0 }) - if i < len(vs) && compare(vs[i], t) == 0 { + if i < len(vs) && Compare(vs[i], t) == 0 { return i } return -i - 1 } -func funcGmtime(v interface{}) interface{} { +func funcGmtime(v any) any { if v, ok := toFloat(v); ok { return epochToArray(v, time.UTC) } - return &funcTypeError{"gmtime", v} + return &func0TypeError{"gmtime", v} } -func funcLocaltime(v interface{}) interface{} { +func funcLocaltime(v any) any { if v, ok := toFloat(v); ok { return epochToArray(v, time.Local) } - return &funcTypeError{"localtime", v} + return &func0TypeError{"localtime", v} } -func epochToArray(v float64, loc *time.Location) []interface{} { +func epochToArray(v float64, loc *time.Location) []any { t := time.Unix(int64(v), int64((v-math.Floor(v))*1e9)).In(loc) - return []interface{}{ + return []any{ t.Year(), int(t.Month()) - 1, t.Day(), @@ -1679,133 +1860,132 @@ func epochToArray(v float64, loc *time.Location) []interface{} { } } -func funcMktime(v interface{}) interface{} { - if a, ok := v.([]interface{}); ok { - t, err := arrayToTime("mktime", a, time.UTC) - if err != nil { - return err - } - return timeToEpoch(t) +func funcMktime(v any) any { + a, ok := v.([]any) + if !ok { + return &func0TypeError{"mktime", v} + } + t, err := arrayToTime(a, time.UTC) + if err != nil { + return &func0WrapError{"mktime", v, err} } - return &funcTypeError{"mktime", v} + return timeToEpoch(t) } func timeToEpoch(t time.Time) float64 { return float64(t.Unix()) + float64(t.Nanosecond())/1e9 } -func funcStrftime(v, x interface{}) interface{} { +func funcStrftime(v, x any) any { if w, ok := toFloat(v); ok { v = epochToArray(w, time.UTC) } - if a, ok := v.([]interface{}); ok { - if format, ok := x.(string); ok { - t, err := arrayToTime("strftime", a, time.UTC) - if err != nil { - return err - } - return timefmt.Format(t, format) - } - return &funcTypeError{"strftime", x} + a, ok := v.([]any) + if !ok { + return &func1TypeError{"strftime", v, x} } - return &funcTypeError{"strftime", v} + format, ok := x.(string) + if !ok { + return &func1TypeError{"strftime", v, x} + } + t, err := arrayToTime(a, time.UTC) + if err != nil { + return &func1WrapError{"strftime", v, x, err} + } + return timefmt.Format(t, format) } -func funcStrflocaltime(v, x interface{}) interface{} { +func funcStrflocaltime(v, x any) any { if w, ok := toFloat(v); ok { v = epochToArray(w, time.Local) } - if a, ok := v.([]interface{}); ok { - if format, ok := x.(string); ok { - t, err := arrayToTime("strflocaltime", a, time.Local) - if err != nil { - return err - } - return timefmt.Format(t, format) - } - return &funcTypeError{"strflocaltime", x} + a, ok := v.([]any) + if !ok { + return &func1TypeError{"strflocaltime", v, x} } - return &funcTypeError{"strflocaltime", v} -} - -func funcStrptime(v, x interface{}) interface{} { - if v, ok := v.(string); ok { - if format, ok := x.(string); ok { - t, err := timefmt.Parse(v, format) - if err != nil { - return err - } - var s time.Time - if t == s { - return &funcTypeError{"strptime", v} - } - return epochToArray(timeToEpoch(t), time.UTC) - } - return &funcTypeError{"strptime", x} + format, ok := x.(string) + if !ok { + return &func1TypeError{"strflocaltime", v, x} } - return &funcTypeError{"strptime", v} + t, err := arrayToTime(a, time.Local) + if err != nil { + return &func1WrapError{"strflocaltime", v, x, err} + } + return timefmt.Format(t, format) } -func arrayToTime(name string, a []interface{}, loc *time.Location) (time.Time, error) { - var t time.Time - if len(a) != 8 { - return t, &funcTypeError{name, a} - } - var y, m, d, h, min, sec, nsec int - if x, ok := toInt(a[0]); ok { - y = x - } else { - return t, &funcTypeError{name, a} - } - if x, ok := toInt(a[1]); ok { - m = x + 1 - } else { - return t, &funcTypeError{name, a} +func funcStrptime(v, x any) any { + s, ok := v.(string) + if !ok { + return &func1TypeError{"strptime", v, x} } - if x, ok := toInt(a[2]); ok { - d = x - } else { - return t, &funcTypeError{name, a} + format, ok := x.(string) + if !ok { + return &func1TypeError{"strptime", v, x} } - if x, ok := toInt(a[3]); ok { - h = x - } else { - return t, &funcTypeError{name, a} + t, err := timefmt.Parse(s, format) + if err != nil { + return &func1WrapError{"strptime", v, x, err} } - if x, ok := toInt(a[4]); ok { - min = x - } else { - return t, &funcTypeError{name, a} + var u time.Time + if t == u { + return &func1TypeError{"strptime", v, x} } - if x, ok := toFloat(a[5]); ok { - sec = int(x) - nsec = int((x - math.Floor(x)) * 1e9) - } else { - return t, &funcTypeError{name, a} + return epochToArray(timeToEpoch(t), time.UTC) +} + +func arrayToTime(a []any, loc *time.Location) (time.Time, error) { + var t time.Time + var year, month, day, hour, minute, + second, nanosecond, weekday, yearday int + for i, p := range []*int{ + &year, &month, &day, &hour, &minute, + &second, &weekday, &yearday, + } { + if i >= len(a) { + break + } + if i == 5 { + if v, ok := toFloat(a[i]); ok { + *p = int(v) + nanosecond = int((v - math.Floor(v)) * 1e9) + } else { + return t, &timeArrayError{} + } + } else if v, ok := toInt(a[i]); ok { + *p = v + } else { + return t, &timeArrayError{} + } } - return time.Date(y, time.Month(m), d, h, min, sec, nsec, loc), nil + return time.Date(year, time.Month(month+1), day, + hour, minute, second, nanosecond, loc), nil } -func funcNow(interface{}) interface{} { +func funcNow(any) any { return timeToEpoch(time.Now()) } -func funcMatch(v, re, fs, testing interface{}) interface{} { +func funcMatch(v, re, fs, testing any) any { + name := "match" + if testing == true { + name = "test" + } var flags string if fs != nil { v, ok := fs.(string) if !ok { - return &funcTypeError{"match", fs} + return &func2TypeError{name, v, re, fs} } flags = v } s, ok := v.(string) if !ok { - return &funcTypeError{"match", v} + return &func2TypeError{name, v, re, fs} } restr, ok := re.(string) if !ok { - return &funcTypeError{"match", v} + return &func2TypeError{name, v, re, fs} } r, err := compileRegexp(restr, flags) if err != nil { @@ -1823,16 +2003,16 @@ func funcMatch(v, re, fs, testing interface{}) interface{} { xs = [][]int{got} } } - res, names := make([]interface{}, len(xs)), r.SubexpNames() + res, names := make([]any, len(xs)), r.SubexpNames() for i, x := range xs { - captures := make([]interface{}, (len(x)-2)/2) + captures := make([]any, (len(x)-2)/2) for j := 1; j < len(x)/2; j++ { - var name interface{} + var name any if n := names[j]; n != "" { name = n } if x[j*2] < 0 { - captures[j-1] = map[string]interface{}{ + captures[j-1] = map[string]any{ "name": name, "offset": -1, "length": 0, @@ -1840,14 +2020,14 @@ func funcMatch(v, re, fs, testing interface{}) interface{} { } continue } - captures[j-1] = map[string]interface{}{ + captures[j-1] = map[string]any{ "name": name, "offset": len([]rune(s[:x[j*2]])), "length": len([]rune(s[:x[j*2+1]])) - len([]rune(s[:x[j*2]])), "string": s[x[j*2]:x[j*2+1]], } } - res[i] = map[string]interface{}{ + res[i] = map[string]any{ "offset": len([]rune(s[:x[0]])), "length": len([]rune(s[:x[1]])) - len([]rune(s[:x[0]])), "string": s[x[0]:x[1]], @@ -1877,19 +2057,19 @@ func compileRegexp(re, flags string) (*regexp.Regexp, error) { return r, nil } -func funcCapture(v interface{}) interface{} { - vs, ok := v.(map[string]interface{}) +func funcCapture(v any) any { + vs, ok := v.(map[string]any) if !ok { return &expectedObjectError{v} } v = vs["captures"] - captures, ok := v.([]interface{}) + captures, ok := v.([]any) if !ok { return &expectedArrayError{v} } - w := make(map[string]interface{}, len(captures)) + w := make(map[string]any, len(captures)) for _, capture := range captures { - if capture, ok := capture.(map[string]interface{}); ok { + if capture, ok := capture.(map[string]any); ok { if name, ok := capture["name"].(string); ok { w[name] = capture["string"] } @@ -1898,33 +2078,29 @@ func funcCapture(v interface{}) interface{} { return w } -func funcError(v interface{}, args []interface{}) interface{} { +func funcError(v any, args []any) any { if len(args) > 0 { v = args[0] } - code := 5 - if v == nil { - code = 0 - } - return &exitCodeError{v, code, false} + return &exitCodeError{v, 5} } -func funcHalt(interface{}) interface{} { - return &exitCodeError{nil, 0, true} +func funcHalt(any) any { + return &HaltError{nil, 0} } -func funcHaltError(v interface{}, args []interface{}) interface{} { +func funcHaltError(v any, args []any) any { code := 5 if len(args) > 0 { var ok bool if code, ok = toInt(args[0]); !ok { - return &funcTypeError{"halt_error", args[0]} + return &func0TypeError{"halt_error", args[0]} } } - return &exitCodeError{v, code, true} + return &HaltError{v, code} } -func toInt(x interface{}) (int, bool) { +func toInt(x any) (int, bool) { switch x := x.(type) { case int: return x, true @@ -1955,7 +2131,7 @@ func floatToInt(x float64) int { return math.MinInt } -func toFloat(x interface{}) (float64, bool) { +func toFloat(x any) (float64, bool) { switch x := x.(type) { case int: return float64(x), true diff --git a/vendor/github.com/itchyny/gojq/go.dev.mod b/vendor/github.com/itchyny/gojq/go.dev.mod index 36c59f81b5..bdc69df6f0 100644 --- a/vendor/github.com/itchyny/gojq/go.dev.mod +++ b/vendor/github.com/itchyny/gojq/go.dev.mod @@ -1,8 +1,8 @@ module github.com/itchyny/gojq -go 1.17 +go 1.21 require ( - github.com/itchyny/astgen-go v0.0.0-20210914105503-cc8fccf6f972 // indirect - github.com/itchyny/timefmt-go v0.1.4 // indirect + github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b // indirect + github.com/itchyny/timefmt-go v0.1.6 // indirect ) diff --git a/vendor/github.com/itchyny/gojq/go.dev.sum b/vendor/github.com/itchyny/gojq/go.dev.sum index 33b70d4422..e8691b822f 100644 --- a/vendor/github.com/itchyny/gojq/go.dev.sum +++ b/vendor/github.com/itchyny/gojq/go.dev.sum @@ -1,4 +1,4 @@ -github.com/itchyny/astgen-go v0.0.0-20210914105503-cc8fccf6f972 h1:XYWolmPDLTY9B1O5o/Ad811/mtVkaHWMiZdbPLm/nDA= -github.com/itchyny/astgen-go v0.0.0-20210914105503-cc8fccf6f972/go.mod h1:jTXcxGeQMJfFN3wWjtzb4aAaWDDN+QbezE0HjH1XfNk= -github.com/itchyny/timefmt-go v0.1.4 h1:hFEfWVdwsEi+CY8xY2FtgWHGQaBaC3JeHd+cve0ynVM= -github.com/itchyny/timefmt-go v0.1.4/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= +github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b h1:72fDU7wad+r3iQObaxhlXVIpAIMRUIUMrNa3go1vb8s= +github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b/go.mod h1:Zp6xzEWVc2pQ/ObfLD6t/M6gDegsJWKdGKJSiT7qlu0= +github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= +github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= diff --git a/vendor/github.com/itchyny/gojq/iter.go b/vendor/github.com/itchyny/gojq/iter.go index 9ee5ad64a0..d0bed96063 100644 --- a/vendor/github.com/itchyny/gojq/iter.go +++ b/vendor/github.com/itchyny/gojq/iter.go @@ -2,11 +2,11 @@ package gojq // Iter is an interface for an iterator. type Iter interface { - Next() (interface{}, bool) + Next() (any, bool) } // NewIter creates a new [Iter] from values. -func NewIter(values ...interface{}) Iter { +func NewIter(values ...any) Iter { switch len(values) { case 0: return emptyIter{} @@ -20,16 +20,16 @@ func NewIter(values ...interface{}) Iter { type emptyIter struct{} -func (emptyIter) Next() (interface{}, bool) { +func (emptyIter) Next() (any, bool) { return nil, false } type unitIter struct { - value interface{} + value any done bool } -func (iter *unitIter) Next() (interface{}, bool) { +func (iter *unitIter) Next() (any, bool) { if iter.done { return nil, false } @@ -37,9 +37,9 @@ func (iter *unitIter) Next() (interface{}, bool) { return iter.value, true } -type sliceIter []interface{} +type sliceIter []any -func (iter *sliceIter) Next() (interface{}, bool) { +func (iter *sliceIter) Next() (any, bool) { if len(*iter) == 0 { return nil, false } diff --git a/vendor/github.com/itchyny/gojq/lexer.go b/vendor/github.com/itchyny/gojq/lexer.go index 82bb2b6b9c..0c2efd122c 100644 --- a/vendor/github.com/itchyny/gojq/lexer.go +++ b/vendor/github.com/itchyny/gojq/lexer.go @@ -235,7 +235,8 @@ func (l *lexer) Lex(lval *yySymType) (tokenType int) { default: if ch >= utf8.RuneSelf { r, size := utf8.DecodeRuneInString(l.source[l.offset-1:]) - l.offset += size + // -1 to adjust for first byte consumed by next() + l.offset += size - 1 l.token = string(r) } } @@ -247,15 +248,9 @@ func (l *lexer) next() (byte, bool) { ch := l.source[l.offset] l.offset++ if ch == '#' { - if len(l.source) == l.offset { + if l.skipComment() { return 0, true } - for !isNewLine(l.source[l.offset]) { - l.offset++ - if len(l.source) == l.offset { - return 0, true - } - } } else if !isWhite(ch) { return ch, false } else if len(l.source) == l.offset { @@ -264,6 +259,28 @@ func (l *lexer) next() (byte, bool) { } } +func (l *lexer) skipComment() bool { + for { + switch l.peek() { + case 0: + return true + case '\\': + switch l.offset++; l.peek() { + case '\\', '\n': + l.offset++ + case '\r': + if l.offset++; l.peek() == '\n' { + l.offset++ + } + } + case '\n', '\r': + return false + default: + l.offset++ + } + } +} + func (l *lexer) peek() byte { if len(l.source) == l.offset { return 0 @@ -505,37 +522,34 @@ func quoteAndEscape(src string, quote bool, controls int) []byte { return buf } -type parseError struct { - offset int - token string +// ParseError represents a description of a query parsing error. +type ParseError struct { + Offset int // the error occurred after reading Offset bytes + Token string // the Token that caused the error (may be empty) tokenType int } -func (err *parseError) Error() string { +func (err *ParseError) Error() string { switch err.tokenType { case eof: return "unexpected EOF" case tokInvalid: - return "invalid token " + jsonMarshal(err.token) + return "invalid token " + jsonMarshal(err.Token) case tokInvalidEscapeSequence: - return `invalid escape sequence "` + err.token + `" in string literal` + return `invalid escape sequence "` + err.Token + `" in string literal` case tokUnterminatedString: return "unterminated string literal" default: - return "unexpected token " + jsonMarshal(err.token) + return "unexpected token " + jsonMarshal(err.Token) } } -func (err *parseError) Token() (string, int) { - return err.token, err.offset -} - func (l *lexer) Error(string) { offset, token := l.offset, l.token if l.tokenType != eof && l.tokenType < utf8.RuneSelf { token = string(rune(l.tokenType)) } - l.err = &parseError{offset, token, l.tokenType} + l.err = &ParseError{offset, token, l.tokenType} } func isWhite(ch byte) bool { @@ -562,12 +576,3 @@ func isHex(ch byte) bool { func isNumber(ch byte) bool { return '0' <= ch && ch <= '9' } - -func isNewLine(ch byte) bool { - switch ch { - case '\n', '\r': - return true - default: - return false - } -} diff --git a/vendor/github.com/itchyny/gojq/module_loader.go b/vendor/github.com/itchyny/gojq/module_loader.go index fff442d93e..0e3d1af034 100644 --- a/vendor/github.com/itchyny/gojq/module_loader.go +++ b/vendor/github.com/itchyny/gojq/module_loader.go @@ -13,16 +13,24 @@ import ( // // Implement following optional methods. Use [NewModuleLoader] to load local modules. // -// LoadModule(string) (*Query, error) -// LoadModuleWithMeta(string, map[string]interface{}) (*Query, error) // LoadInitModules() ([]*Query, error) -// LoadJSON(string) (interface{}, error) -// LoadJSONWithMeta(string, map[string]interface{}) (interface{}, error) -type ModuleLoader interface{} +// LoadModule(string) (*Query, error) +// LoadModuleWithMeta(string, map[string]any) (*Query, error) +// LoadJSON(string) (any, error) +// LoadJSONWithMeta(string, map[string]any) (any, error) +type ModuleLoader any -// NewModuleLoader creates a new [ModuleLoader] reading local modules in the paths. +// NewModuleLoader creates a new [ModuleLoader] loading local modules in the paths. +// Note that user can load modules outside the paths using "search" path of metadata. +// Empty paths are ignored, so specify "." for the current working directory. func NewModuleLoader(paths []string) ModuleLoader { - return &moduleLoader{expandHomeDir(paths)} + ps := make([]string, 0, len(paths)) + for _, path := range paths { + if path = resolvePath(path, ""); path != "" { + ps = append(ps, path) + } + } + return &moduleLoader{ps} } type moduleLoader struct { @@ -49,7 +57,7 @@ func (l *moduleLoader) LoadInitModules() ([]*Query, error) { if err != nil { return nil, err } - q, err := parseModule(path, string(cnt)) + q, err := parseModule(string(cnt), filepath.Dir(path)) if err != nil { return nil, &queryParseError{path, string(cnt), err} } @@ -58,7 +66,7 @@ func (l *moduleLoader) LoadInitModules() ([]*Query, error) { return qs, nil } -func (l *moduleLoader) LoadModuleWithMeta(name string, meta map[string]interface{}) (*Query, error) { +func (l *moduleLoader) LoadModuleWithMeta(name string, meta map[string]any) (*Query, error) { path, err := l.lookupModule(name, ".jq", meta) if err != nil { return nil, err @@ -67,14 +75,14 @@ func (l *moduleLoader) LoadModuleWithMeta(name string, meta map[string]interface if err != nil { return nil, err } - q, err := parseModule(path, string(cnt)) + q, err := parseModule(string(cnt), filepath.Dir(path)) if err != nil { return nil, &queryParseError{path, string(cnt), err} } return q, nil } -func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]interface{}) (interface{}, error) { +func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]any) (any, error) { path, err := l.lookupModule(name, ".json", meta) if err != nil { return nil, err @@ -84,11 +92,11 @@ func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]interface{} return nil, err } defer f.Close() - var vals []interface{} + vals := []any{} dec := json.NewDecoder(f) dec.UseNumber() for { - var val interface{} + var val any if err := dec.Decode(&val); err != nil { if err == io.EOF { break @@ -107,17 +115,19 @@ func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]interface{} return vals, nil } -func (l *moduleLoader) lookupModule(name, extension string, meta map[string]interface{}) (string, error) { +func (l *moduleLoader) lookupModule(name, extension string, meta map[string]any) (string, error) { paths := l.paths - if path := searchPath(meta); path != "" { - paths = append([]string{path}, paths...) + if path, ok := meta["search"].(string); ok { + if path = resolvePath(path, ""); path != "" { + paths = append([]string{path}, paths...) + } } for _, base := range paths { - path := filepath.Clean(filepath.Join(base, name+extension)) + path := filepath.Join(base, name+extension) if _, err := os.Stat(path); err == nil { return path, err } - path = filepath.Clean(filepath.Join(base, name, filepath.Base(name)+extension)) + path = filepath.Join(base, name, filepath.Base(name)+extension) if _, err := os.Stat(path); err == nil { return path, err } @@ -125,66 +135,50 @@ func (l *moduleLoader) lookupModule(name, extension string, meta map[string]inte return "", fmt.Errorf("module not found: %q", name) } -// This is a dirty hack to implement the "search" field. -func parseModule(path, cnt string) (*Query, error) { +func parseModule(cnt, dir string) (*Query, error) { q, err := Parse(cnt) if err != nil { return nil, err } for _, i := range q.Imports { - if i.Meta == nil { - continue + if i.Meta != nil { + for _, e := range i.Meta.KeyVals { + if e.Key == "search" || e.KeyString == "search" { + if path, ok := e.Val.toString(); ok { + if path = resolvePath(path, dir); path != "" { + e.Val.Str = path + } else { + e.Val.Null = true + } + } + } + } } - i.Meta.KeyVals = append( - i.Meta.KeyVals, - &ConstObjectKeyVal{ - Key: "$$path", - Val: &ConstTerm{Str: path}, - }, - ) } return q, nil } -func searchPath(meta map[string]interface{}) string { - x, ok := meta["search"] - if !ok { - return "" - } - s, ok := x.(string) - if !ok { - return "" - } - if filepath.IsAbs(s) { - return s - } - if strings.HasPrefix(s, "~") { - if homeDir, err := os.UserHomeDir(); err == nil { - return filepath.Join(homeDir, s[1:]) +func resolvePath(path, dir string) string { + switch { + case filepath.IsAbs(path): + return path + case strings.HasPrefix(path, "~/"): + dir, err := os.UserHomeDir() + if err != nil { + return "" } - } - var path string - if x, ok := meta["$$path"]; ok { - path, _ = x.(string) - } - if path == "" { - return s - } - return filepath.Join(filepath.Dir(path), s) -} - -func expandHomeDir(paths []string) []string { - var homeDir string - var err error - for i, path := range paths { - if strings.HasPrefix(path, "~") { - if homeDir == "" && err == nil { - homeDir, err = os.UserHomeDir() - } - if homeDir != "" { - paths[i] = filepath.Join(homeDir, path[1:]) - } + return filepath.Join(dir, path[2:]) + case strings.HasPrefix(path, "$ORIGIN/"): + exe, err := os.Executable() + if err != nil { + return "" + } + exe, err = filepath.EvalSymlinks(exe) + if err != nil { + return "" } + return filepath.Join(filepath.Dir(exe), path[8:]) + default: + return filepath.Join(dir, path) } - return paths } diff --git a/vendor/github.com/itchyny/gojq/normalize.go b/vendor/github.com/itchyny/gojq/normalize.go index bd0ddda905..2bfcd21569 100644 --- a/vendor/github.com/itchyny/gojq/normalize.go +++ b/vendor/github.com/itchyny/gojq/normalize.go @@ -7,7 +7,7 @@ import ( "strings" ) -func normalizeNumber(v json.Number) interface{} { +func normalizeNumber(v json.Number) any { if i, err := v.Int64(); err == nil && math.MinInt <= i && i <= math.MaxInt { return int(i) } @@ -25,7 +25,7 @@ func normalizeNumber(v json.Number) interface{} { return math.Inf(1) } -func normalizeNumbers(v interface{}) interface{} { +func normalizeNumbers(v any) any { switch v := v.(type) { case json.Number: return normalizeNumber(v) @@ -68,12 +68,12 @@ func normalizeNumbers(v interface{}) interface{} { return int(v) case float32: return float64(v) - case []interface{}: + case []any: for i, x := range v { v[i] = normalizeNumbers(x) } return v - case map[string]interface{}: + case map[string]any: for k, x := range v { v[k] = normalizeNumbers(x) } diff --git a/vendor/github.com/itchyny/gojq/operator.go b/vendor/github.com/itchyny/gojq/operator.go index 071b3d64cb..64b74b7805 100644 --- a/vendor/github.com/itchyny/gojq/operator.go +++ b/vendor/github.com/itchyny/gojq/operator.go @@ -208,14 +208,14 @@ func (op Operator) getFunc() string { } func binopTypeSwitch( - l, r interface{}, - callbackInts func(_, _ int) interface{}, - callbackFloats func(_, _ float64) interface{}, - callbackBigInts func(_, _ *big.Int) interface{}, - callbackStrings func(_, _ string) interface{}, - callbackArrays func(_, _ []interface{}) interface{}, - callbackMaps func(_, _ map[string]interface{}) interface{}, - fallback func(_, _ interface{}) interface{}) interface{} { + l, r any, + callbackInts func(_, _ int) any, + callbackFloats func(_, _ float64) any, + callbackBigInts func(_, _ *big.Int) any, + callbackStrings func(_, _ string) any, + callbackArrays func(_, _ []any) any, + callbackMaps func(_, _ map[string]any) any, + fallback func(_, _ any) any) any { switch l := l.(type) { case int: switch r := r.(type) { @@ -257,16 +257,16 @@ func binopTypeSwitch( default: return fallback(l, r) } - case []interface{}: + case []any: switch r := r.(type) { - case []interface{}: + case []any: return callbackArrays(l, r) default: return fallback(l, r) } - case map[string]interface{}: + case map[string]any: switch r := r.(type) { - case map[string]interface{}: + case map[string]any: return callbackMaps(l, r) default: return fallback(l, r) @@ -276,7 +276,7 @@ func binopTypeSwitch( } } -func funcOpPlus(v interface{}) interface{} { +func funcOpPlus(v any) any { switch v := v.(type) { case int: return v @@ -289,7 +289,7 @@ func funcOpPlus(v interface{}) interface{} { } } -func funcOpNegate(v interface{}) interface{} { +func funcOpNegate(v any) any { switch v := v.(type) { case int: return -v @@ -302,38 +302,38 @@ func funcOpNegate(v interface{}) interface{} { } } -func funcOpAdd(_, l, r interface{}) interface{} { +func funcOpAdd(_, l, r any) any { return binopTypeSwitch(l, r, - func(l, r int) interface{} { + func(l, r int) any { if v := l + r; (v >= l) == (r >= 0) { return v } x, y := big.NewInt(int64(l)), big.NewInt(int64(r)) return x.Add(x, y) }, - func(l, r float64) interface{} { return l + r }, - func(l, r *big.Int) interface{} { return new(big.Int).Add(l, r) }, - func(l, r string) interface{} { return l + r }, - func(l, r []interface{}) interface{} { + func(l, r float64) any { return l + r }, + func(l, r *big.Int) any { return new(big.Int).Add(l, r) }, + func(l, r string) any { return l + r }, + func(l, r []any) any { if len(l) == 0 { return r } if len(r) == 0 { return l } - v := make([]interface{}, len(l)+len(r)) + v := make([]any, len(l)+len(r)) copy(v, l) copy(v[len(l):], r) return v }, - func(l, r map[string]interface{}) interface{} { + func(l, r map[string]any) any { if len(l) == 0 { return r } if len(r) == 0 { return l } - m := make(map[string]interface{}, len(l)+len(r)) + m := make(map[string]any, len(l)+len(r)) for k, v := range l { m[k] = v } @@ -342,7 +342,7 @@ func funcOpAdd(_, l, r interface{}) interface{} { } return m }, - func(l, r interface{}) interface{} { + func(l, r any) any { if l == nil { return r } @@ -354,24 +354,24 @@ func funcOpAdd(_, l, r interface{}) interface{} { ) } -func funcOpSub(_, l, r interface{}) interface{} { +func funcOpSub(_, l, r any) any { return binopTypeSwitch(l, r, - func(l, r int) interface{} { + func(l, r int) any { if v := l - r; (v <= l) == (r >= 0) { return v } x, y := big.NewInt(int64(l)), big.NewInt(int64(r)) return x.Sub(x, y) }, - func(l, r float64) interface{} { return l - r }, - func(l, r *big.Int) interface{} { return new(big.Int).Sub(l, r) }, - func(l, r string) interface{} { return &binopTypeError{"subtract", l, r} }, - func(l, r []interface{}) interface{} { - v := make([]interface{}, 0, len(l)) + func(l, r float64) any { return l - r }, + func(l, r *big.Int) any { return new(big.Int).Sub(l, r) }, + func(l, r string) any { return &binopTypeError{"subtract", l, r} }, + func(l, r []any) any { + v := make([]any, 0, len(l)) L: for _, l := range l { for _, r := range r { - if compare(l, r) == 0 { + if Compare(l, r) == 0 { continue L } } @@ -379,26 +379,26 @@ func funcOpSub(_, l, r interface{}) interface{} { } return v }, - func(l, r map[string]interface{}) interface{} { return &binopTypeError{"subtract", l, r} }, - func(l, r interface{}) interface{} { return &binopTypeError{"subtract", l, r} }, + func(l, r map[string]any) any { return &binopTypeError{"subtract", l, r} }, + func(l, r any) any { return &binopTypeError{"subtract", l, r} }, ) } -func funcOpMul(_, l, r interface{}) interface{} { +func funcOpMul(_, l, r any) any { return binopTypeSwitch(l, r, - func(l, r int) interface{} { + func(l, r int) any { if v := l * r; r == 0 || v/r == l { return v } x, y := big.NewInt(int64(l)), big.NewInt(int64(r)) return x.Mul(x, y) }, - func(l, r float64) interface{} { return l * r }, - func(l, r *big.Int) interface{} { return new(big.Int).Mul(l, r) }, - func(l, r string) interface{} { return &binopTypeError{"multiply", l, r} }, - func(l, r []interface{}) interface{} { return &binopTypeError{"multiply", l, r} }, + func(l, r float64) any { return l * r }, + func(l, r *big.Int) any { return new(big.Int).Mul(l, r) }, + func(l, r string) any { return &binopTypeError{"multiply", l, r} }, + func(l, r []any) any { return &binopTypeError{"multiply", l, r} }, deepMergeObjects, - func(l, r interface{}) interface{} { + func(l, r any) any { if l, ok := l.(string); ok { if r, ok := toFloat(r); ok { return repeatString(l, r) @@ -414,15 +414,15 @@ func funcOpMul(_, l, r interface{}) interface{} { ) } -func deepMergeObjects(l, r map[string]interface{}) interface{} { - m := make(map[string]interface{}, len(l)+len(r)) +func deepMergeObjects(l, r map[string]any) any { + m := make(map[string]any, len(l)+len(r)) for k, v := range l { m[k] = v } for k, v := range r { if mk, ok := m[k]; ok { - if mk, ok := mk.(map[string]interface{}); ok { - if w, ok := v.(map[string]interface{}); ok { + if mk, ok := mk.(map[string]any); ok { + if w, ok := v.(map[string]any); ok { v = deepMergeObjects(mk, w) } } @@ -432,23 +432,20 @@ func deepMergeObjects(l, r map[string]interface{}) interface{} { return m } -func repeatString(s string, n float64) interface{} { - if n <= 0.0 || len(s) > 0 && n > float64(0x10000000/len(s)) || math.IsNaN(n) { +func repeatString(s string, n float64) any { + if n < 0.0 || len(s) > 0 && n > float64(0x10000000/len(s)) || math.IsNaN(n) { return nil } - if n < 1.0 { - return s + if s == "" { + return "" } return strings.Repeat(s, int(n)) } -func funcOpDiv(_, l, r interface{}) interface{} { +func funcOpDiv(_, l, r any) any { return binopTypeSwitch(l, r, - func(l, r int) interface{} { + func(l, r int) any { if r == 0 { - if l == 0 { - return math.NaN() - } return &zeroDivisionError{l, r} } if l%r == 0 { @@ -456,20 +453,14 @@ func funcOpDiv(_, l, r interface{}) interface{} { } return float64(l) / float64(r) }, - func(l, r float64) interface{} { + func(l, r float64) any { if r == 0.0 { - if l == 0.0 { - return math.NaN() - } return &zeroDivisionError{l, r} } return l / r }, - func(l, r *big.Int) interface{} { + func(l, r *big.Int) any { if r.Sign() == 0 { - if l.Sign() == 0 { - return math.NaN() - } return &zeroDivisionError{l, r} } d, m := new(big.Int).DivMod(l, r, new(big.Int)) @@ -478,78 +469,81 @@ func funcOpDiv(_, l, r interface{}) interface{} { } return bigToFloat(l) / bigToFloat(r) }, - func(l, r string) interface{} { + func(l, r string) any { if l == "" { - return []interface{}{} + return []any{} } xs := strings.Split(l, r) - vs := make([]interface{}, len(xs)) + vs := make([]any, len(xs)) for i, x := range xs { vs[i] = x } return vs }, - func(l, r []interface{}) interface{} { return &binopTypeError{"divide", l, r} }, - func(l, r map[string]interface{}) interface{} { return &binopTypeError{"divide", l, r} }, - func(l, r interface{}) interface{} { return &binopTypeError{"divide", l, r} }, + func(l, r []any) any { return &binopTypeError{"divide", l, r} }, + func(l, r map[string]any) any { return &binopTypeError{"divide", l, r} }, + func(l, r any) any { return &binopTypeError{"divide", l, r} }, ) } -func funcOpMod(_, l, r interface{}) interface{} { +func funcOpMod(_, l, r any) any { return binopTypeSwitch(l, r, - func(l, r int) interface{} { + func(l, r int) any { if r == 0 { return &zeroModuloError{l, r} } return l % r }, - func(l, r float64) interface{} { + func(l, r float64) any { ri := floatToInt(r) if ri == 0 { return &zeroModuloError{l, r} } + if math.IsNaN(l) || math.IsNaN(r) { + return math.NaN() + } return floatToInt(l) % ri }, - func(l, r *big.Int) interface{} { + func(l, r *big.Int) any { if r.Sign() == 0 { return &zeroModuloError{l, r} } return new(big.Int).Rem(l, r) }, - func(l, r string) interface{} { return &binopTypeError{"modulo", l, r} }, - func(l, r []interface{}) interface{} { return &binopTypeError{"modulo", l, r} }, - func(l, r map[string]interface{}) interface{} { return &binopTypeError{"modulo", l, r} }, - func(l, r interface{}) interface{} { return &binopTypeError{"modulo", l, r} }, + func(l, r string) any { return &binopTypeError{"modulo", l, r} }, + func(l, r []any) any { return &binopTypeError{"modulo", l, r} }, + func(l, r map[string]any) any { return &binopTypeError{"modulo", l, r} }, + func(l, r any) any { return &binopTypeError{"modulo", l, r} }, ) } -func funcOpAlt(_, l, r interface{}) interface{} { +func funcOpAlt(_, l, r any) any { if l == nil || l == false { return r } return l } -func funcOpEq(_, l, r interface{}) interface{} { - return compare(l, r) == 0 +func funcOpEq(_, l, r any) any { + return Compare(l, r) == 0 } -func funcOpNe(_, l, r interface{}) interface{} { - return compare(l, r) != 0 +func funcOpNe(_, l, r any) any { + return Compare(l, r) != 0 } -func funcOpGt(_, l, r interface{}) interface{} { - return compare(l, r) > 0 +func funcOpGt(_, l, r any) any { + return Compare(l, r) > 0 } -func funcOpLt(_, l, r interface{}) interface{} { - return compare(l, r) < 0 +func funcOpLt(_, l, r any) any { + return Compare(l, r) < 0 } -func funcOpGe(_, l, r interface{}) interface{} { - return compare(l, r) >= 0 +func funcOpGe(_, l, r any) any { + return Compare(l, r) >= 0 } -func funcOpLe(_, l, r interface{}) interface{} { - return compare(l, r) <= 0 +func funcOpLe(_, l, r any) any { + return Compare(l, r) <= 0 } diff --git a/vendor/github.com/itchyny/gojq/option.go b/vendor/github.com/itchyny/gojq/option.go index 6ccfa9b3bd..f1a110fae3 100644 --- a/vendor/github.com/itchyny/gojq/option.go +++ b/vendor/github.com/itchyny/gojq/option.go @@ -39,8 +39,7 @@ func WithVariables(variables []string) CompilerOption { // function. If you want to emit multiple values, call the empty function, // accept a filter for its argument, or call another built-in function, then // use LoadInitModules of the module loader. -func WithFunction(name string, minarity, maxarity int, - f func(interface{}, []interface{}) interface{}) CompilerOption { +func WithFunction(name string, minarity, maxarity int, f func(any, []any) any) CompilerOption { return withFunction(name, minarity, maxarity, false, f) } @@ -49,17 +48,15 @@ func WithFunction(name string, minarity, maxarity int, // returns an Iter to emit multiple values. You cannot define both iterator and // non-iterator functions of the same name (with possibly different arities). // See also [NewIter], which can be used to convert values or an error to an Iter. -func WithIterFunction(name string, minarity, maxarity int, - f func(interface{}, []interface{}) Iter) CompilerOption { +func WithIterFunction(name string, minarity, maxarity int, f func(any, []any) Iter) CompilerOption { return withFunction(name, minarity, maxarity, true, - func(v interface{}, args []interface{}) interface{} { + func(v any, args []any) any { return f(v, args) }, ) } -func withFunction(name string, minarity, maxarity int, iter bool, - f func(interface{}, []interface{}) interface{}) CompilerOption { +func withFunction(name string, minarity, maxarity int, iter bool, f func(any, []any) any) CompilerOption { if !(0 <= minarity && minarity <= maxarity && maxarity <= 30) { panic(fmt.Sprintf("invalid arity for %q: %d, %d", name, minarity, maxarity)) } @@ -74,7 +71,7 @@ func withFunction(name string, minarity, maxarity int, iter bool, } c.customFuncs[name] = function{ argcount | fn.argcount, iter, - func(x interface{}, xs []interface{}) interface{} { + func(x any, xs []any) any { if argcount&(1< 0 { - return nil, l.err - } - return l.result, nil -} - func reverseFuncDef(xs []*FuncDef) []*FuncDef { for i, j := 0, len(xs)-1; i < j; i, j = i+1, j-1 { xs[i], xs[j] = xs[j], xs[i] @@ -35,10 +21,10 @@ func prependFuncDef(xs []*FuncDef, x *FuncDef) []*FuncDef { return xs } -//line parser.go.y:33 +//line parser.go.y:19 type yySymType struct { yys int - value interface{} + value any token string operator Operator } @@ -46,9 +32,9 @@ type yySymType struct { const tokAltOp = 57346 const tokUpdateOp = 57347 const tokDestAltOp = 57348 -const tokOrOp = 57349 -const tokAndOp = 57350 -const tokCompareOp = 57351 +const tokCompareOp = 57349 +const tokOrOp = 57350 +const tokAndOp = 57351 const tokModule = 57352 const tokImport = 57353 const tokInclude = 57354 @@ -59,33 +45,34 @@ const tokBreak = 57358 const tokNull = 57359 const tokTrue = 57360 const tokFalse = 57361 -const tokIdent = 57362 -const tokVariable = 57363 -const tokModuleIdent = 57364 -const tokModuleVariable = 57365 -const tokIndex = 57366 -const tokNumber = 57367 -const tokFormat = 57368 -const tokString = 57369 -const tokStringStart = 57370 -const tokStringQuery = 57371 -const tokStringEnd = 57372 -const tokIf = 57373 -const tokThen = 57374 -const tokElif = 57375 -const tokElse = 57376 -const tokEnd = 57377 -const tokTry = 57378 -const tokCatch = 57379 -const tokReduce = 57380 -const tokForeach = 57381 -const tokRecurse = 57382 -const tokFuncDefPost = 57383 -const tokTermPost = 57384 -const tokEmptyCatch = 57385 -const tokInvalid = 57386 -const tokInvalidEscapeSequence = 57387 -const tokUnterminatedString = 57388 +const tokIf = 57362 +const tokThen = 57363 +const tokElif = 57364 +const tokElse = 57365 +const tokEnd = 57366 +const tokTry = 57367 +const tokCatch = 57368 +const tokReduce = 57369 +const tokForeach = 57370 +const tokIdent = 57371 +const tokVariable = 57372 +const tokModuleIdent = 57373 +const tokModuleVariable = 57374 +const tokRecurse = 57375 +const tokIndex = 57376 +const tokNumber = 57377 +const tokFormat = 57378 +const tokString = 57379 +const tokStringStart = 57380 +const tokStringQuery = 57381 +const tokStringEnd = 57382 +const tokInvalid = 57383 +const tokInvalidEscapeSequence = 57384 +const tokUnterminatedString = 57385 +const tokFuncDefQuery = 57386 +const tokExpr = 57387 +const tokTerm = 57388 +const tokEmptyCatch = 57389 var yyToknames = [...]string{ "$end", @@ -94,9 +81,9 @@ var yyToknames = [...]string{ "tokAltOp", "tokUpdateOp", "tokDestAltOp", + "tokCompareOp", "tokOrOp", "tokAndOp", - "tokCompareOp", "tokModule", "tokImport", "tokInclude", @@ -107,10 +94,20 @@ var yyToknames = [...]string{ "tokNull", "tokTrue", "tokFalse", + "tokIf", + "tokThen", + "tokElif", + "tokElse", + "tokEnd", + "tokTry", + "tokCatch", + "tokReduce", + "tokForeach", "tokIdent", "tokVariable", "tokModuleIdent", "tokModuleVariable", + "tokRecurse", "tokIndex", "tokNumber", "tokFormat", @@ -118,22 +115,12 @@ var yyToknames = [...]string{ "tokStringStart", "tokStringQuery", "tokStringEnd", - "tokIf", - "tokThen", - "tokElif", - "tokElse", - "tokEnd", - "tokTry", - "tokCatch", - "tokReduce", - "tokForeach", - "tokRecurse", - "tokFuncDefPost", - "tokTermPost", - "tokEmptyCatch", "tokInvalid", "tokInvalidEscapeSequence", "tokUnterminatedString", + "tokFuncDefQuery", + "tokExpr", + "tokTerm", "'|'", "','", "'+'", @@ -143,6 +130,7 @@ var yyToknames = [...]string{ "'%'", "'.'", "'?'", + "tokEmptyCatch", "'['", "';'", "':'", @@ -159,218 +147,181 @@ const yyEofCode = 1 const yyErrCode = 2 const yyInitialStackSize = 16 -//line parser.go.y:693 +//line parser.go.y:671 //line yacctab:1 var yyExca = [...]int16{ -1, 1, 1, -1, -2, 0, - -1, 97, - 55, 0, - -2, 104, - -1, 130, + -1, 145, 5, 0, - -2, 32, - -1, 133, - 9, 0, - -2, 35, - -1, 194, - 58, 114, - -2, 54, + -2, 27, + -1, 148, + 7, 0, + -2, 30, + -1, 199, + 59, 114, + -2, 49, } const yyPrivate = 57344 -const yyLast = 1127 +const yyLast = 782 var yyAct = [...]int16{ - 86, 214, 174, 112, 12, 203, 9, 175, 111, 31, - 190, 6, 156, 140, 117, 47, 95, 97, 93, 94, - 89, 141, 49, 7, 179, 180, 181, 240, 246, 264, - 239, 103, 177, 106, 178, 227, 164, 119, 107, 108, - 105, 245, 102, 75, 76, 113, 77, 78, 79, 123, - 226, 163, 211, 225, 259, 210, 142, 179, 180, 181, - 158, 159, 143, 182, 122, 177, 224, 178, 219, 7, - 235, 234, 104, 127, 243, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 72, 74, 80, 81, - 82, 83, 84, 147, 73, 88, 182, 196, 73, 229, - 195, 145, 7, 150, 228, 161, 166, 165, 157, 126, - 125, 124, 144, 88, 258, 167, 80, 81, 82, 83, - 84, 206, 73, 44, 242, 91, 90, 92, 183, 184, - 82, 83, 84, 154, 73, 153, 267, 186, 49, 173, - 42, 43, 100, 91, 90, 92, 99, 191, 120, 197, - 256, 257, 200, 192, 201, 202, 188, 75, 76, 207, - 77, 78, 79, 198, 199, 209, 42, 43, 216, 92, - 215, 215, 218, 213, 113, 98, 75, 76, 185, 77, - 78, 79, 204, 205, 101, 221, 222, 170, 155, 171, - 169, 3, 28, 27, 230, 96, 220, 232, 176, 46, - 223, 11, 80, 81, 82, 83, 84, 11, 73, 78, - 79, 157, 241, 110, 8, 152, 237, 255, 236, 72, - 74, 80, 81, 82, 83, 84, 85, 73, 79, 278, - 160, 191, 277, 121, 189, 253, 254, 192, 248, 247, - 187, 139, 249, 250, 208, 262, 260, 261, 215, 263, - 80, 81, 82, 83, 84, 149, 73, 268, 269, 10, - 270, 5, 4, 2, 1, 88, 272, 273, 80, 81, - 82, 83, 84, 0, 73, 279, 0, 0, 271, 280, - 51, 52, 0, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 115, 116, 91, 90, 92, 0, 0, - 42, 43, 0, 87, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 88, 0, 20, 0, 17, 37, 24, - 25, 26, 38, 40, 39, 41, 23, 29, 30, 42, - 43, 0, 114, 15, 0, 0, 212, 0, 16, 0, - 13, 14, 22, 91, 90, 92, 0, 0, 0, 0, - 0, 33, 34, 0, 0, 0, 21, 0, 36, 0, - 148, 32, 0, 146, 35, 51, 52, 0, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 115, 116, - 0, 0, 0, 0, 0, 42, 43, 0, 0, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 18, 19, - 20, 0, 17, 37, 24, 25, 26, 38, 40, 39, - 41, 23, 29, 30, 42, 43, 0, 114, 15, 0, - 0, 109, 0, 16, 0, 13, 14, 22, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 34, 0, 0, - 0, 21, 0, 36, 0, 0, 32, 0, 20, 35, - 17, 37, 24, 25, 26, 38, 40, 39, 41, 23, - 29, 30, 42, 43, 0, 0, 15, 0, 0, 0, - 0, 16, 0, 13, 14, 22, 0, 0, 0, 0, - 0, 0, 0, 0, 33, 34, 0, 0, 0, 21, - 0, 36, 0, 0, 32, 0, 231, 35, 20, 0, - 17, 37, 24, 25, 26, 38, 40, 39, 41, 23, - 29, 30, 42, 43, 0, 0, 15, 0, 0, 0, - 0, 16, 0, 13, 14, 22, 0, 0, 0, 0, - 0, 0, 0, 0, 33, 34, 0, 0, 0, 21, - 0, 36, 0, 0, 32, 0, 118, 35, 20, 0, - 17, 37, 24, 25, 26, 38, 40, 39, 41, 23, - 29, 30, 42, 43, 0, 0, 15, 0, 77, 78, - 79, 16, 0, 13, 14, 22, 0, 0, 0, 0, - 0, 0, 0, 0, 33, 34, 0, 0, 0, 21, - 0, 36, 0, 0, 32, 51, 52, 35, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 48, 0, - 80, 81, 82, 83, 84, 50, 73, 0, 0, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 51, 52, - 0, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 48, 0, 0, 0, 0, 0, 0, 50, 0, - 0, 172, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 51, 52, 0, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 115, 194, 0, 0, 0, 0, - 0, 42, 43, 0, 45, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 37, 24, 25, 26, 38, 40, - 39, 41, 23, 29, 30, 42, 43, 75, 76, 0, - 77, 78, 79, 193, 0, 0, 0, 0, 22, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 34, 0, - 0, 0, 21, 0, 36, 0, 0, 32, 75, 76, - 35, 77, 78, 79, 0, 0, 0, 0, 0, 0, - 72, 74, 80, 81, 82, 83, 84, 0, 73, 0, - 0, 0, 75, 76, 252, 77, 78, 79, 0, 0, + 78, 134, 186, 102, 103, 10, 175, 195, 32, 211, + 48, 108, 81, 176, 131, 6, 229, 5, 50, 73, + 74, 159, 14, 180, 181, 182, 124, 98, 110, 135, + 280, 97, 228, 279, 115, 104, 16, 158, 265, 121, + 114, 178, 123, 179, 244, 73, 74, 180, 181, 182, + 73, 74, 112, 113, 154, 155, 136, 117, 117, 117, + 254, 243, 137, 183, 282, 178, 255, 179, 220, 6, + 247, 116, 118, 119, 128, 129, 73, 74, 99, 73, + 74, 227, 73, 74, 246, 141, 238, 183, 201, 237, + 132, 200, 139, 6, 235, 226, 138, 163, 208, 80, + 157, 207, 241, 231, 230, 161, 162, 73, 74, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 83, + 82, 278, 84, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 184, 185, 174, 50, 160, 193, 73, + 74, 127, 196, 202, 203, 126, 197, 73, 74, 125, + 73, 74, 248, 253, 189, 204, 45, 240, 206, 73, + 74, 245, 143, 210, 214, 215, 73, 74, 104, 217, + 218, 213, 79, 219, 86, 87, 76, 90, 88, 89, + 169, 43, 44, 117, 117, 73, 74, 75, 166, 117, + 222, 224, 80, 225, 73, 74, 273, 212, 212, 232, + 132, 223, 234, 216, 120, 271, 73, 74, 191, 239, + 43, 44, 83, 82, 85, 84, 274, 270, 96, 91, + 92, 93, 94, 95, 73, 74, 93, 94, 95, 249, + 84, 164, 251, 252, 196, 236, 267, 250, 197, 130, + 25, 256, 73, 74, 262, 263, 187, 188, 3, 190, + 257, 258, 260, 261, 264, 24, 266, 73, 74, 9, + 221, 268, 269, 117, 117, 111, 171, 272, 172, 170, + 13, 275, 276, 77, 90, 277, 89, 212, 212, 13, + 177, 281, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 106, 107, 91, 92, 93, 94, 95, + 47, 43, 44, 101, 165, 259, 91, 92, 93, 94, + 95, 242, 156, 122, 194, 17, 192, 15, 37, 21, + 22, 23, 33, 133, 105, 205, 7, 34, 209, 35, + 36, 39, 41, 40, 42, 19, 20, 28, 31, 43, + 44, 8, 4, 2, 86, 87, 1, 90, 88, 89, + 0, 29, 30, 0, 168, 90, 18, 0, 0, 27, + 0, 142, 38, 0, 140, 26, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 106, 107, 91, + 92, 93, 94, 95, 0, 43, 44, 91, 92, 93, + 94, 95, 0, 0, 0, 0, 0, 11, 12, 17, + 0, 15, 37, 21, 22, 23, 33, 0, 105, 0, + 0, 34, 100, 35, 36, 39, 41, 40, 42, 19, + 20, 28, 31, 43, 44, 0, 0, 0, 0, 86, + 87, 0, 90, 88, 89, 29, 30, 0, 0, 167, + 18, 0, 0, 27, 0, 0, 38, 0, 17, 26, + 15, 37, 21, 22, 23, 33, 0, 0, 0, 0, + 34, 0, 35, 36, 39, 41, 40, 42, 19, 20, + 28, 31, 43, 44, 91, 92, 93, 94, 95, 0, + 0, 0, 0, 0, 29, 30, 90, 88, 89, 18, + 0, 0, 27, 0, 0, 38, 0, 233, 26, 17, + 0, 15, 37, 21, 22, 23, 33, 0, 0, 0, + 0, 34, 0, 35, 36, 39, 41, 40, 42, 19, + 20, 28, 31, 43, 44, 0, 0, 0, 91, 92, + 93, 94, 95, 0, 0, 29, 30, 0, 0, 0, + 18, 0, 0, 27, 0, 0, 38, 0, 109, 26, + 17, 0, 15, 37, 21, 22, 23, 33, 0, 0, + 0, 0, 34, 0, 35, 36, 39, 41, 40, 42, + 19, 20, 28, 31, 43, 44, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 29, 30, 0, 0, + 0, 18, 0, 0, 27, 0, 0, 38, 0, 0, + 26, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 49, 0, 0, 0, 0, 0, 0, 0, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 49, 0, 0, 0, 0, 173, 0, 0, + 51, 37, 21, 22, 23, 33, 0, 0, 0, 0, + 34, 0, 35, 36, 39, 41, 40, 42, 19, 20, + 28, 31, 43, 44, 0, 0, 0, 46, 0, 0, + 0, 0, 0, 0, 29, 30, 0, 0, 0, 18, + 0, 0, 27, 0, 0, 38, 0, 0, 26, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 106, 199, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 72, 74, 80, 81, 82, 83, 84, 0, 73, - 0, 0, 0, 75, 76, 233, 77, 78, 79, 0, - 0, 0, 0, 0, 0, 72, 74, 80, 81, 82, - 83, 84, 0, 73, 0, 0, 0, 75, 76, 168, - 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 72, 74, 80, 81, - 82, 83, 84, 0, 73, 0, 0, 75, 76, 281, - 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, - 72, 74, 80, 81, 82, 83, 84, 0, 73, 0, - 0, 75, 76, 276, 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 74, 80, 81, 82, 83, 84, 0, 73, 0, - 0, 75, 76, 251, 77, 78, 79, 0, 0, 0, - 0, 0, 0, 0, 72, 74, 80, 81, 82, 83, - 84, 0, 73, 0, 0, 75, 76, 244, 77, 78, - 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 72, 74, 80, 81, 82, 83, - 84, 0, 73, 0, 0, 75, 76, 217, 77, 78, - 79, 0, 0, 0, 0, 0, 0, 0, 72, 74, - 80, 81, 82, 83, 84, 0, 73, 0, 0, 75, - 76, 162, 77, 78, 79, 0, 0, 0, 0, 0, - 75, 76, 0, 77, 78, 79, 0, 0, 72, 74, - 80, 81, 82, 83, 84, 0, 73, 0, 275, 75, - 76, 0, 77, 78, 79, 0, 0, 0, 0, 0, - 0, 0, 72, 74, 80, 81, 82, 83, 84, 0, - 73, 0, 266, 72, 74, 80, 81, 82, 83, 84, - 0, 73, 0, 265, 75, 76, 0, 77, 78, 79, - 0, 0, 72, 74, 80, 81, 82, 83, 84, 0, - 73, 0, 238, 0, 0, 0, 75, 76, 0, 77, - 78, 79, 274, 0, 0, 75, 76, 0, 77, 78, - 79, 0, 0, 0, 0, 0, 0, 72, 74, 80, - 81, 82, 83, 84, 151, 73, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, - 74, 80, 81, 82, 83, 84, 0, 73, 72, 74, - 80, 81, 82, 83, 84, 0, 73, + 0, 198, } var yyPact = [...]int16{ - 181, -1000, -1000, -39, -1000, 387, 66, 621, -1000, 1071, - -1000, 535, 289, 678, 678, 535, 535, 154, 119, 115, - 164, 113, -1000, -1000, -1000, -1000, -1000, 13, -1000, -1000, - 139, -1000, 535, 678, 678, 358, 485, 127, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1, -1000, 53, 52, - 51, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 238, -1000, -1000, -48, 406, 98, 643, -1000, -1000, -1000, + 112, 150, 139, 557, 158, 184, 170, 189, 173, -1000, + -1000, -1000, -1000, -1000, 18, -1000, 368, 506, -1000, 665, + 665, 144, -1000, 557, 665, 665, 665, 174, 557, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -22, -1000, 90, + 86, 82, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 535, -1000, 535, 535, 535, 535, 535, 535, - 535, 535, 535, 535, 535, -1000, 1071, 0, -1000, -1000, - -1000, 113, 302, 241, 89, 1062, 535, 98, 86, 174, - -39, 2, -1000, -1000, 535, -1000, 921, 71, 71, -1000, - -12, -1000, 49, 48, 535, -1000, -1000, -1000, -1000, 758, - -1000, 160, -1000, 588, 40, 40, 40, 1071, 153, 153, - 561, 201, 219, 67, 79, 79, 43, 43, 43, 131, - -1000, -1000, 0, 654, -1000, -1000, -1000, 39, 535, 0, - 0, 535, -1000, 535, 535, 162, 64, -1000, 535, 162, - -5, 1071, -1000, -1000, 273, 678, 678, 897, -1000, -1000, - -1000, 535, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 7, -1000, -1000, 535, 0, 5, -1000, -13, - -1000, 46, 41, 535, -1000, -1000, 435, 734, 12, 11, - 1071, -1000, 1071, -39, -1000, -1000, -1000, 1005, -30, -1000, - -1000, 535, -1000, -1000, 77, 71, 77, 16, 867, -1000, - -20, -1000, 1071, -1000, -1000, 0, -1000, 654, 0, 0, - 843, -1000, 703, -1000, 535, 535, 117, 57, -1000, -4, - 162, 1071, 678, 678, -1000, -1000, 40, -1000, -1000, -1000, - -1000, -29, -1000, 986, 975, 101, 535, 535, -1000, 535, - -1000, 71, 77, -1000, 0, 535, 535, -1000, 1040, 1071, - 951, -1000, 813, 172, 535, -1000, -1000, -1000, 535, 1071, - 789, -1000, + -1000, -1000, -1000, 557, 557, 225, -48, -1000, 112, -1, + -1000, -1000, -1000, 173, 312, 115, 665, 665, 665, 665, + 665, 665, 665, 665, 665, 665, -5, -1000, -1000, 557, + -1000, -27, -1000, 78, 46, 557, -1000, -1000, -1000, -1000, + 35, 557, 65, 65, -1000, 210, 162, 65, 445, 350, + -1000, 119, 229, -1000, 613, 30, 30, 30, 112, -1000, + 217, 96, -1000, 202, -1000, -1000, -1, 721, -1000, -1000, + -1000, 29, 557, 557, 170, 499, 267, 358, 256, 175, + 175, -1000, -1000, -1000, 557, 217, 40, 112, -1000, 274, + 665, 665, 103, -1000, 557, -1000, 665, -1, -1, -1000, + -1000, -1000, 557, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 6, -1000, -1000, -48, -1000, -1000, -1000, + 557, -1, 33, -1000, -32, -1000, 45, 44, 557, -1000, + -1000, 455, 32, 112, 177, 28, -1000, -1000, 557, -1000, + -1000, 110, 170, 110, 43, 112, -1000, 1, -16, 100, + -1000, 22, -1000, 94, 112, -1000, -1000, -1, -1000, 721, + -1, -1, 92, -1000, -2, -1000, -1000, 7, 217, 112, + 665, 665, 230, 557, 557, -1000, -1000, 30, -1000, -1000, + -1000, -1000, -1000, -21, -1000, 557, -1000, 110, 110, 212, + 557, 557, 159, 147, -1000, -1, 138, -1000, 195, 112, + 557, 557, -1000, -1000, 557, 60, -28, 112, -1000, -1000, + 557, 3, -1000, } var yyPgo = [...]int16{ - 0, 264, 263, 262, 261, 259, 12, 214, 195, 244, - 0, 241, 13, 240, 234, 10, 4, 9, 233, 20, - 230, 218, 217, 215, 213, 8, 1, 2, 7, 199, - 15, 198, 196, 5, 193, 192, 14, 3, + 0, 356, 353, 352, 351, 14, 336, 259, 265, 335, + 0, 333, 1, 326, 324, 7, 36, 22, 8, 323, + 12, 322, 321, 315, 314, 313, 3, 9, 6, 13, + 310, 10, 280, 260, 2, 255, 240, 11, 4, } var yyR1 = [...]int8{ 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, - 6, 6, 7, 7, 8, 8, 9, 9, 33, 33, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, - 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 17, 17, 18, 18, 18, 34, - 34, 35, 35, 19, 19, 19, 19, 19, 20, 20, - 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, - 25, 25, 25, 37, 37, 37, 26, 26, 27, 27, - 27, 27, 27, 27, 27, 28, 28, 28, 29, 29, - 30, 30, 30, 31, 31, 32, 32, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, + 6, 6, 7, 7, 8, 8, 9, 9, 34, 34, + 10, 10, 10, 10, 10, 10, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 11, 11, 12, + 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 18, 18, 19, 19, 19, 35, + 35, 36, 36, 20, 20, 20, 20, 20, 21, 21, + 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, + 26, 26, 26, 38, 38, 38, 27, 27, 28, 28, + 28, 28, 28, 28, 28, 29, 29, 29, 30, 30, + 31, 31, 31, 32, 32, 33, 33, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, } var yyR2 = [...]int8{ - 0, 2, 0, 3, 2, 2, 0, 2, 6, 4, - 0, 1, 0, 2, 5, 8, 1, 3, 1, 1, - 2, 3, 5, 9, 9, 11, 7, 3, 4, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, - 3, 3, 3, 5, 1, 1, 1, 1, 2, 2, - 1, 1, 1, 1, 4, 1, 1, 1, 2, 1, - 3, 2, 2, 2, 3, 4, 2, 3, 2, 2, + 0, 3, 0, 3, 0, 2, 6, 4, 0, 1, + 1, 1, 0, 2, 5, 8, 1, 3, 1, 1, + 2, 3, 5, 4, 3, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 1, 1, 3, 1, + 3, 3, 1, 3, 1, 3, 3, 3, 5, 1, + 1, 1, 1, 2, 2, 1, 1, 1, 1, 4, + 1, 2, 3, 4, 2, 3, 1, 2, 2, 1, + 2, 1, 7, 3, 9, 9, 11, 2, 3, 2, 2, 2, 3, 3, 1, 3, 0, 2, 4, 1, 1, 1, 1, 2, 3, 4, 4, 5, 1, 3, 0, 5, 0, 2, 0, 2, 1, 3, 3, 3, - 5, 1, 1, 1, 1, 1, 1, 3, 1, 1, + 5, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 3, 3, 3, 3, 2, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -378,67 +329,67 @@ var yyR2 = [...]int8{ } var yyChk = [...]int16{ - -1000, -1, -2, 10, -3, -4, -28, 62, -7, -10, - -5, -8, -16, 38, 39, 31, 36, 15, 11, 12, - 13, 54, 40, 24, 17, 18, 19, -34, -35, 25, - 26, -17, 59, 49, 50, 62, 56, 16, 20, 22, - 21, 23, 27, 28, 57, 63, -29, -30, 20, -36, - 27, 7, 8, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 47, 55, 48, 4, 5, 7, 8, 9, - 49, 50, 51, 52, 53, -7, -10, 14, 24, -19, - 55, 54, 56, -16, -16, -10, -8, -10, 21, 27, - 27, 20, -19, -17, 59, -17, -10, -16, -16, 63, - -24, -25, -37, -17, 59, 20, 21, -36, 61, -10, - 21, -18, 63, 48, 58, 58, 58, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -11, - -12, 21, 56, 62, -19, -17, 61, -10, 58, 14, - 14, 32, -23, 37, 47, 14, -6, -28, 58, 59, - -20, -10, 60, 63, 48, 58, 58, -10, 61, 30, - 27, 29, 63, -30, -27, -28, -31, 25, 27, 17, - 18, 19, 56, -27, -27, 47, 6, -13, -12, -14, - -15, -37, -17, 59, 21, 61, 58, -10, -12, -12, - -10, -10, -10, -33, 20, 21, 57, -10, -9, -33, - 60, 57, 63, -25, -26, -16, -26, 60, -10, 61, - -32, -27, -10, -12, 61, 48, 63, 48, 58, 58, - -10, 61, -10, 61, 59, 59, -21, -6, 57, 60, - 57, -10, 47, 58, 60, 61, 48, -12, -15, -12, - -12, 60, 61, -10, -10, -22, 33, 34, 57, 58, - -33, -16, -26, -27, 58, 57, 57, 35, -10, -10, - -10, -12, -10, -10, 32, 57, 60, 60, 57, -10, - -10, 60, + -1000, -1, -2, 10, -3, -29, 63, -6, -4, -7, + -10, 11, 12, -8, -17, 15, -16, 13, 54, 33, + 34, 17, 18, 19, -35, -36, 63, 57, 35, 49, + 50, 36, -18, 20, 25, 27, 28, 16, 60, 29, + 31, 30, 32, 37, 38, 58, 64, -30, -31, 29, + -37, 37, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 47, 48, 37, 37, -7, -10, 14, + 34, -20, 55, 54, 57, 30, 4, 5, 8, 9, + 7, 49, 50, 51, 52, 53, 29, -20, -18, 60, + 64, -25, -26, -38, -18, 60, 29, 30, -37, 62, + -10, -8, -17, -17, -18, -10, -16, -17, -16, -16, + 30, -10, -19, 64, 48, 59, 59, 59, -10, -10, + 14, -5, -29, -11, -12, 30, 57, 63, -20, -18, + 62, -10, 59, 47, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, 59, 60, -21, -10, 64, 48, + 59, 59, -10, 62, 21, -24, 26, 14, 14, 61, + 40, 37, 39, 64, -31, -28, -29, -32, 35, 37, + 17, 18, 19, 57, -28, -28, -34, 29, 30, 58, + 47, 6, -13, -12, -14, -15, -38, -18, 60, 30, + 62, 59, -10, -10, -10, -9, -34, 61, 58, 64, + -26, -27, -16, -27, 61, -10, -16, -12, -12, -10, + 62, -33, -28, -5, -10, -12, 62, 48, 64, 48, + 59, 59, -10, 62, -10, 62, 58, 61, 58, -10, + 47, 59, -22, 60, 60, 61, 62, 48, 58, -12, + -15, -12, -12, 61, 62, 59, -34, -27, -27, -23, + 22, 23, -10, -10, -28, 59, -10, 24, -10, -10, + 58, 58, -12, 58, 21, -10, -10, -10, 61, 61, + 58, -10, 61, } var yyDef = [...]int16{ - 2, -2, 6, 0, 1, 12, 0, 0, 4, 5, - 7, 12, 41, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 56, 57, 60, 61, 62, 63, 65, 66, - 67, 69, 0, 0, 0, 0, 0, 0, 89, 90, - 91, 92, 84, 86, 3, 125, 0, 128, 0, 0, - 0, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 0, 29, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 13, 20, 0, 79, 80, - 81, 0, 0, 0, 0, 0, 0, -2, 0, 0, - 10, 0, 58, 59, 0, 68, 0, 71, 72, 73, - 0, 106, 111, 112, 0, 113, 114, 115, 76, 0, - 78, 0, 126, 0, 0, 0, 0, 21, 30, 31, - -2, 33, 34, -2, 36, 37, 38, 39, 40, 0, - 42, 44, 0, 0, 82, 83, 93, 0, 0, 0, - 0, 0, 27, 0, 0, 0, 0, 11, 0, 0, - 0, 98, 70, 74, 0, 0, 0, 0, 77, 85, - 87, 0, 127, 129, 130, 118, 119, 120, 121, 122, - 123, 124, 0, 131, 132, 0, 0, 0, 47, 0, - 49, 0, 0, 0, -2, 94, 0, 0, 0, 0, - 100, 105, 28, 10, 18, 19, 9, 0, 0, 16, - 64, 0, 75, 107, 108, 116, 109, 0, 0, 133, - 0, 135, 22, 43, 45, 0, 46, 0, 0, 0, - 0, 95, 0, 96, 0, 0, 102, 0, 14, 0, - 0, 99, 0, 0, 88, 134, 0, 48, 50, 51, - 52, 0, 97, 0, 0, 0, 0, 0, 8, 0, - 17, 117, 110, 136, 0, 0, 0, 26, 0, 103, - 0, 53, 0, 0, 0, 15, 23, 24, 0, 101, - 0, 25, + 2, -2, 4, 0, 12, 0, 0, 1, 5, 10, + 11, 0, 0, 12, 36, 0, 25, 0, 50, 51, + 52, 55, 56, 57, 58, 60, 0, 0, 66, 0, + 0, 69, 71, 0, 0, 0, 0, 0, 0, 89, + 90, 91, 92, 84, 86, 3, 125, 0, 128, 0, + 0, 0, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 0, 0, 0, 8, 13, 20, 0, + 79, 80, 81, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 53, 54, 0, + 61, 0, 106, 111, 112, 0, 113, 114, 115, 64, + 0, 0, 67, 68, 70, 0, 104, 36, 0, 0, + 77, 0, 0, 126, 0, 0, 0, 0, 21, 24, + 0, 0, 9, 0, 37, 39, 0, 0, 82, 83, + 93, 0, 0, 0, 26, -2, 28, 29, -2, 31, + 32, 33, 34, 35, 0, 0, 0, 98, 62, 0, + 0, 0, 0, 65, 0, 73, 0, 0, 0, 78, + 85, 87, 0, 127, 129, 130, 118, 119, 120, 121, + 122, 123, 124, 0, 131, 132, 8, 18, 19, 7, + 0, 0, 0, 42, 0, 44, 0, 0, 0, -2, + 94, 0, 0, 23, 0, 0, 16, 59, 0, 63, + 107, 108, 117, 109, 0, 100, 105, 0, 0, 0, + 133, 0, 135, 0, 22, 38, 40, 0, 41, 0, + 0, 0, 0, 95, 0, 96, 14, 0, 0, 99, + 0, 0, 102, 0, 0, 88, 134, 0, 6, 43, + 45, 46, 47, 0, 97, 0, 17, 116, 110, 0, + 0, 0, 0, 0, 136, 0, 0, 72, 0, 103, + 0, 0, 48, 15, 0, 0, 0, 101, 74, 75, + 0, 0, 76, } var yyTok1 = [...]int8{ @@ -446,15 +397,15 @@ var yyTok1 = [...]int8{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 53, 3, 3, - 59, 60, 51, 49, 48, 50, 54, 52, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 58, 57, + 60, 61, 51, 49, 48, 50, 54, 52, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 59, 58, 3, 3, 3, 55, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 56, 3, 61, 3, 3, 3, 3, 3, 3, + 3, 57, 3, 62, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 62, 47, 63, + 3, 3, 3, 63, 47, 64, } var yyTok2 = [...]int8{ @@ -462,7 +413,7 @@ var yyTok2 = [...]int8{ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, + 42, 43, 44, 45, 46, 56, } var yyTok3 = [...]int8{ @@ -807,933 +758,756 @@ yydefault: switch yynt { case 1: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:73 + yyDollar = yyS[yypt-3 : yypt+1] +//line parser.go.y:58 { - if yyDollar[1].value != nil { - yyDollar[2].value.(*Query).Meta = yyDollar[1].value.(*ConstObject) - } - yylex.(*lexer).result = yyDollar[2].value.(*Query) + query := yyDollar[3].value.(*Query) + query.Meta = yyDollar[1].value.(*ConstObject) + query.Imports = yyDollar[2].value.([]*Import) + yylex.(*lexer).result = query } case 2: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:80 +//line parser.go.y:67 { - yyVAL.value = nil + yyVAL.value = (*ConstObject)(nil) } case 3: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:84 +//line parser.go.y:71 { yyVAL.value = yyDollar[2].value } case 4: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:90 - { - yyVAL.value = &Query{Imports: yyDollar[1].value.([]*Import), FuncDefs: reverseFuncDef(yyDollar[2].value.([]*FuncDef)), Term: &Term{Type: TermTypeIdentity}} - } - case 5: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:94 - { - if yyDollar[1].value != nil { - yyDollar[2].value.(*Query).Imports = yyDollar[1].value.([]*Import) - } - yyVAL.value = yyDollar[2].value - } - case 6: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:101 +//line parser.go.y:77 { yyVAL.value = []*Import(nil) } - case 7: + case 5: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:105 +//line parser.go.y:81 { yyVAL.value = append(yyDollar[1].value.([]*Import), yyDollar[2].value.(*Import)) } - case 8: + case 6: yyDollar = yyS[yypt-6 : yypt+1] -//line parser.go.y:111 +//line parser.go.y:87 { yyVAL.value = &Import{ImportPath: yyDollar[2].token, ImportAlias: yyDollar[4].token, Meta: yyDollar[5].value.(*ConstObject)} } - case 9: + case 7: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:115 +//line parser.go.y:91 { yyVAL.value = &Import{IncludePath: yyDollar[2].token, Meta: yyDollar[3].value.(*ConstObject)} } - case 10: + case 8: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:121 +//line parser.go.y:97 { yyVAL.value = (*ConstObject)(nil) } - case 11: + case 10: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:124 +//line parser.go.y:104 { + yyVAL.value = &Query{FuncDefs: reverseFuncDef(yyDollar[1].value.([]*FuncDef))} } case 12: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:128 +//line parser.go.y:111 { yyVAL.value = []*FuncDef(nil) } case 13: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:132 +//line parser.go.y:115 { yyVAL.value = append(yyDollar[2].value.([]*FuncDef), yyDollar[1].value.(*FuncDef)) } case 14: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:138 +//line parser.go.y:121 { yyVAL.value = &FuncDef{Name: yyDollar[2].token, Body: yyDollar[4].value.(*Query)} } case 15: yyDollar = yyS[yypt-8 : yypt+1] -//line parser.go.y:142 +//line parser.go.y:125 { yyVAL.value = &FuncDef{yyDollar[2].token, yyDollar[4].value.([]string), yyDollar[7].value.(*Query)} } case 16: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:148 +//line parser.go.y:131 { yyVAL.value = []string{yyDollar[1].token} } case 17: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:152 +//line parser.go.y:135 { yyVAL.value = append(yyDollar[1].value.([]string), yyDollar[3].token) } - case 18: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:157 - { - } - case 19: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:158 - { - } case 20: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:162 +//line parser.go.y:145 { - yyDollar[2].value.(*Query).FuncDefs = prependFuncDef(yyDollar[2].value.(*Query).FuncDefs, yyDollar[1].value.(*FuncDef)) - yyVAL.value = yyDollar[2].value + query := yyDollar[2].value.(*Query) + query.FuncDefs = prependFuncDef(query.FuncDefs, yyDollar[1].value.(*FuncDef)) + yyVAL.value = query } case 21: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:167 +//line parser.go.y:151 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpPipe, Right: yyDollar[3].value.(*Query)} } case 22: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:171 +//line parser.go.y:155 { - yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Bind: &Bind{yyDollar[3].value.([]*Pattern), yyDollar[5].value.(*Query)}}) - yyVAL.value = &Query{Term: yyDollar[1].value.(*Term)} + term := yyDollar[1].value.(*Term) + term.SuffixList = append(term.SuffixList, &Suffix{Bind: &Bind{yyDollar[3].value.([]*Pattern), yyDollar[5].value.(*Query)}}) + yyVAL.value = &Query{Term: term} } case 23: - yyDollar = yyS[yypt-9 : yypt+1] -//line parser.go.y:176 - { - yyVAL.value = &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query)}}} - } - case 24: - yyDollar = yyS[yypt-9 : yypt+1] -//line parser.go.y:180 - { - yyVAL.value = &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), nil}}} - } - case 25: - yyDollar = yyS[yypt-11 : yypt+1] -//line parser.go.y:184 - { - yyVAL.value = &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), yyDollar[10].value.(*Query)}}} - } - case 26: - yyDollar = yyS[yypt-7 : yypt+1] -//line parser.go.y:188 - { - yyVAL.value = &Query{Term: &Term{Type: TermTypeIf, If: &If{yyDollar[2].value.(*Query), yyDollar[4].value.(*Query), yyDollar[5].value.([]*IfElif), yyDollar[6].value.(*Query)}}} - } - case 27: - yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:192 - { - yyVAL.value = &Query{Term: &Term{Type: TermTypeTry, Try: &Try{yyDollar[2].value.(*Query), yyDollar[3].value.(*Query)}}} - } - case 28: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:196 +//line parser.go.y:161 { yyVAL.value = &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{yyDollar[2].token, yyDollar[4].value.(*Query)}}} } - case 29: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:200 - { - if t := yyDollar[1].value.(*Query).Term; t != nil { - t.SuffixList = append(t.SuffixList, &Suffix{Optional: true}) - } else { - yyVAL.value = &Query{Term: &Term{Type: TermTypeQuery, Query: yyDollar[1].value.(*Query), SuffixList: []*Suffix{{Optional: true}}}} - } - } - case 30: + case 24: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:208 +//line parser.go.y:165 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpComma, Right: yyDollar[3].value.(*Query)} } - case 31: + case 26: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:212 +//line parser.go.y:172 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)} } - case 32: + case 27: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:216 +//line parser.go.y:176 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)} } - case 33: + case 28: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:220 +//line parser.go.y:180 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpOr, Right: yyDollar[3].value.(*Query)} } - case 34: + case 29: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:224 +//line parser.go.y:184 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAnd, Right: yyDollar[3].value.(*Query)} } - case 35: + case 30: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:228 +//line parser.go.y:188 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)} } - case 36: + case 31: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:232 +//line parser.go.y:192 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAdd, Right: yyDollar[3].value.(*Query)} } - case 37: + case 32: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:236 +//line parser.go.y:196 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpSub, Right: yyDollar[3].value.(*Query)} } - case 38: + case 33: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:240 +//line parser.go.y:200 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMul, Right: yyDollar[3].value.(*Query)} } - case 39: + case 34: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:244 +//line parser.go.y:204 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpDiv, Right: yyDollar[3].value.(*Query)} } - case 40: + case 35: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:248 +//line parser.go.y:208 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMod, Right: yyDollar[3].value.(*Query)} } - case 41: + case 36: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:252 +//line parser.go.y:212 { yyVAL.value = &Query{Term: yyDollar[1].value.(*Term)} } - case 42: + case 37: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:258 +//line parser.go.y:218 { yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)} } - case 43: + case 38: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:262 +//line parser.go.y:222 { yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern)) } - case 44: + case 39: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:268 +//line parser.go.y:228 { yyVAL.value = &Pattern{Name: yyDollar[1].token} } - case 45: + case 40: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:272 +//line parser.go.y:232 { yyVAL.value = &Pattern{Array: yyDollar[2].value.([]*Pattern)} } - case 46: + case 41: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:276 +//line parser.go.y:236 { yyVAL.value = &Pattern{Object: yyDollar[2].value.([]*PatternObject)} } - case 47: + case 42: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:282 +//line parser.go.y:242 { yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)} } - case 48: + case 43: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:286 +//line parser.go.y:246 { yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern)) } - case 49: + case 44: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:292 +//line parser.go.y:252 { yyVAL.value = []*PatternObject{yyDollar[1].value.(*PatternObject)} } - case 50: + case 45: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:296 +//line parser.go.y:256 { yyVAL.value = append(yyDollar[1].value.([]*PatternObject), yyDollar[3].value.(*PatternObject)) } - case 51: + case 46: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:302 +//line parser.go.y:262 { yyVAL.value = &PatternObject{Key: yyDollar[1].token, Val: yyDollar[3].value.(*Pattern)} } - case 52: + case 47: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:306 +//line parser.go.y:266 { yyVAL.value = &PatternObject{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*Pattern)} } - case 53: + case 48: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:310 +//line parser.go.y:270 { yyVAL.value = &PatternObject{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*Pattern)} } - case 54: + case 49: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:314 +//line parser.go.y:274 { yyVAL.value = &PatternObject{Key: yyDollar[1].token} } - case 55: + case 50: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:320 +//line parser.go.y:280 { yyVAL.value = &Term{Type: TermTypeIdentity} } - case 56: + case 51: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:324 +//line parser.go.y:284 { yyVAL.value = &Term{Type: TermTypeRecurse} } - case 57: + case 52: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:328 +//line parser.go.y:288 { yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Name: yyDollar[1].token}} } - case 58: + case 53: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:332 +//line parser.go.y:292 { - if yyDollar[2].value.(*Suffix).Iter { - yyVAL.value = &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{yyDollar[2].value.(*Suffix)}} + suffix := yyDollar[2].value.(*Suffix) + if suffix.Iter { + yyVAL.value = &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{suffix}} } else { - yyVAL.value = &Term{Type: TermTypeIndex, Index: yyDollar[2].value.(*Suffix).Index} + yyVAL.value = &Term{Type: TermTypeIndex, Index: suffix.Index} } } - case 59: + case 54: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:340 +//line parser.go.y:301 { yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Str: yyDollar[2].value.(*String)}} } - case 60: + case 55: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:344 +//line parser.go.y:305 { yyVAL.value = &Term{Type: TermTypeNull} } - case 61: + case 56: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:348 +//line parser.go.y:309 { yyVAL.value = &Term{Type: TermTypeTrue} } - case 62: + case 57: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:352 +//line parser.go.y:313 { yyVAL.value = &Term{Type: TermTypeFalse} } - case 63: + case 58: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:356 +//line parser.go.y:317 { yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}} } - case 64: + case 59: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:360 +//line parser.go.y:321 { yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token, Args: yyDollar[3].value.([]*Query)}} } - case 65: + case 60: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:364 +//line parser.go.y:325 { yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}} } + case 61: + yyDollar = yyS[yypt-2 : yypt+1] +//line parser.go.y:329 + { + yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{}} + } + case 62: + yyDollar = yyS[yypt-3 : yypt+1] +//line parser.go.y:333 + { + yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}} + } + case 63: + yyDollar = yyS[yypt-4 : yypt+1] +//line parser.go.y:337 + { + yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}} + } + case 64: + yyDollar = yyS[yypt-2 : yypt+1] +//line parser.go.y:341 + { + yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{}} + } + case 65: + yyDollar = yyS[yypt-3 : yypt+1] +//line parser.go.y:345 + { + yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{yyDollar[2].value.(*Query)}} + } case 66: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:368 +//line parser.go.y:349 { yyVAL.value = &Term{Type: TermTypeNumber, Number: yyDollar[1].token} } case 67: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:372 + yyDollar = yyS[yypt-2 : yypt+1] +//line parser.go.y:353 { - yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token} + yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpAdd, yyDollar[2].value.(*Term)}} } case 68: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:376 +//line parser.go.y:357 { - yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token, Str: yyDollar[2].value.(*String)} + yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpSub, yyDollar[2].value.(*Term)}} } case 69: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:380 +//line parser.go.y:361 { - yyVAL.value = &Term{Type: TermTypeString, Str: yyDollar[1].value.(*String)} + yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token} } case 70: - yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:384 + yyDollar = yyS[yypt-2 : yypt+1] +//line parser.go.y:365 { - yyVAL.value = &Term{Type: TermTypeQuery, Query: yyDollar[2].value.(*Query)} + yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token, Str: yyDollar[2].value.(*String)} } case 71: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:388 + yyDollar = yyS[yypt-1 : yypt+1] +//line parser.go.y:369 { - yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpAdd, yyDollar[2].value.(*Term)}} + yyVAL.value = &Term{Type: TermTypeString, Str: yyDollar[1].value.(*String)} } case 72: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:392 + yyDollar = yyS[yypt-7 : yypt+1] +//line parser.go.y:373 { - yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpSub, yyDollar[2].value.(*Term)}} + yyVAL.value = &Term{Type: TermTypeIf, If: &If{yyDollar[2].value.(*Query), yyDollar[4].value.(*Query), yyDollar[5].value.([]*IfElif), yyDollar[6].value.(*Query)}} } case 73: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:396 + yyDollar = yyS[yypt-3 : yypt+1] +//line parser.go.y:377 { - yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{}} + yyVAL.value = &Term{Type: TermTypeTry, Try: &Try{yyDollar[2].value.(*Query), yyDollar[3].value.(*Query)}} } case 74: - yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:400 + yyDollar = yyS[yypt-9 : yypt+1] +//line parser.go.y:381 { - yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}} + yyVAL.value = &Term{Type: TermTypeReduce, Reduce: &Reduce{yyDollar[2].value.(*Query), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query)}} } case 75: - yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:404 + yyDollar = yyS[yypt-9 : yypt+1] +//line parser.go.y:385 { - yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}} + yyVAL.value = &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Query), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), nil}} } case 76: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:408 + yyDollar = yyS[yypt-11 : yypt+1] +//line parser.go.y:389 { - yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{}} + yyVAL.value = &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Query), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), yyDollar[10].value.(*Query)}} } case 77: - yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:412 + yyDollar = yyS[yypt-2 : yypt+1] +//line parser.go.y:393 { - yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{yyDollar[2].value.(*Query)}} + yyVAL.value = &Term{Type: TermTypeBreak, Break: yyDollar[2].token} } case 78: - yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:416 + yyDollar = yyS[yypt-3 : yypt+1] +//line parser.go.y:397 { - yyVAL.value = &Term{Type: TermTypeBreak, Break: yyDollar[2].token} + yyVAL.value = &Term{Type: TermTypeQuery, Query: yyDollar[2].value.(*Query)} } case 79: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:420 +//line parser.go.y:401 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Name: yyDollar[2].token}}) } case 80: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:424 +//line parser.go.y:405 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[2].value.(*Suffix)) } case 81: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:428 +//line parser.go.y:409 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Optional: true}) } case 82: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:432 +//line parser.go.y:413 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[3].value.(*Suffix)) } case 83: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:436 +//line parser.go.y:417 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Str: yyDollar[3].value.(*String)}}) } case 84: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:442 +//line parser.go.y:423 { yyVAL.value = &String{Str: yyDollar[1].token} } case 85: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:446 +//line parser.go.y:427 { yyVAL.value = &String{Queries: yyDollar[2].value.([]*Query)} } case 86: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:452 +//line parser.go.y:433 { yyVAL.value = []*Query{} } case 87: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:456 +//line parser.go.y:437 { yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: yyDollar[2].token}}}) } case 88: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:460 +//line parser.go.y:441 { yylex.(*lexer).inString = true yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeQuery, Query: yyDollar[3].value.(*Query)}}) } - case 89: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:466 - { - } - case 90: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:467 - { - } - case 91: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:470 - { - } - case 92: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:471 - { - } case 93: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:475 +//line parser.go.y:456 { yyVAL.value = &Suffix{Iter: true} } case 94: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:479 +//line parser.go.y:460 { yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query)}} } case 95: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:483 +//line parser.go.y:464 { yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), IsSlice: true}} } case 96: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:487 +//line parser.go.y:468 { yyVAL.value = &Suffix{Index: &Index{End: yyDollar[3].value.(*Query), IsSlice: true}} } case 97: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:491 +//line parser.go.y:472 { yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), End: yyDollar[4].value.(*Query), IsSlice: true}} } case 98: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:497 +//line parser.go.y:478 { yyVAL.value = []*Query{yyDollar[1].value.(*Query)} } case 99: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:501 +//line parser.go.y:482 { yyVAL.value = append(yyDollar[1].value.([]*Query), yyDollar[3].value.(*Query)) } case 100: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:507 +//line parser.go.y:488 { yyVAL.value = []*IfElif(nil) } case 101: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:511 +//line parser.go.y:492 { yyVAL.value = append(yyDollar[1].value.([]*IfElif), &IfElif{yyDollar[3].value.(*Query), yyDollar[5].value.(*Query)}) } case 102: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:517 +//line parser.go.y:498 { yyVAL.value = (*Query)(nil) } case 103: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:521 +//line parser.go.y:502 { yyVAL.value = yyDollar[2].value } case 104: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:527 +//line parser.go.y:508 { yyVAL.value = (*Query)(nil) } case 105: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:531 +//line parser.go.y:512 { yyVAL.value = yyDollar[2].value } case 106: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:537 +//line parser.go.y:518 { yyVAL.value = []*ObjectKeyVal{yyDollar[1].value.(*ObjectKeyVal)} } case 107: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:541 +//line parser.go.y:522 { yyVAL.value = append(yyDollar[1].value.([]*ObjectKeyVal), yyDollar[3].value.(*ObjectKeyVal)) } case 108: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:547 +//line parser.go.y:528 { - yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ObjectVal)} + yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*Query)} } case 109: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:551 +//line parser.go.y:532 { - yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*ObjectVal)} + yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*Query)} } case 110: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:555 +//line parser.go.y:536 { - yyVAL.value = &ObjectKeyVal{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*ObjectVal)} + yyVAL.value = &ObjectKeyVal{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*Query)} } case 111: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:559 +//line parser.go.y:540 { yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token} } case 112: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:563 +//line parser.go.y:544 { yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String)} } - case 113: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:568 - { - } - case 114: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:569 - { - } - case 115: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:570 - { - } case 116: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:574 - { - yyVAL.value = &ObjectVal{[]*Query{{Term: yyDollar[1].value.(*Term)}}} - } - case 117: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:578 +//line parser.go.y:555 { - yyVAL.value = &ObjectVal{append(yyDollar[1].value.(*ObjectVal).Queries, &Query{Term: yyDollar[3].value.(*Term)})} + yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpPipe, Right: yyDollar[3].value.(*Query)} } case 118: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:584 +//line parser.go.y:562 { yyVAL.value = &ConstTerm{Object: yyDollar[1].value.(*ConstObject)} } case 119: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:588 +//line parser.go.y:566 { yyVAL.value = &ConstTerm{Array: yyDollar[1].value.(*ConstArray)} } case 120: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:592 +//line parser.go.y:570 { yyVAL.value = &ConstTerm{Number: yyDollar[1].token} } case 121: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:596 +//line parser.go.y:574 { yyVAL.value = &ConstTerm{Str: yyDollar[1].token} } case 122: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:600 +//line parser.go.y:578 { yyVAL.value = &ConstTerm{Null: true} } case 123: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:604 +//line parser.go.y:582 { yyVAL.value = &ConstTerm{True: true} } case 124: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:608 +//line parser.go.y:586 { yyVAL.value = &ConstTerm{False: true} } case 125: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:614 +//line parser.go.y:592 { yyVAL.value = &ConstObject{} } case 126: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:618 +//line parser.go.y:596 { yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)} } case 127: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:622 +//line parser.go.y:600 { yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)} } case 128: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:628 +//line parser.go.y:606 { yyVAL.value = []*ConstObjectKeyVal{yyDollar[1].value.(*ConstObjectKeyVal)} } case 129: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:632 +//line parser.go.y:610 { yyVAL.value = append(yyDollar[1].value.([]*ConstObjectKeyVal), yyDollar[3].value.(*ConstObjectKeyVal)) } case 130: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:638 +//line parser.go.y:616 { yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)} } case 131: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:642 +//line parser.go.y:620 { yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)} } case 132: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:646 +//line parser.go.y:624 { yyVAL.value = &ConstObjectKeyVal{KeyString: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)} } case 133: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:652 +//line parser.go.y:630 { yyVAL.value = &ConstArray{} } case 134: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:656 +//line parser.go.y:634 { yyVAL.value = &ConstArray{yyDollar[2].value.([]*ConstTerm)} } case 135: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:662 +//line parser.go.y:640 { yyVAL.value = []*ConstTerm{yyDollar[1].value.(*ConstTerm)} } case 136: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:666 +//line parser.go.y:644 { yyVAL.value = append(yyDollar[1].value.([]*ConstTerm), yyDollar[3].value.(*ConstTerm)) } - case 137: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:671 - { - } - case 138: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:672 - { - } - case 139: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:673 - { - } - case 140: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:674 - { - } - case 141: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:675 - { - } - case 142: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:676 - { - } - case 143: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:677 - { - } - case 144: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:678 - { - } - case 145: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:679 - { - } - case 146: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:680 - { - } - case 147: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:681 - { - } - case 148: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:682 - { - } - case 149: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:683 - { - } - case 150: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:684 - { - } - case 151: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:685 - { - } - case 152: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:686 - { - } - case 153: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:687 - { - } - case 154: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:688 - { - } - case 155: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:689 - { - } - case 156: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:690 - { - } - case 157: - yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:691 - { - } } goto yystack /* stack new state and value */ } diff --git a/vendor/github.com/itchyny/gojq/parser.go.y b/vendor/github.com/itchyny/gojq/parser.go.y index e03b14bc42..5481e21140 100644 --- a/vendor/github.com/itchyny/gojq/parser.go.y +++ b/vendor/github.com/itchyny/gojq/parser.go.y @@ -1,20 +1,6 @@ %{ package gojq -// Parse a query string, and returns the query struct. -// -// If parsing failed, the returned error has the method Token() (string, int), -// which reports the invalid token and the byte offset in the query string. The -// token is empty if the error occurred after scanning the entire query string. -// The byte offset is the scanned bytes when the error occurred. -func Parse(src string) (*Query, error) { - l := newLexer(src) - if yyParse(l) > 0 { - return nil, l.err - } - return l.result, nil -} - func reverseFuncDef(xs []*FuncDef) []*FuncDef { for i, j := 0, len(xs)-1; i < j; i, j = i+1, j-1 { xs[i], xs[j] = xs[j], xs[i] @@ -31,29 +17,28 @@ func prependFuncDef(xs []*FuncDef, x *FuncDef) []*FuncDef { %} %union { - value interface{} + value any token string operator Operator } -%type program moduleheader programbody imports import metaopt funcdefs funcdef funcdefargs query +%type program header imports import meta body funcdefs funcdef funcargs query %type bindpatterns pattern arraypatterns objectpatterns objectpattern -%type term string stringparts suffix args ifelifs ifelse trycatch +%type expr term string stringparts suffix args ifelifs ifelse trycatch %type objectkeyvals objectkeyval objectval %type constterm constobject constobjectkeyvals constobjectkeyval constarray constarrayelems %type tokIdentVariable tokIdentModuleIdent tokVariableModuleVariable tokKeyword objectkey -%token tokAltOp tokUpdateOp tokDestAltOp tokOrOp tokAndOp tokCompareOp -%token tokModule tokImport tokInclude tokDef tokAs tokLabel tokBreak +%token tokAltOp tokUpdateOp tokDestAltOp tokCompareOp +%token tokOrOp tokAndOp tokModule tokImport tokInclude tokDef tokAs tokLabel tokBreak %token tokNull tokTrue tokFalse -%token tokIdent tokVariable tokModuleIdent tokModuleVariable -%token tokIndex tokNumber tokFormat -%token tokString tokStringStart tokStringQuery tokStringEnd %token tokIf tokThen tokElif tokElse tokEnd %token tokTry tokCatch tokReduce tokForeach -%token tokRecurse tokFuncDefPost tokTermPost tokEmptyCatch -%token tokInvalid tokInvalidEscapeSequence tokUnterminatedString +%token tokIdent tokVariable tokModuleIdent tokModuleVariable +%token tokRecurse tokIndex tokNumber tokFormat +%token tokString tokStringStart tokStringQuery tokStringEnd +%token tokInvalid tokInvalidEscapeSequence tokUnterminatedString -%nonassoc tokFuncDefPost tokTermPost +%nonassoc tokFuncDefQuery tokExpr tokTerm %right '|' %left ',' %right tokAltOp @@ -69,33 +54,24 @@ func prependFuncDef(xs []*FuncDef, x *FuncDef) []*FuncDef { %% program - : moduleheader programbody + : header imports body { - if $1 != nil { $2.(*Query).Meta = $1.(*ConstObject) } - yylex.(*lexer).result = $2.(*Query) + query := $3.(*Query) + query.Meta = $1.(*ConstObject) + query.Imports = $2.([]*Import) + yylex.(*lexer).result = query } -moduleheader +header : { - $$ = nil + $$ = (*ConstObject)(nil) } | tokModule constobject ';' { $$ = $2; } -programbody - : imports funcdefs - { - $$ = &Query{Imports: $1.([]*Import), FuncDefs: reverseFuncDef($2.([]*FuncDef)), Term: &Term{Type: TermTypeIdentity}} - } - | imports query - { - if $1 != nil { $2.(*Query).Imports = $1.([]*Import) } - $$ = $2 - } - imports : { @@ -107,21 +83,28 @@ imports } import - : tokImport tokString tokAs tokIdentVariable metaopt ';' + : tokImport tokString tokAs tokIdentVariable meta ';' { $$ = &Import{ImportPath: $2, ImportAlias: $4, Meta: $5.(*ConstObject)} } - | tokInclude tokString metaopt ';' + | tokInclude tokString meta ';' { $$ = &Import{IncludePath: $2, Meta: $3.(*ConstObject)} } -metaopt +meta : { $$ = (*ConstObject)(nil) } - | constobject {} + | constobject + +body + : funcdefs + { + $$ = &Query{FuncDefs: reverseFuncDef($1.([]*FuncDef))} + } + | query funcdefs : @@ -138,30 +121,31 @@ funcdef { $$ = &FuncDef{Name: $2, Body: $4.(*Query)} } - | tokDef tokIdent '(' funcdefargs ')' ':' query ';' + | tokDef tokIdent '(' funcargs ')' ':' query ';' { $$ = &FuncDef{$2, $4.([]string), $7.(*Query)} } -funcdefargs +funcargs : tokIdentVariable { $$ = []string{$1} } - | funcdefargs ';' tokIdentVariable + | funcargs ';' tokIdentVariable { $$ = append($1.([]string), $3) } tokIdentVariable - : tokIdent {} - | tokVariable {} + : tokIdent + | tokVariable query - : funcdef query %prec tokFuncDefPost + : funcdef query %prec tokFuncDefQuery { - $2.(*Query).FuncDefs = prependFuncDef($2.(*Query).FuncDefs, $1.(*FuncDef)) - $$ = $2 + query := $2.(*Query) + query.FuncDefs = prependFuncDef(query.FuncDefs, $1.(*FuncDef)) + $$ = query } | query '|' query { @@ -169,86 +153,62 @@ query } | term tokAs bindpatterns '|' query { - $1.(*Term).SuffixList = append($1.(*Term).SuffixList, &Suffix{Bind: &Bind{$3.([]*Pattern), $5.(*Query)}}) - $$ = &Query{Term: $1.(*Term)} - } - | tokReduce term tokAs pattern '(' query ';' query ')' - { - $$ = &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{$2.(*Term), $4.(*Pattern), $6.(*Query), $8.(*Query)}}} - } - | tokForeach term tokAs pattern '(' query ';' query ')' - { - $$ = &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{$2.(*Term), $4.(*Pattern), $6.(*Query), $8.(*Query), nil}}} - } - | tokForeach term tokAs pattern '(' query ';' query ';' query ')' - { - $$ = &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{$2.(*Term), $4.(*Pattern), $6.(*Query), $8.(*Query), $10.(*Query)}}} - } - | tokIf query tokThen query ifelifs ifelse tokEnd - { - $$ = &Query{Term: &Term{Type: TermTypeIf, If: &If{$2.(*Query), $4.(*Query), $5.([]*IfElif), $6.(*Query)}}} - } - | tokTry query trycatch - { - $$ = &Query{Term: &Term{Type: TermTypeTry, Try: &Try{$2.(*Query), $3.(*Query)}}} + term := $1.(*Term) + term.SuffixList = append(term.SuffixList, &Suffix{Bind: &Bind{$3.([]*Pattern), $5.(*Query)}}) + $$ = &Query{Term: term} } | tokLabel tokVariable '|' query { $$ = &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{$2, $4.(*Query)}}} } - | query '?' - { - if t := $1.(*Query).Term; t != nil { - t.SuffixList = append(t.SuffixList, &Suffix{Optional: true}) - } else { - $$ = &Query{Term: &Term{Type: TermTypeQuery, Query: $1.(*Query), SuffixList: []*Suffix{{Optional: true}}}} - } - } | query ',' query { $$ = &Query{Left: $1.(*Query), Op: OpComma, Right: $3.(*Query)} } - | query tokAltOp query + | expr %prec tokExpr + +expr + : expr tokAltOp expr { $$ = &Query{Left: $1.(*Query), Op: $2, Right: $3.(*Query)} } - | query tokUpdateOp query + | expr tokUpdateOp expr { $$ = &Query{Left: $1.(*Query), Op: $2, Right: $3.(*Query)} } - | query tokOrOp query + | expr tokOrOp expr { $$ = &Query{Left: $1.(*Query), Op: OpOr, Right: $3.(*Query)} } - | query tokAndOp query + | expr tokAndOp expr { $$ = &Query{Left: $1.(*Query), Op: OpAnd, Right: $3.(*Query)} } - | query tokCompareOp query + | expr tokCompareOp expr { $$ = &Query{Left: $1.(*Query), Op: $2, Right: $3.(*Query)} } - | query '+' query + | expr '+' expr { $$ = &Query{Left: $1.(*Query), Op: OpAdd, Right: $3.(*Query)} } - | query '-' query + | expr '-' expr { $$ = &Query{Left: $1.(*Query), Op: OpSub, Right: $3.(*Query)} } - | query '*' query + | expr '*' expr { $$ = &Query{Left: $1.(*Query), Op: OpMul, Right: $3.(*Query)} } - | query '/' query + | expr '/' expr { $$ = &Query{Left: $1.(*Query), Op: OpDiv, Right: $3.(*Query)} } - | query '%' query + | expr '%' expr { $$ = &Query{Left: $1.(*Query), Op: OpMod, Right: $3.(*Query)} } - | term %prec tokTermPost + | term %prec tokTerm { $$ = &Query{Term: $1.(*Term)} } @@ -330,10 +290,11 @@ term } | '.' suffix { - if $2.(*Suffix).Iter { - $$ = &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{$2.(*Suffix)}} + suffix := $2.(*Suffix) + if suffix.Iter { + $$ = &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{suffix}} } else { - $$ = &Term{Type: TermTypeIndex, Index: $2.(*Suffix).Index} + $$ = &Term{Type: TermTypeIndex, Index: suffix.Index} } } | '.' string @@ -364,25 +325,29 @@ term { $$ = &Term{Type: TermTypeFunc, Func: &Func{Name: $1}} } - | tokNumber + | '{' '}' { - $$ = &Term{Type: TermTypeNumber, Number: $1} + $$ = &Term{Type: TermTypeObject, Object: &Object{}} } - | tokFormat + | '{' objectkeyvals '}' { - $$ = &Term{Type: TermTypeFormat, Format: $1} + $$ = &Term{Type: TermTypeObject, Object: &Object{$2.([]*ObjectKeyVal)}} } - | tokFormat string + | '{' objectkeyvals ',' '}' { - $$ = &Term{Type: TermTypeFormat, Format: $1, Str: $2.(*String)} + $$ = &Term{Type: TermTypeObject, Object: &Object{$2.([]*ObjectKeyVal)}} } - | string + | '[' ']' { - $$ = &Term{Type: TermTypeString, Str: $1.(*String)} + $$ = &Term{Type: TermTypeArray, Array: &Array{}} } - | '(' query ')' + | '[' query ']' { - $$ = &Term{Type: TermTypeQuery, Query: $2.(*Query)} + $$ = &Term{Type: TermTypeArray, Array: &Array{$2.(*Query)}} + } + | tokNumber + { + $$ = &Term{Type: TermTypeNumber, Number: $1} } | '+' term { @@ -392,30 +357,46 @@ term { $$ = &Term{Type: TermTypeUnary, Unary: &Unary{OpSub, $2.(*Term)}} } - | '{' '}' + | tokFormat { - $$ = &Term{Type: TermTypeObject, Object: &Object{}} + $$ = &Term{Type: TermTypeFormat, Format: $1} } - | '{' objectkeyvals '}' + | tokFormat string { - $$ = &Term{Type: TermTypeObject, Object: &Object{$2.([]*ObjectKeyVal)}} + $$ = &Term{Type: TermTypeFormat, Format: $1, Str: $2.(*String)} } - | '{' objectkeyvals ',' '}' + | string { - $$ = &Term{Type: TermTypeObject, Object: &Object{$2.([]*ObjectKeyVal)}} + $$ = &Term{Type: TermTypeString, Str: $1.(*String)} } - | '[' ']' + | tokIf query tokThen query ifelifs ifelse tokEnd { - $$ = &Term{Type: TermTypeArray, Array: &Array{}} + $$ = &Term{Type: TermTypeIf, If: &If{$2.(*Query), $4.(*Query), $5.([]*IfElif), $6.(*Query)}} } - | '[' query ']' + | tokTry expr trycatch { - $$ = &Term{Type: TermTypeArray, Array: &Array{$2.(*Query)}} + $$ = &Term{Type: TermTypeTry, Try: &Try{$2.(*Query), $3.(*Query)}} + } + | tokReduce expr tokAs pattern '(' query ';' query ')' + { + $$ = &Term{Type: TermTypeReduce, Reduce: &Reduce{$2.(*Query), $4.(*Pattern), $6.(*Query), $8.(*Query)}} + } + | tokForeach expr tokAs pattern '(' query ';' query ')' + { + $$ = &Term{Type: TermTypeForeach, Foreach: &Foreach{$2.(*Query), $4.(*Pattern), $6.(*Query), $8.(*Query), nil}} + } + | tokForeach expr tokAs pattern '(' query ';' query ';' query ')' + { + $$ = &Term{Type: TermTypeForeach, Foreach: &Foreach{$2.(*Query), $4.(*Pattern), $6.(*Query), $8.(*Query), $10.(*Query)}} } | tokBreak tokVariable { $$ = &Term{Type: TermTypeBreak, Break: $2} } + | '(' query ')' + { + $$ = &Term{Type: TermTypeQuery, Query: $2.(*Query)} + } | term tokIndex { $1.(*Term).SuffixList = append($1.(*Term).SuffixList, &Suffix{Index: &Index{Name: $2}}) @@ -463,12 +444,12 @@ stringparts } tokIdentModuleIdent - : tokIdent {} - | tokModuleIdent {} + : tokIdent + | tokModuleIdent tokVariableModuleVariable - : tokVariable {} - | tokModuleVariable {} + : tokVariable + | tokModuleVariable suffix : '[' ']' @@ -527,7 +508,7 @@ trycatch { $$ = (*Query)(nil) } - | tokCatch query + | tokCatch expr { $$ = $2 } @@ -545,15 +526,15 @@ objectkeyvals objectkeyval : objectkey ':' objectval { - $$ = &ObjectKeyVal{Key: $1, Val: $3.(*ObjectVal)} + $$ = &ObjectKeyVal{Key: $1, Val: $3.(*Query)} } | string ':' objectval { - $$ = &ObjectKeyVal{KeyString: $1.(*String), Val: $3.(*ObjectVal)} + $$ = &ObjectKeyVal{KeyString: $1.(*String), Val: $3.(*Query)} } | '(' query ')' ':' objectval { - $$ = &ObjectKeyVal{KeyQuery: $2.(*Query), Val: $5.(*ObjectVal)} + $$ = &ObjectKeyVal{KeyQuery: $2.(*Query), Val: $5.(*Query)} } | objectkey { @@ -565,19 +546,16 @@ objectkeyval } objectkey - : tokIdent {} - | tokVariable {} - | tokKeyword {} + : tokIdent + | tokVariable + | tokKeyword objectval - : term + : objectval '|' objectval { - $$ = &ObjectVal{[]*Query{{Term: $1.(*Term)}}} - } - | objectval '|' term - { - $$ = &ObjectVal{append($1.(*ObjectVal).Queries, &Query{Term: $3.(*Term)})} + $$ = &Query{Left: $1.(*Query), Op: OpPipe, Right: $3.(*Query)} } + | expr constterm : constobject @@ -668,26 +646,26 @@ constarrayelems } tokKeyword - : tokOrOp {} - | tokAndOp {} - | tokModule {} - | tokImport {} - | tokInclude {} - | tokDef {} - | tokAs {} - | tokLabel {} - | tokBreak {} - | tokNull {} - | tokTrue {} - | tokFalse {} - | tokIf {} - | tokThen {} - | tokElif {} - | tokElse {} - | tokEnd {} - | tokTry {} - | tokCatch {} - | tokReduce {} - | tokForeach {} + : tokOrOp + | tokAndOp + | tokModule + | tokImport + | tokInclude + | tokDef + | tokAs + | tokLabel + | tokBreak + | tokNull + | tokTrue + | tokFalse + | tokIf + | tokThen + | tokElif + | tokElse + | tokEnd + | tokTry + | tokCatch + | tokReduce + | tokForeach %% diff --git a/vendor/github.com/itchyny/gojq/preview.go b/vendor/github.com/itchyny/gojq/preview.go index 763d5109e5..e082eb5619 100644 --- a/vendor/github.com/itchyny/gojq/preview.go +++ b/vendor/github.com/itchyny/gojq/preview.go @@ -8,18 +8,18 @@ import "unicode/utf8" // // This method is used by error messages of built-in operators and functions, // and accepts only limited types (nil, bool, int, float64, *big.Int, string, -// []interface{}, and map[string]interface{}). Note that the maximum width and -// trailing strings on truncation may be changed in the future. -func Preview(v interface{}) string { +// []any, and map[string]any). Note that the maximum width and trailing strings +// on truncation may be changed in the future. +func Preview(v any) string { bs := jsonLimitedMarshal(v, 32) if l := 30; len(bs) > l { var trailing string switch v.(type) { case string: trailing = ` ..."` - case []interface{}: + case []any: trailing = " ...]" - case map[string]interface{}: + case map[string]any: trailing = " ...}" default: trailing = " ..." @@ -33,7 +33,7 @@ func Preview(v interface{}) string { return string(bs) } -func jsonLimitedMarshal(v interface{}, n int) (bs []byte) { +func jsonLimitedMarshal(v any, n int) (bs []byte) { w := &limitedWriter{buf: make([]byte, n)} defer func() { _ = recover() @@ -51,7 +51,7 @@ type limitedWriter struct { func (w *limitedWriter) Write(bs []byte) (int, error) { n := copy(w.buf[w.off:], bs) if w.off += n; w.off == len(w.buf) { - panic(nil) + panic(struct{}{}) } return n, nil } @@ -59,7 +59,7 @@ func (w *limitedWriter) Write(bs []byte) (int, error) { func (w *limitedWriter) WriteByte(b byte) error { w.buf[w.off] = b if w.off++; w.off == len(w.buf) { - panic(nil) + panic(struct{}{}) } return nil } @@ -67,7 +67,7 @@ func (w *limitedWriter) WriteByte(b byte) error { func (w *limitedWriter) WriteString(s string) (int, error) { n := copy(w.buf[w.off:], s) if w.off += n; w.off == len(w.buf) { - panic(nil) + panic(struct{}{}) } return n, nil } diff --git a/vendor/github.com/itchyny/gojq/query.go b/vendor/github.com/itchyny/gojq/query.go index 4bba2d2add..e7cf778908 100644 --- a/vendor/github.com/itchyny/gojq/query.go +++ b/vendor/github.com/itchyny/gojq/query.go @@ -5,6 +5,20 @@ import ( "strings" ) +// Parse a query string, and returns the query struct. +// +// If parsing failed, it returns an error of type [*ParseError], which has +// the byte offset and the invalid token. The byte offset is the scanned bytes +// when the error occurred. The token is empty if the error occurred after +// scanning the entire query string. +func Parse(src string) (*Query, error) { + l := newLexer(src) + if yyParse(l) > 0 { + return nil, l.err + } + return l.result, nil +} + // Query represents the abstract syntax tree of a jq query. type Query struct { Meta *ConstObject @@ -21,12 +35,12 @@ type Query struct { // // It is safe to call this method in goroutines, to reuse a parsed [*Query]. // But for arguments, do not give values sharing same data between goroutines. -func (e *Query) Run(v interface{}) Iter { +func (e *Query) Run(v any) Iter { return e.RunWithContext(context.Background(), v) } // RunWithContext runs the query with context. -func (e *Query) RunWithContext(ctx context.Context, v interface{}) Iter { +func (e *Query) RunWithContext(ctx context.Context, v any) Iter { code, err := Compile(e) if err != nil { return NewIter(err) @@ -49,13 +63,8 @@ func (e *Query) writeTo(s *strings.Builder) { for _, im := range e.Imports { im.writeTo(s) } - for i, fd := range e.FuncDefs { - if i > 0 { - s.WriteByte(' ') - } + for _, fd := range e.FuncDefs { fd.writeTo(s) - } - if len(e.FuncDefs) > 0 { s.WriteByte(' ') } if e.Func != "" { @@ -92,14 +101,14 @@ func (e *Query) minify() { } } -func (e *Query) toIndexKey() interface{} { +func (e *Query) toIndexKey() any { if e.Term == nil { return nil } return e.Term.toIndexKey() } -func (e *Query) toIndices(xs []interface{}) []interface{} { +func (e *Query) toIndices(xs []any) []any { if e.Term == nil { return nil } @@ -314,7 +323,7 @@ func (e *Term) toFunc() string { } } -func (e *Term) toIndexKey() interface{} { +func (e *Term) toIndexKey() any { switch e.Type { case TermTypeNumber: return toNumber(e.Number) @@ -330,7 +339,7 @@ func (e *Term) toIndexKey() interface{} { } } -func (e *Term) toIndices(xs []interface{}) []interface{} { +func (e *Term) toIndices(xs []any) []any { switch e.Type { case TermTypeIndex: if xs = e.Index.toIndices(xs); xs == nil { @@ -351,7 +360,7 @@ func (e *Term) toIndices(xs []interface{}) []interface{} { return xs } -func (e *Term) toNumber() interface{} { +func (e *Term) toNumber() any { if e.Type == TermTypeNumber { return toNumber(e.Number) } @@ -379,7 +388,7 @@ func (e *Unary) minify() { e.Term.minify() } -func (e *Unary) toNumber() interface{} { +func (e *Unary) toNumber() any { v := e.Term.toNumber() if v != nil && e.Op == OpSub { v = funcOpNegate(v) @@ -514,7 +523,7 @@ func (e *Index) minify() { } } -func (e *Index) toIndexKey() interface{} { +func (e *Index) toIndexKey() any { if e.Name != "" { return e.Name } else if e.Str != nil { @@ -524,7 +533,7 @@ func (e *Index) toIndexKey() interface{} { } else if !e.IsSlice { return e.Start.toIndexKey() } else { - var start, end interface{} + var start, end any ok := true if e.Start != nil { start = e.Start.toIndexKey() @@ -535,13 +544,13 @@ func (e *Index) toIndexKey() interface{} { ok = end != nil } if ok { - return map[string]interface{}{"start": start, "end": end} + return map[string]any{"start": start, "end": end} } } return nil } -func (e *Index) toIndices(xs []interface{}) []interface{} { +func (e *Index) toIndices(xs []any) []any { if k := e.toIndexKey(); k != nil { return append(xs, k) } @@ -660,7 +669,7 @@ type ObjectKeyVal struct { Key string KeyString *String KeyQuery *Query - Val *ObjectVal + Val *Query } func (e *ObjectKeyVal) String() string { @@ -696,32 +705,6 @@ func (e *ObjectKeyVal) minify() { } } -// ObjectVal ... -type ObjectVal struct { - Queries []*Query -} - -func (e *ObjectVal) String() string { - var s strings.Builder - e.writeTo(&s) - return s.String() -} - -func (e *ObjectVal) writeTo(s *strings.Builder) { - for i, e := range e.Queries { - if i > 0 { - s.WriteString(" | ") - } - e.writeTo(s) - } -} - -func (e *ObjectVal) minify() { - for _, e := range e.Queries { - e.minify() - } -} - // Array ... type Array struct { Query *Query @@ -795,7 +778,7 @@ func (e *Suffix) toTerm() *Term { } } -func (e *Suffix) toIndices(xs []interface{}) []interface{} { +func (e *Suffix) toIndices(xs []any) []any { if e.Index == nil { return nil } @@ -929,7 +912,7 @@ func (e *Try) minify() { // Reduce ... type Reduce struct { - Term *Term + Query *Query Pattern *Pattern Start *Query Update *Query @@ -943,7 +926,7 @@ func (e *Reduce) String() string { func (e *Reduce) writeTo(s *strings.Builder) { s.WriteString("reduce ") - e.Term.writeTo(s) + e.Query.writeTo(s) s.WriteString(" as ") e.Pattern.writeTo(s) s.WriteString(" (") @@ -954,14 +937,14 @@ func (e *Reduce) writeTo(s *strings.Builder) { } func (e *Reduce) minify() { - e.Term.minify() + e.Query.minify() e.Start.minify() e.Update.minify() } // Foreach ... type Foreach struct { - Term *Term + Query *Query Pattern *Pattern Start *Query Update *Query @@ -976,7 +959,7 @@ func (e *Foreach) String() string { func (e *Foreach) writeTo(s *strings.Builder) { s.WriteString("foreach ") - e.Term.writeTo(s) + e.Query.writeTo(s) s.WriteString(" as ") e.Pattern.writeTo(s) s.WriteString(" (") @@ -991,7 +974,7 @@ func (e *Foreach) writeTo(s *strings.Builder) { } func (e *Foreach) minify() { - e.Term.minify() + e.Query.minify() e.Start.minify() e.Update.minify() if e.Extract != nil { @@ -1057,7 +1040,7 @@ func (e *ConstTerm) writeTo(s *strings.Builder) { } } -func (e *ConstTerm) toValue() interface{} { +func (e *ConstTerm) toValue() any { if e.Object != nil { return e.Object.ToValue() } else if e.Array != nil { @@ -1075,6 +1058,14 @@ func (e *ConstTerm) toValue() interface{} { } } +func (e *ConstTerm) toString() (string, bool) { + if e.Object != nil || e.Array != nil || + e.Number != "" || e.Null || e.True || e.False { + return "", false + } + return e.Str, true +} + // ConstObject ... type ConstObject struct { KeyVals []*ConstObjectKeyVal @@ -1101,12 +1092,12 @@ func (e *ConstObject) writeTo(s *strings.Builder) { s.WriteString(" }") } -// ToValue converts the object to map[string]interface{}. -func (e *ConstObject) ToValue() map[string]interface{} { +// ToValue converts the object to map[string]any. +func (e *ConstObject) ToValue() map[string]any { if e == nil { return nil } - v := make(map[string]interface{}, len(e.KeyVals)) + v := make(map[string]any, len(e.KeyVals)) for _, e := range e.KeyVals { key := e.Key if key == "" { @@ -1134,7 +1125,7 @@ func (e *ConstObjectKeyVal) writeTo(s *strings.Builder) { if e.Key != "" { s.WriteString(e.Key) } else { - s.WriteString(e.KeyString) + jsonEncodeString(s, e.KeyString) } s.WriteString(": ") e.Val.writeTo(s) @@ -1162,8 +1153,8 @@ func (e *ConstArray) writeTo(s *strings.Builder) { s.WriteByte(']') } -func (e *ConstArray) toValue() []interface{} { - v := make([]interface{}, len(e.Elems)) +func (e *ConstArray) toValue() []any { + v := make([]any, len(e.Elems)) for i, e := range e.Elems { v[i] = e.toValue() } diff --git a/vendor/github.com/itchyny/gojq/release.go b/vendor/github.com/itchyny/gojq/release.go index 1144485e7e..7bbf77e61a 100644 --- a/vendor/github.com/itchyny/gojq/release.go +++ b/vendor/github.com/itchyny/gojq/release.go @@ -1,16 +1,15 @@ //go:build !gojq_debug -// +build !gojq_debug package gojq type codeinfo struct{} -func (c *compiler) appendCodeInfo(interface{}) {} +func (*compiler) appendCodeInfo(any) {} -func (c *compiler) deleteCodeInfo(string) {} +func (*compiler) deleteCodeInfo(string) {} -func (env *env) debugCodes() {} +func (*env) debugCodes() {} -func (env *env) debugState(int, bool) {} +func (*env) debugState(int, bool) {} -func (env *env) debugForks(int, string) {} +func (*env) debugForks(int, string) {} diff --git a/vendor/github.com/itchyny/gojq/scope_stack.go b/vendor/github.com/itchyny/gojq/scope_stack.go index e140ca15b8..f652e2997c 100644 --- a/vendor/github.com/itchyny/gojq/scope_stack.go +++ b/vendor/github.com/itchyny/gojq/scope_stack.go @@ -17,13 +17,9 @@ func newScopeStack() *scopeStack { func (s *scopeStack) push(v scope) { b := scopeBlock{v, s.index} - i := s.index + 1 - if i <= s.limit { - i = s.limit + 1 - } - s.index = i - if i < len(s.data) { - s.data[i] = b + s.index = max(s.index, s.limit) + 1 + if s.index < len(s.data) { + s.data[s.index] = b } else { s.data = append(s.data, b) } diff --git a/vendor/github.com/itchyny/gojq/stack.go b/vendor/github.com/itchyny/gojq/stack.go index 50445fc21b..0983ed26a2 100644 --- a/vendor/github.com/itchyny/gojq/stack.go +++ b/vendor/github.com/itchyny/gojq/stack.go @@ -7,7 +7,7 @@ type stack struct { } type block struct { - value interface{} + value any next int } @@ -15,27 +15,23 @@ func newStack() *stack { return &stack{index: -1, limit: -1} } -func (s *stack) push(v interface{}) { +func (s *stack) push(v any) { b := block{v, s.index} - i := s.index + 1 - if i <= s.limit { - i = s.limit + 1 - } - s.index = i - if i < len(s.data) { - s.data[i] = b + s.index = max(s.index, s.limit) + 1 + if s.index < len(s.data) { + s.data[s.index] = b } else { s.data = append(s.data, b) } } -func (s *stack) pop() interface{} { +func (s *stack) pop() any { b := s.data[s.index] s.index = b.next return b.value } -func (s *stack) top() interface{} { +func (s *stack) top() any { return s.data[s.index].value } diff --git a/vendor/github.com/itchyny/gojq/type.go b/vendor/github.com/itchyny/gojq/type.go index 578a6f4c86..bb388e20e4 100644 --- a/vendor/github.com/itchyny/gojq/type.go +++ b/vendor/github.com/itchyny/gojq/type.go @@ -8,9 +8,8 @@ import ( // TypeOf returns the jq-flavored type name of v. // // This method is used by built-in type/0 function, and accepts only limited -// types (nil, bool, int, float64, *big.Int, string, []interface{}, -// and map[string]interface{}). -func TypeOf(v interface{}) string { +// types (nil, bool, int, float64, *big.Int, string, []any, and map[string]any). +func TypeOf(v any) string { switch v.(type) { case nil: return "null" @@ -20,9 +19,9 @@ func TypeOf(v interface{}) string { return "number" case string: return "string" - case []interface{}: + case []any: return "array" - case map[string]interface{}: + case map[string]any: return "object" default: panic(fmt.Sprintf("invalid type: %[1]T (%[1]v)", v)) diff --git a/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md index 075ca8ef60..d863ac3bea 100644 --- a/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md +++ b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md @@ -1,4 +1,12 @@ # Changelog +## [v0.1.6](https://github.com/itchyny/timefmt-go/compare/v0.1.5..v0.1.6) (2024-06-01) +* support parsing week directives (`%A`, `%a`, `%w`, `%u`, `%V`, `%U`, `%W`) +* validate range of values on parsing directives +* fix formatting `%l` to show `12` at midnight + +## [v0.1.5](https://github.com/itchyny/timefmt-go/compare/v0.1.4..v0.1.5) (2022-12-01) +* support parsing time zone offset with name using both `%z` and `%Z` + ## [v0.1.4](https://github.com/itchyny/timefmt-go/compare/v0.1.3..v0.1.4) (2022-09-01) * improve documents * drop support for Go 1.16 diff --git a/vendor/github.com/itchyny/timefmt-go/README.md b/vendor/github.com/itchyny/timefmt-go/README.md index f01af96112..9c028c746a 100644 --- a/vendor/github.com/itchyny/timefmt-go/README.md +++ b/vendor/github.com/itchyny/timefmt-go/README.md @@ -1,5 +1,5 @@ # timefmt-go -[![CI Status](https://github.com/itchyny/timefmt-go/workflows/CI/badge.svg)](https://github.com/itchyny/timefmt-go/actions) +[![CI Status](https://github.com/itchyny/timefmt-go/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/itchyny/timefmt-go/actions?query=branch:main) [![Go Report Card](https://goreportcard.com/badge/github.com/itchyny/timefmt-go)](https://goreportcard.com/report/github.com/itchyny/timefmt-go) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/timefmt-go/blob/main/LICENSE) [![release](https://img.shields.io/github/release/itchyny/timefmt-go/all.svg)](https://github.com/itchyny/timefmt-go/releases) @@ -54,7 +54,7 @@ Note that `E` and `O` modifier characters are not supported. - `Parse` (`strptime`) allows to parse - composed directives like `%F %T`, - century years like `%C %y`, - - week names like `%A` `%a` (parsed results are discarded). + - week directives like `%W %a` and `%G-W%V-%u`. - `ParseInLocation` is provided for configuring the default location. ![](https://user-images.githubusercontent.com/375258/88606920-de475c80-d0b8-11ea-8d40-cbfee9e35c2e.jpg) @@ -63,7 +63,7 @@ Note that `E` and `O` modifier characters are not supported. Report bug at [Issues・itchyny/timefmt-go - GitHub](https://github.com/itchyny/timefmt-go/issues). ## Author -itchyny (https://github.com/itchyny) +itchyny () ## License This software is released under the MIT License, see LICENSE. diff --git a/vendor/github.com/itchyny/timefmt-go/format.go b/vendor/github.com/itchyny/timefmt-go/format.go index eea976ee9c..b38202dff0 100644 --- a/vendor/github.com/itchyny/timefmt-go/format.go +++ b/vendor/github.com/itchyny/timefmt-go/format.go @@ -132,19 +132,13 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { case 'a': buf = appendString(buf, shortWeekNames[t.Weekday()], width, padding, upper, swap) case 'w': - for ; width > 1; width-- { - buf = append(buf, padding&paddingMask) - } - buf = append(buf, '0'+byte(t.Weekday())) + buf = appendInt(buf, int(t.Weekday()), width, padding) case 'u': w := int(t.Weekday()) if w == 0 { w = 7 } - for ; width > 1; width-- { - buf = append(buf, padding&paddingMask) - } - buf = append(buf, '0'+byte(w)) + buf = appendInt(buf, w, width, padding) case 'V': if width < 2 { width = 2 @@ -193,17 +187,10 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { } buf = appendInt(buf, hour, width, padding) case 'l': - if width < 2 { - width = 2 - } if padding < ^paddingMask { padding = ' ' } - h := hour - if h > 12 { - h -= 12 - } - buf = appendInt(buf, h, width, padding) + fallthrough case 'I': if width < 2 { width = 2 @@ -215,18 +202,15 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { h = 12 } buf = appendInt(buf, h, width, padding) + case 'P': + swap = !(upper || swap) + fallthrough case 'p': if hour < 12 { buf = appendString(buf, "AM", width, padding, upper, swap) } else { buf = appendString(buf, "PM", width, padding, upper, swap) } - case 'P': - if hour < 12 { - buf = appendString(buf, "am", width, padding, upper, swap) - } else { - buf = appendString(buf, "pm", width, padding, upper, swap) - } case 'M': if width < 2 { width = 2 @@ -271,14 +255,14 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { if buf[k] == ' ' { buf[k-1], buf[k] = buf[k], buf[k-1] } - if k = offset % 3600; colons <= 2 || k != 0 { + if offset %= 3600; colons <= 2 || offset != 0 { if colons != 0 { buf = append(buf, ':') } - buf = appendInt(buf, k/60, 2, '0') - if k %= 60; colons == 2 || colons == 3 && k != 0 { + buf = appendInt(buf, offset/60, 2, '0') + if offset %= 60; colons == 2 || colons == 3 && offset != 0 { buf = append(buf, ':') - buf = appendInt(buf, k, 2, '0') + buf = appendInt(buf, offset, 2, '0') } } colons = 0 @@ -294,9 +278,7 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { copy(buf[k:], buf[j:]) buf = buf[:l] if padding&paddingMask == '0' { - for ; k > i; k-- { - buf[k-1], buf[k] = buf[k], buf[k-1] - } + buf[i], buf[k] = buf[k], buf[i] } } case ':': @@ -444,7 +426,7 @@ func appendString(buf []byte, str string, width int, padding byte, upper, swap b } switch { case swap: - if str[len(str)-1] < 'a' { + if str[1] < 'a' { for _, b := range []byte(str) { buf = append(buf, b|0x20) } diff --git a/vendor/github.com/itchyny/timefmt-go/parse.go b/vendor/github.com/itchyny/timefmt-go/parse.go index ae21534fc3..26ae0f0c25 100644 --- a/vendor/github.com/itchyny/timefmt-go/parse.go +++ b/vendor/github.com/itchyny/timefmt-go/parse.go @@ -3,6 +3,7 @@ package timefmt import ( "errors" "fmt" + "math" "time" ) @@ -18,31 +19,32 @@ func ParseInLocation(source, format string, loc *time.Location) (t time.Time, er } func parse(source, format string, loc, base *time.Location) (t time.Time, err error) { - year, month, day, hour, min, sec, nsec := 1900, 1, 1, 0, 0, 0, 0 + year, month, day, hour, min, sec, nsec := 1900, 1, 0, 0, 0, 0, 0 defer func() { if err != nil { err = fmt.Errorf("failed to parse %q with %q: %w", source, format, err) } }() - var j, century, yday, colons int - var pm bool + var j, week, weekday, yday, colons int + century, weekstart := -1, time.Weekday(-1) + var pm, hasISOYear, hasZoneName, hasZoneOffset bool var pending string for i, l := 0, len(source); i < len(format); i++ { if b := format[i]; b == '%' { i++ if i == len(format) { - err = errors.New("stray %") + err = errors.New(`stray "%"`) return } b = format[i] L: switch b { case 'Y': - if year, j, err = parseNumber(source, j, 4, 'Y'); err != nil { + if year, j, err = parseNumber(source, j, 4, 0, 9999, 'Y'); err != nil { return } case 'y': - if year, j, err = parseNumber(source, j, 2, 'y'); err != nil { + if year, j, err = parseNumber(source, j, 2, 0, 99, 'y'); err != nil { return } if year < 69 { @@ -51,65 +53,85 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er year += 1900 } case 'C': - if century, j, err = parseNumber(source, j, 2, 'C'); err != nil { + if century, j, err = parseNumber(source, j, 2, 0, 99, 'C'); err != nil { return } case 'g': - if year, j, err = parseNumber(source, j, 2, b); err != nil { + if year, j, err = parseNumber(source, j, 2, 0, 99, b); err != nil { return } year += 2000 + hasISOYear = true case 'G': - if year, j, err = parseNumber(source, j, 4, b); err != nil { + if year, j, err = parseNumber(source, j, 4, 0, 9999, b); err != nil { return } + hasISOYear = true case 'm': - if month, j, err = parseNumber(source, j, 2, 'm'); err != nil { + if month, j, err = parseNumber(source, j, 2, 1, 12, 'm'); err != nil { return } case 'B': - if month, j, err = lookup(source, j, longMonthNames, 'B'); err != nil { + if month, j, err = parseAny(source, j, longMonthNames, 'B'); err != nil { return } case 'b', 'h': - if month, j, err = lookup(source, j, shortMonthNames, b); err != nil { + if month, j, err = parseAny(source, j, shortMonthNames, b); err != nil { return } case 'A': - if _, j, err = lookup(source, j, longWeekNames, 'A'); err != nil { + if weekday, j, err = parseAny(source, j, longWeekNames, 'A'); err != nil { return } case 'a': - if _, j, err = lookup(source, j, shortWeekNames, 'a'); err != nil { + if weekday, j, err = parseAny(source, j, shortWeekNames, 'a'); err != nil { return } case 'w': - if j >= l || source[j] < '0' || '6' < source[j] { - err = parseFormatError(b) + if weekday, j, err = parseNumber(source, j, 1, 0, 6, 'w'); err != nil { return } - j++ + weekday++ case 'u': - if j >= l || source[j] < '1' || '7' < source[j] { - err = parseFormatError(b) + if weekday, j, err = parseNumber(source, j, 1, 1, 7, 'u'); err != nil { return } - j++ - case 'V', 'U', 'W': - if _, j, err = parseNumber(source, j, 2, b); err != nil { + weekday = weekday%7 + 1 + case 'V': + if week, j, err = parseNumber(source, j, 2, 1, 53, b); err != nil { + return + } + weekstart = time.Thursday + if weekday == 0 { + weekday = 2 + } + case 'U': + if week, j, err = parseNumber(source, j, 2, 0, 53, b); err != nil { return } + weekstart = time.Sunday + if weekday == 0 { + weekday = 1 + } + case 'W': + if week, j, err = parseNumber(source, j, 2, 0, 53, b); err != nil { + return + } + weekstart = time.Monday + if weekday == 0 { + weekday = 2 + } case 'e': if j < l && source[j] == ' ' { j++ } fallthrough case 'd': - if day, j, err = parseNumber(source, j, 2, b); err != nil { + if day, j, err = parseNumber(source, j, 2, 1, 31, b); err != nil { return } case 'j': - if yday, j, err = parseNumber(source, j, 3, 'j'); err != nil { + if yday, j, err = parseNumber(source, j, 3, 1, 366, 'j'); err != nil { return } case 'k': @@ -118,7 +140,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } fallthrough case 'H': - if hour, j, err = parseNumber(source, j, 2, b); err != nil { + if hour, j, err = parseNumber(source, j, 2, 0, 23, b); err != nil { return } case 'l': @@ -127,29 +149,29 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } fallthrough case 'I': - if hour, j, err = parseNumber(source, j, 2, b); err != nil { + if hour, j, err = parseNumber(source, j, 2, 1, 12, b); err != nil { return } if hour == 12 { hour = 0 } - case 'p', 'P': + case 'P', 'p': var ampm int - if ampm, j, err = lookup(source, j, []string{"AM", "PM"}, 'p'); err != nil { + if ampm, j, err = parseAny(source, j, []string{"AM", "PM"}, b); err != nil { return } pm = ampm == 2 case 'M': - if min, j, err = parseNumber(source, j, 2, 'M'); err != nil { + if min, j, err = parseNumber(source, j, 2, 0, 59, 'M'); err != nil { return } case 'S': - if sec, j, err = parseNumber(source, j, 2, 'S'); err != nil { + if sec, j, err = parseNumber(source, j, 2, 0, 60, 'S'); err != nil { return } case 's': var unix int - if unix, j, err = parseNumber(source, j, 10, 's'); err != nil { + if unix, j, err = parseNumber(source, j, 10, 0, math.MaxInt, 's'); err != nil { return } t = time.Unix(int64(unix), 0).In(time.UTC) @@ -158,28 +180,34 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er hour, min, sec = t.Clock() month = int(mon) case 'f': - var usec, k, d int - if usec, k, err = parseNumber(source, j, 6, 'f'); err != nil { + usec, i := 0, j + if usec, j, err = parseNumber(source, j, 6, 0, 999999, 'f'); err != nil { return } - for j, d = k, k-j; d < 6; d++ { + for i = j - i; i < 6; i++ { usec *= 10 } nsec = usec * 1000 case 'Z': - k := j - for ; k < l; k++ { - if c := source[k]; c < 'A' || 'Z' < c { + i := j + for ; j < l; j++ { + if c := source[j]; c < 'A' || 'Z' < c { break } } - t, err = time.ParseInLocation("MST", source[j:k], base) + t, err = time.ParseInLocation("MST", source[i:j], base) if err != nil { - err = fmt.Errorf(`cannot parse %q with "%%Z"`, source[j:k]) + err = fmt.Errorf(`cannot parse %q with "%%Z"`, source[i:j]) return } - loc = t.Location() - j = k + if hasZoneOffset { + name, _ := t.Zone() + _, offset := locationZone(loc) + loc = time.FixedZone(name, offset) + } else { + loc = t.Location() + } + hasZoneName = true case 'z': if j >= l { err = parseZFormatError(colons) @@ -191,47 +219,49 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er sign = -1 fallthrough case '+': - var hour, min, sec, k int - if hour, k, _ = parseNumber(source, j+1, 2, 'z'); k != j+3 { + hour, min, sec, i := 0, 0, 0, j + if hour, j, _ = parseNumber(source, j+1, 2, 0, 23, 'z'); j != i+3 { err = parseZFormatError(colons) return } - if j = k; j >= l || source[j] != ':' { - switch colons { - case 1: - err = errors.New("expected ':' for %:z") - return - case 2: - err = errors.New("expected ':' for %::z") + if j >= l || source[j] != ':' { + if colons > 0 { + err = expectedColonForZFormatError(colons) return } } else if j++; colons == 0 { colons = 4 } - if min, k, _ = parseNumber(source, j, 2, 'z'); k != j+2 { - if colons == 0 { - k = j - } else { + i = j + if min, j, _ = parseNumber(source, j, 2, 0, 59, 'z'); j != i+2 { + if colons > 0 { err = parseZFormatError(colons & 3) return } - } - if j = k; colons > 1 { + j = i + } else if colons > 1 { if j >= l || source[j] != ':' { if colons == 2 { - err = errors.New("expected ':' for %::z") - return - } - } else if sec, k, _ = parseNumber(source, j+1, 2, 'z'); k != j+3 { - if colons == 2 { - err = parseZFormatError(colons) + err = expectedColonForZFormatError(colons) return } } else { - j = k + i = j + if sec, j, _ = parseNumber(source, j+1, 2, 0, 59, 'z'); j != i+3 { + if colons == 2 { + err = parseZFormatError(colons) + return + } + j = i + } } } - loc, colons = time.FixedZone("", sign*((hour*60+min)*60+sec)), 0 + var name string + if hasZoneName { + name, _ = locationZone(loc) + } + loc, colons = time.FixedZone(name, sign*((hour*60+min)*60+sec)), 0 + hasZoneOffset = true case 'Z': loc, colons, j = time.UTC, 0, j+1 default: @@ -246,40 +276,32 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } j++ } else { - if i++; i == len(format) { - err = errors.New(`expected 'z' after "%:"`) - return - } else if b = format[i]; b == 'z' { - colons = 1 - } else if b != ':' { - err = errors.New(`expected 'z' after "%:"`) - return - } else if i++; i == len(format) { - err = errors.New(`expected 'z' after "%::"`) - return - } else if b = format[i]; b == 'z' { - colons = 2 - } else { - err = errors.New(`expected 'z' after "%::"`) - return + for colons = 1; colons <= 2; colons++ { + if i++; i == len(format) { + break + } else if b = format[i]; b == 'z' { + goto L + } else if b != ':' || colons == 2 { + break + } } - goto L + err = expectedZAfterColonError(colons) + return } case 't', 'n': - k := j + i := j K: - for ; k < l; k++ { - switch source[k] { + for ; j < l; j++ { + switch source[j] { case ' ', '\t', '\n', '\v', '\f', '\r': default: break K } } - if k == j { - err = fmt.Errorf("expected a space for %%%c", b) + if i == j { + err = fmt.Errorf(`expected a space for "%%%c"`, b) return } - j = k case '%': if j >= l || source[j] != b { err = expectedFormatError(b) @@ -292,7 +314,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er if pending, ok = compositions[b]; ok { break } - err = fmt.Errorf(`unexpected format: "%%%c"`, b) + err = fmt.Errorf(`unexpected format "%%%c"`, b) return } if j >= l || source[j] != b { @@ -305,7 +327,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er b, pending = pending[0], pending[1:] goto L } - } else if j >= len(source) || source[j] != b { + } else if j >= l || source[j] != b { err = expectedFormatError(b) return } else { @@ -313,25 +335,52 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } } if j < len(source) { - err = fmt.Errorf("unconverted string: %q", source[j:]) + err = fmt.Errorf("unparsed string %q", source[j:]) return } if pm { hour += 12 } - if century > 0 { + if century >= 0 { year = century*100 + year%100 } - if yday > 0 { - return time.Date(year, time.January, 1, hour, min, sec, nsec, loc).AddDate(0, 0, yday-1), nil + if day == 0 { + if yday > 0 { + if hasISOYear { + err = errors.New(`use "%Y" to parse non-ISO year for "%j"`) + return + } + return time.Date(year, time.January, yday, hour, min, sec, nsec, loc), nil + } + if weekstart >= time.Sunday { + if weekstart == time.Thursday { + if !hasISOYear { + err = errors.New(`use "%G" to parse ISO year for "%V"`) + return + } + } else if hasISOYear { + err = errors.New(`use "%Y" to parse non-ISO year for "%U" or "%W"`) + return + } + if weekstart > time.Sunday && weekday == 1 { + week++ + } + t := time.Date(year, time.January, -int(weekstart), hour, min, sec, nsec, loc) + return t.AddDate(0, 0, week*7-int(t.Weekday())+weekday-1), nil + } + day = 1 } return time.Date(year, time.Month(month), day, hour, min, sec, nsec, loc), nil } +func locationZone(loc *time.Location) (name string, offset int) { + return time.Date(2000, time.January, 1, 0, 0, 0, 0, loc).Zone() +} + type parseFormatError byte func (err parseFormatError) Error() string { - return fmt.Sprintf("cannot parse %%%c", byte(err)) + return fmt.Sprintf(`cannot parse "%%%c"`, byte(err)) } type expectedFormatError byte @@ -343,46 +392,51 @@ func (err expectedFormatError) Error() string { type parseZFormatError int func (err parseZFormatError) Error() string { - switch int(err) { - case 0: - return "cannot parse %z" - case 1: - return "cannot parse %:z" - default: - return "cannot parse %::z" - } + return `cannot parse "%` + `::z"`[2-err:] +} + +type expectedColonForZFormatError int + +func (err expectedColonForZFormatError) Error() string { + return `expected ':' for "%` + `::z"`[2-err:] +} + +type expectedZAfterColonError int + +func (err expectedZAfterColonError) Error() string { + return `expected 'z' after "%` + `::"`[2-err:] } -func parseNumber(source string, min, size int, format byte) (int, int, error) { - var val int - if l := len(source); min+size > l { +func parseNumber(source string, index, size, min, max int, format byte) (int, int, error) { + var value int + if l := len(source); index+size > l { size = l } else { - size += min + size += index } - i := min + i := index for ; i < size; i++ { if b := source[i]; '0' <= b && b <= '9' { - val = val*10 + int(b&0x0F) + value = value*10 + int(b&0x0F) } else { break } } - if i == min { + if i == index || value < min || max < value { return 0, 0, parseFormatError(format) } - return val, i, nil + return value, i, nil } -func lookup(source string, min int, candidates []string, format byte) (int, int, error) { +func parseAny(source string, index int, candidates []string, format byte) (int, int, error) { L: for i, xs := range candidates { - j := min + j := index for k := 0; k < len(xs); k, j = k+1, j+1 { if j >= len(source) { continue L } - if x, y := xs[k], source[j]; x != y && x|('a'-'A') != y|('a'-'A') { + if x, y := xs[k], source[j]; x != y && x|0x20 != y|0x20 { continue L } } diff --git a/vendor/github.com/itchyny/timefmt-go/timefmt.go b/vendor/github.com/itchyny/timefmt-go/timefmt.go new file mode 100644 index 0000000000..45bf6ae903 --- /dev/null +++ b/vendor/github.com/itchyny/timefmt-go/timefmt.go @@ -0,0 +1,2 @@ +// Package timefmt provides functions for formatting and parsing date time strings. +package timefmt diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index 39bbcf00f0..d0ea68f408 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,6 +1,7 @@ -//go:build (darwin || freebsd || openbsd || netbsd || dragonfly) && !appengine -// +build darwin freebsd openbsd netbsd dragonfly +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine && !tinygo +// +build darwin freebsd openbsd netbsd dragonfly hurd // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index 31503226f6..7402e0618a 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,5 +1,6 @@ -//go:build appengine || js || nacl || wasm -// +build appengine js nacl wasm +//go:build (appengine || js || nacl || tinygo || wasm) && !windows +// +build appengine js nacl tinygo wasm +// +build !windows package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go index 67787657fb..0337d8cf6d 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -1,6 +1,7 @@ -//go:build (linux || aix || zos) && !appengine +//go:build (linux || aix || zos) && !appengine && !tinygo // +build linux aix zos // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/modules.txt b/vendor/modules.txt index da685950a5..27f7e0f8d1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -307,11 +307,11 @@ github.com/hashicorp/go-version # github.com/inconshreveable/mousetrap v1.1.0 ## explicit; go 1.18 github.com/inconshreveable/mousetrap -# github.com/itchyny/gojq v0.12.9 -## explicit; go 1.17 +# github.com/itchyny/gojq v0.12.17 +## explicit; go 1.21 github.com/itchyny/gojq -# github.com/itchyny/timefmt-go v0.1.4 -## explicit; go 1.17 +# github.com/itchyny/timefmt-go v0.1.6 +## explicit; go 1.20 github.com/itchyny/timefmt-go # github.com/jackc/chunkreader/v2 v2.0.1 ## explicit; go 1.12 @@ -353,7 +353,7 @@ github.com/kballard/go-shellquote # github.com/mattn/go-colorable v0.1.7 ## explicit; go 1.13 github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.16 +# github.com/mattn/go-isatty v0.0.20 ## explicit; go 1.15 github.com/mattn/go-isatty # github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d