From b4b29197ea3810397349b2dbf85bf411321b0d48 Mon Sep 17 00:00:00 2001 From: Tim Voronov Date: Mon, 20 Nov 2023 11:36:05 -0500 Subject: [PATCH] Refactored type system --- go.mod | 32 +- go.sum | 69 +- pkg/compiler/compiler.go | 5 +- pkg/compiler/compiler_for_test.go | 19 + pkg/compiler/compiler_for_while_test.go | 27 +- pkg/compiler/compiler_let_test.go | 5 + pkg/compiler/compiler_range_test.go | 35 + pkg/compiler/listener.go | 8 +- pkg/compiler/test_test.go | 7 +- pkg/compiler/visitor.go | 138 +- pkg/drivers/cdp/dom/document.go | 2 +- pkg/drivers/cdp/dom/element.go | 15 +- pkg/drivers/cdp/page.go | 4 +- pkg/drivers/common/frames.go | 2 +- pkg/drivers/common/getter.go | 146 +- pkg/drivers/common/iterator.go | 22 +- pkg/drivers/common/setter.go | 146 - pkg/drivers/cookie.go | 16 +- pkg/drivers/cookies.go | 43 +- pkg/drivers/headers.go | 17 +- pkg/drivers/helpers.go | 14 +- pkg/drivers/http/document.go | 2 +- pkg/drivers/http/element.go | 2 +- pkg/drivers/http/page.go | 2 +- pkg/drivers/request.go | 39 +- pkg/drivers/response.go | 40 +- pkg/drivers/selector.go | 12 +- pkg/drivers/type.go | 24 +- pkg/drivers/value.go | 14 +- pkg/parser/case_changing_stream.go | 2 +- pkg/parser/fql/fql_lexer.go | 48 +- pkg/parser/fql/fql_parser.go | 4282 ++++++++++++--------- pkg/parser/fql/fqlparser_base_listener.go | 4 +- pkg/parser/fql/fqlparser_base_visitor.go | 4 +- pkg/parser/fql/fqlparser_listener.go | 4 +- pkg/parser/fql/fqlparser_visitor.go | 4 +- pkg/parser/parser.go | 2 +- pkg/runtime/collections/adapters.go | 77 - pkg/runtime/collections/collection.go | 28 - pkg/runtime/collections/filter.go | 48 - pkg/runtime/collections/filter_test.go | 210 - pkg/runtime/collections/helpers.go | 69 - pkg/runtime/collections/indexed.go | 67 - pkg/runtime/collections/indexed_test.go | 147 - pkg/runtime/collections/iterator.go | 17 - pkg/runtime/collections/keyed.go | 65 - pkg/runtime/collections/keyed_test.go | 100 - pkg/runtime/collections/limit.go | 62 - pkg/runtime/collections/limit_test.go | 163 - pkg/runtime/collections/map.go | 74 - pkg/runtime/collections/map_test.go | 96 - pkg/runtime/collections/slice.go | 56 - pkg/runtime/collections/slice_test.go | 123 - pkg/runtime/collections/sort.go | 161 - pkg/runtime/collections/sort_test.go | 354 -- pkg/runtime/collections/tap.go | 40 - pkg/runtime/collections/tap_test.go | 130 - pkg/runtime/collections/unique.go | 55 - pkg/runtime/collections/unique_test.go | 109 - pkg/runtime/collections/while.go | 73 - pkg/runtime/collections/while_pre_test.go | 64 - pkg/runtime/collections/while_test.go | 64 - pkg/runtime/core/cloneable.go | 3 + pkg/runtime/core/collections.go | 13 + pkg/runtime/core/comparable.go | 5 + pkg/runtime/core/errors.go | 61 +- pkg/runtime/core/expression.go | 21 - pkg/runtime/core/getter.go | 25 - pkg/runtime/core/helpers.go | 19 +- pkg/runtime/core/iterator.go | 16 + pkg/runtime/core/measurable.go | 5 + pkg/runtime/core/predicate.go | 8 - pkg/runtime/core/reflectable.go | 20 + pkg/runtime/core/scope.go | 154 - pkg/runtime/core/scope_test.go | 253 -- pkg/runtime/core/setter.go | 12 - pkg/runtime/core/type.go | 100 +- pkg/runtime/core/type_test.go | 111 - pkg/runtime/core/value.go | 34 +- pkg/runtime/events/iterator.go | 25 +- pkg/runtime/globals.go | 1 + pkg/runtime/opcodes.go | 16 +- pkg/runtime/operators/like.go | 14 +- pkg/runtime/operators/math.go | 321 +- pkg/runtime/operators/range.go | 37 +- pkg/runtime/program_test.go | 31 - pkg/runtime/values/array.go | 156 +- pkg/runtime/values/array_iter.go | 28 + pkg/runtime/values/array_test.go | 97 - pkg/runtime/values/assertions.go | 119 + pkg/runtime/values/binary.go | 27 +- pkg/runtime/values/boolean.go | 26 +- pkg/runtime/values/boolean_test.go | 7 - pkg/runtime/values/boxed.go | 44 + pkg/runtime/values/casting.go | 166 + pkg/runtime/values/comparator.go | 23 + pkg/runtime/values/date_time.go | 24 +- pkg/runtime/values/float.go | 35 +- pkg/runtime/values/helpers.go | 298 +- pkg/runtime/values/helpers_test.go | 126 +- pkg/runtime/values/int.go | 34 +- pkg/runtime/values/none.go | 6 +- pkg/runtime/values/object.go | 168 +- pkg/runtime/values/object_iter.go | 44 + pkg/runtime/values/object_test.go | 94 - pkg/runtime/values/range.go | 84 + pkg/runtime/values/range_iter.go | 27 + pkg/runtime/values/regexp.go | 20 +- pkg/runtime/values/string.go | 20 +- pkg/runtime/values/types/comparator.go | 50 + pkg/runtime/values/types/helpers.go | 55 - pkg/runtime/values/types/helpers_test.go | 196 - pkg/runtime/values/types/types.go | 32 +- pkg/runtime/values/types/types_test.go | 89 - pkg/runtime/vm.go | 138 +- pkg/runtime/vm_test.go | 9 - pkg/stdlib/arrays/append.go | 8 +- pkg/stdlib/arrays/first.go | 4 +- pkg/stdlib/arrays/flatten.go | 12 +- pkg/stdlib/arrays/intersection.go | 4 +- pkg/stdlib/arrays/last.go | 4 +- pkg/stdlib/arrays/minus.go | 4 +- pkg/stdlib/arrays/nth.go | 6 +- pkg/stdlib/arrays/pop.go | 4 +- pkg/stdlib/arrays/position.go | 8 +- pkg/stdlib/arrays/push.go | 17 +- pkg/stdlib/arrays/remove_nth.go | 6 +- pkg/stdlib/arrays/remove_value.go | 8 +- pkg/stdlib/arrays/remove_values.go | 6 +- pkg/stdlib/arrays/shift.go | 4 +- pkg/stdlib/arrays/slice.go | 14 +- pkg/stdlib/arrays/sorted.go | 4 +- pkg/stdlib/arrays/sorted_unique.go | 4 +- pkg/stdlib/arrays/union.go | 6 +- pkg/stdlib/arrays/union_distinct.go | 6 +- pkg/stdlib/arrays/unique.go | 4 +- pkg/stdlib/arrays/unshift.go | 20 +- pkg/stdlib/collections/include.go | 10 +- pkg/stdlib/collections/length.go | 10 +- pkg/stdlib/collections/reverse.go | 9 +- pkg/stdlib/datetime/add_subtract.go | 20 +- pkg/stdlib/datetime/compare.go | 24 +- pkg/stdlib/datetime/date.go | 7 +- pkg/stdlib/datetime/day.go | 8 +- pkg/stdlib/datetime/dayofweek.go | 8 +- pkg/stdlib/datetime/dayofyear.go | 8 +- pkg/stdlib/datetime/daysinmonth.go | 7 +- pkg/stdlib/datetime/diff.go | 24 +- pkg/stdlib/datetime/format.go | 11 +- pkg/stdlib/datetime/hour.go | 8 +- pkg/stdlib/datetime/leapyear.go | 8 +- pkg/stdlib/datetime/millisecond.go | 8 +- pkg/stdlib/datetime/minute.go | 8 +- pkg/stdlib/datetime/month.go | 8 +- pkg/stdlib/datetime/quarter.go | 7 +- pkg/stdlib/datetime/second.go | 8 +- pkg/stdlib/datetime/year.go | 8 +- pkg/stdlib/html/attr_remove.go | 12 +- pkg/stdlib/io/fs/write.go | 15 +- pkg/stdlib/io/net/http/get.go | 15 +- pkg/stdlib/io/net/http/request.go | 12 +- pkg/stdlib/lib.go | 7 +- pkg/stdlib/math/cos.go | 8 +- pkg/stdlib/math/lib.go | 12 +- pkg/stdlib/objects/keep_keys.go | 26 +- pkg/stdlib/objects/merge.go | 20 +- pkg/stdlib/objects/merge_recursive.go | 15 +- pkg/stdlib/path/join.go | 11 +- pkg/stdlib/strings/concat.go | 51 +- pkg/stdlib/strings/contains.go | 30 +- pkg/stdlib/strings/find.go | 25 +- pkg/stdlib/strings/regex.go | 7 +- pkg/stdlib/strings/split.go | 7 +- pkg/stdlib/strings/substitute.go | 7 +- pkg/stdlib/strings/substr.go | 17 +- pkg/stdlib/testing/array.go | 8 +- pkg/stdlib/testing/base/compare.go | 17 +- pkg/stdlib/testing/base/format.go | 2 +- pkg/stdlib/testing/binary.go | 8 +- pkg/stdlib/testing/datetime.go | 8 +- pkg/stdlib/testing/float.go | 8 +- pkg/stdlib/testing/include.go | 2 +- pkg/stdlib/testing/int.go | 8 +- pkg/stdlib/testing/len.go | 3 +- pkg/stdlib/testing/match.go | 2 +- pkg/stdlib/testing/object.go | 8 +- pkg/stdlib/testing/string.go | 8 +- pkg/stdlib/types/is_nan.go | 11 +- pkg/stdlib/types/type_name.go | 6 +- 189 files changed, 4608 insertions(+), 7406 deletions(-) create mode 100644 pkg/compiler/compiler_for_test.go create mode 100644 pkg/compiler/compiler_range_test.go delete mode 100644 pkg/drivers/common/setter.go delete mode 100644 pkg/runtime/collections/adapters.go delete mode 100644 pkg/runtime/collections/collection.go delete mode 100644 pkg/runtime/collections/filter.go delete mode 100644 pkg/runtime/collections/filter_test.go delete mode 100644 pkg/runtime/collections/helpers.go delete mode 100644 pkg/runtime/collections/indexed.go delete mode 100644 pkg/runtime/collections/indexed_test.go delete mode 100644 pkg/runtime/collections/iterator.go delete mode 100644 pkg/runtime/collections/keyed.go delete mode 100644 pkg/runtime/collections/keyed_test.go delete mode 100644 pkg/runtime/collections/limit.go delete mode 100644 pkg/runtime/collections/limit_test.go delete mode 100644 pkg/runtime/collections/map.go delete mode 100644 pkg/runtime/collections/map_test.go delete mode 100644 pkg/runtime/collections/slice.go delete mode 100644 pkg/runtime/collections/slice_test.go delete mode 100644 pkg/runtime/collections/sort.go delete mode 100644 pkg/runtime/collections/sort_test.go delete mode 100644 pkg/runtime/collections/tap.go delete mode 100644 pkg/runtime/collections/tap_test.go delete mode 100644 pkg/runtime/collections/unique.go delete mode 100644 pkg/runtime/collections/unique_test.go delete mode 100644 pkg/runtime/collections/while.go delete mode 100644 pkg/runtime/collections/while_pre_test.go delete mode 100644 pkg/runtime/collections/while_test.go create mode 100644 pkg/runtime/core/collections.go create mode 100644 pkg/runtime/core/comparable.go delete mode 100644 pkg/runtime/core/expression.go delete mode 100644 pkg/runtime/core/getter.go create mode 100644 pkg/runtime/core/iterator.go create mode 100644 pkg/runtime/core/measurable.go delete mode 100644 pkg/runtime/core/predicate.go create mode 100644 pkg/runtime/core/reflectable.go delete mode 100644 pkg/runtime/core/scope.go delete mode 100644 pkg/runtime/core/scope_test.go delete mode 100644 pkg/runtime/core/setter.go delete mode 100644 pkg/runtime/core/type_test.go create mode 100644 pkg/runtime/globals.go delete mode 100644 pkg/runtime/program_test.go create mode 100644 pkg/runtime/values/array_iter.go create mode 100644 pkg/runtime/values/assertions.go create mode 100644 pkg/runtime/values/boxed.go create mode 100644 pkg/runtime/values/casting.go create mode 100644 pkg/runtime/values/comparator.go create mode 100644 pkg/runtime/values/object_iter.go create mode 100644 pkg/runtime/values/range.go create mode 100644 pkg/runtime/values/range_iter.go create mode 100644 pkg/runtime/values/types/comparator.go delete mode 100644 pkg/runtime/values/types/helpers.go delete mode 100644 pkg/runtime/values/types/helpers_test.go delete mode 100644 pkg/runtime/values/types/types_test.go delete mode 100644 pkg/runtime/vm_test.go diff --git a/go.mod b/go.mod index 824cc528..eba1fedb 100644 --- a/go.mod +++ b/go.mod @@ -1,41 +1,41 @@ module github.com/MontFerret/ferret -go 1.18 +go 1.20 require ( github.com/PuerkitoBio/goquery v1.8.1 github.com/antchfx/htmlquery v1.3.0 github.com/antchfx/xpath v1.2.4 - github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230321174746-8dcc6526cfb1 + github.com/antlr4-go/antlr/v4 v4.13.0 github.com/corpix/uarand v0.2.0 github.com/gobwas/glob v0.2.3 github.com/gorilla/css v1.0.0 - github.com/jarcoal/httpmock v1.3.0 - github.com/mafredri/cdp v0.34.0 + github.com/jarcoal/httpmock v1.3.1 + github.com/mafredri/cdp v0.34.1 github.com/pkg/errors v0.9.1 - github.com/rs/zerolog v1.29.0 + github.com/rs/zerolog v1.31.0 github.com/sethgrid/pester v1.2.0 - github.com/smartystreets/goconvey v1.7.2 - github.com/stretchr/testify v1.8.2 + github.com/smartystreets/goconvey v1.8.1 + github.com/stretchr/testify v1.8.4 github.com/wI2L/jettison v0.7.4 - golang.org/x/net v0.8.0 - golang.org/x/sync v0.1.0 - golang.org/x/text v0.8.0 + golang.org/x/net v0.15.0 + golang.org/x/sync v0.3.0 + golang.org/x/text v0.13.0 ) require ( github.com/andybalholm/cascadia v1.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect + github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/smartystreets/assertions v1.2.0 // indirect + github.com/smarty/assertions v1.15.0 // indirect github.com/stretchr/objx v0.5.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/sys v0.6.0 // indirect + golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + golang.org/x/sys v0.12.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 13847c38..bcc4e0a2 100644 --- a/go.sum +++ b/go.sum @@ -7,10 +7,10 @@ github.com/antchfx/htmlquery v1.3.0/go.mod h1:zKPDVTMhfOmcwxheXUsx4rKJy8KEY/PU6e github.com/antchfx/xpath v1.2.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= github.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY= github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230321174746-8dcc6526cfb1 h1:X8MJ0fnN5FPdcGF5Ij2/OW+HgiJrRg3AfHAx1PJtIzM= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230321174746-8dcc6526cfb1/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/corpix/uarand v0.2.0 h1:U98xXwud/AVuCpkpgfPF7J5TQgr7R5tqT8VZP5KWbzE= github.com/corpix/uarand v0.2.0/go.mod h1:/3Z1QIqWkDIhf6XWn/08/uMHoQ8JUoTIKc2iPchBOmM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -36,15 +36,15 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= -github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -52,14 +52,15 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/mafredri/cdp v0.34.0 h1:kC8LFc1IJcjexESrt6U+MkqLtbwLV+WQ9hgcn1hntc4= -github.com/mafredri/cdp v0.34.0/go.mod h1:Dbsh7eY/zhQlsddEDWzZGOztv9Jf2gzKq47M7a2P3C4= +github.com/mafredri/cdp v0.34.1 h1:EeLNc+6pkDx2hrAm1arIjiofoH0fM5On1uAFzcuUn+o= +github.com/mafredri/cdp v0.34.1/go.mod h1:Dbsh7eY/zhQlsddEDWzZGOztv9Jf2gzKq47M7a2P3C4= github.com/mafredri/go-lint v0.0.0-20180911205320-920981dfc79e/go.mod h1:k/zdyxI3q6dup24o8xpYjJKTCf2F7rfxLp6w/efTiWs= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -69,17 +70,17 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= -github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc= github.com/segmentio/encoding v0.3.4 h1:WM4IBnxH8B9TakiM2QD5LyNl9JSndh88QbHqVC+Pauc= github.com/sethgrid/pester v1.2.0 h1:adC9RS29rRUef3rIKWPOuP1Jm3/MmB6ke+OhE5giENI= github.com/sethgrid/pester v1.2.0/go.mod h1:hEUINb4RqvDxtoCaU0BNT/HV4ig5kfgOasrf1xcvr0A= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= +github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= +github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= +github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= +github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= @@ -88,8 +89,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/wI2L/jettison v0.7.4 h1:ptjriu75R/k5RAZO0DJzy2t55f7g+dPiBxBY38icaKg= @@ -100,12 +101,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -114,14 +114,14 @@ golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -131,14 +131,14 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= @@ -150,11 +150,10 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index ed25d12d..4b636314 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -3,9 +3,8 @@ package compiler import ( "errors" - "github.com/MontFerret/ferret/pkg/runtime" - "github.com/MontFerret/ferret/pkg/parser" + "github.com/MontFerret/ferret/pkg/runtime" "github.com/MontFerret/ferret/pkg/stdlib" ) @@ -56,7 +55,7 @@ func (c *Compiler) Compile(query string) (program *runtime.Program, err error) { p := parser.New(query) p.AddErrorListener(newErrorListener()) - l := newVisitor(query, c.funcs) + l := newVisitor(query) p.Visit(l) diff --git a/pkg/compiler/compiler_for_test.go b/pkg/compiler/compiler_for_test.go new file mode 100644 index 00000000..b074a35f --- /dev/null +++ b/pkg/compiler/compiler_for_test.go @@ -0,0 +1,19 @@ +package compiler_test + +import ( + "testing" + + . "github.com/smartystreets/goconvey/convey" + + "github.com/MontFerret/ferret/pkg/compiler" +) + +func TestFor(t *testing.T) { + RunUseCases(t, compiler.New(), []UseCase{ + { + "FOR i IN 1..5 RETURN i", + []any{1, 2, 3, 4, 5}, + ShouldEqualJSON, + }, + }) +} diff --git a/pkg/compiler/compiler_for_while_test.go b/pkg/compiler/compiler_for_while_test.go index f17da5d0..1abb8d28 100644 --- a/pkg/compiler/compiler_for_while_test.go +++ b/pkg/compiler/compiler_for_while_test.go @@ -1,19 +1,40 @@ package compiler_test import ( + "context" "testing" + "github.com/MontFerret/ferret/pkg/runtime" + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values" + . "github.com/smartystreets/goconvey/convey" "github.com/MontFerret/ferret/pkg/compiler" ) func TestForWhile(t *testing.T) { + var counter int64 RunUseCases(t, compiler.New(), []UseCase{ + //{ + // "FOR i WHILE false RETURN i", + // []any{}, + // ShouldEqualJSON, + //}, { - "FOR i WHILE false RETURN i", - []any{}, + "FOR i WHILE UNTIL(5) RETURN i", + []any{0, 1, 2, 3, 4}, ShouldEqualJSON, }, - }) + }, runtime.WithFunctions(map[string]core.Function{ + "UNTIL": func(ctx context.Context, args ...core.Value) (core.Value, error) { + if counter < int64(values.ToInt(args[0])) { + counter++ + + return values.True, nil + } + + return values.False, nil + }, + })) } diff --git a/pkg/compiler/compiler_let_test.go b/pkg/compiler/compiler_let_test.go index 09148768..0ec485a4 100644 --- a/pkg/compiler/compiler_let_test.go +++ b/pkg/compiler/compiler_let_test.go @@ -90,6 +90,11 @@ func TestLet(t *testing.T) { []any{map[string]any{"a": map[string]any{"c": 1}, "b": []any{1}}}, ShouldEqualJSON, }, + { + "LET a = 'a' LET b = a LET c = 'c' RETURN b", + "a", + ShouldEqual, + }, }) // diff --git a/pkg/compiler/compiler_range_test.go b/pkg/compiler/compiler_range_test.go new file mode 100644 index 00000000..3d89da37 --- /dev/null +++ b/pkg/compiler/compiler_range_test.go @@ -0,0 +1,35 @@ +package compiler_test + +import ( + "github.com/MontFerret/ferret/pkg/compiler" + . "github.com/smartystreets/goconvey/convey" + "testing" +) + +func TestRange(t *testing.T) { + RunUseCases(t, compiler.New(), []UseCase{ + { + "RETURN 1..10", + []any{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + ShouldEqualJSON, + }, + { + ` +LET start = 1 +LET end = 10 +RETURN start..end +`, + []any{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + ShouldEqualJSON, + }, + // { + // ` + //LET start = @start + //LET end = @end + //RETURN start..end + //`, + // []any{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + // ShouldEqualJSON, + // }, + }) +} diff --git a/pkg/compiler/listener.go b/pkg/compiler/listener.go index f473ab8f..11163e99 100644 --- a/pkg/compiler/listener.go +++ b/pkg/compiler/listener.go @@ -1,7 +1,7 @@ package compiler import ( - "github.com/antlr/antlr4/runtime/Go/antlr/v4" + "github.com/antlr4-go/antlr/v4" "github.com/pkg/errors" ) @@ -9,16 +9,16 @@ type errorListener struct { *antlr.DiagnosticErrorListener } -func newErrorListener() *errorListener { +func newErrorListener() antlr.ErrorListener { return &errorListener{ antlr.NewDiagnosticErrorListener(false), } } -func (d *errorListener) ReportAttemptingFullContext(_ antlr.Parser, _ *antlr.DFA, _, _ int, _ *antlr.BitSet, _ antlr.ATNConfigSet) { +func (d *errorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs *antlr.ATNConfigSet) { } -func (d *errorListener) ReportContextSensitivity(_ antlr.Parser, _ *antlr.DFA, _, _, _ int, _ antlr.ATNConfigSet) { +func (d *errorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs *antlr.ATNConfigSet) { } func (d *errorListener) SyntaxError(_ antlr.Recognizer, _ interface{}, line, column int, msg string, _ antlr.RecognitionException) { diff --git a/pkg/compiler/test_test.go b/pkg/compiler/test_test.go index f7664f51..a6584645 100644 --- a/pkg/compiler/test_test.go +++ b/pkg/compiler/test_test.go @@ -60,9 +60,12 @@ func RunUseCases(t *testing.T, c *compiler.Compiler, useCases []UseCase, opts .. So(err, ShouldBeNil) - opts = append(opts, runtime.WithFunctions(c.Functions().Unwrap())) + options := []runtime.EnvironmentOption{ + runtime.WithFunctions(c.Functions().Unwrap()), + } + options = append(options, opts...) - out, err := Exec(prog, ArePtrsEqual(useCase.Assertion, ShouldEqualJSON), opts...) + out, err := Exec(prog, ArePtrsEqual(useCase.Assertion, ShouldEqualJSON), options...) if !ArePtrsEqual(useCase.Assertion, ShouldBeError) { So(err, ShouldBeNil) diff --git a/pkg/compiler/visitor.go b/pkg/compiler/visitor.go index 10ba1027..c3312f60 100644 --- a/pkg/compiler/visitor.go +++ b/pkg/compiler/visitor.go @@ -1,19 +1,15 @@ package compiler import ( - "fmt" - "math" "strconv" "strings" - "github.com/MontFerret/ferret/pkg/runtime" - - "github.com/antlr/antlr4/runtime/Go/antlr/v4" + "github.com/antlr4-go/antlr/v4" "github.com/MontFerret/ferret/pkg/parser/fql" + "github.com/MontFerret/ferret/pkg/runtime" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -24,9 +20,9 @@ type ( visitor struct { *fql.BaseFqlParserVisitor - err error - src string - funcs core.Functions + err error + src string + //funcs core.Functions constantsIndex map[uint64]int locations []core.Location bytecode []runtime.Opcode @@ -46,11 +42,11 @@ const ( forScope = "for" ) -func newVisitor(src string, funcs core.Functions) *visitor { +func newVisitor(src string) *visitor { v := new(visitor) v.BaseFqlParserVisitor = new(fql.BaseFqlParserVisitor) v.src = src - v.funcs = funcs + //v.funcs = funcs v.constantsIndex = make(map[uint64]int) v.locations = make([]core.Location, 0) v.bytecode = make([]runtime.Opcode, 0) @@ -111,20 +107,68 @@ func (v *visitor) VisitHead(_ *fql.HeadContext) interface{} { func (v *visitor) VisitForExpression(ctx *fql.ForExpressionContext) interface{} { v.beginScope() + v.emit(runtime.OpArray) - loopStart := len(v.bytecode) - var exitJump int + var loopStart, exitJump int // identify whether it's WHILE or FOR loop isForInLoop := ctx.While() == nil - v.emit(runtime.OpLoopInit) - if isForInLoop { + loopStart = len(v.bytecode) + // Loop data source to iterate over if c := ctx.ForExpressionSource(); c != nil { c.Accept(v) } + + v.emit(runtime.OpLoopInit) + v.emit(runtime.OpLoopHasNext) + exitJump = v.emitJump(runtime.OpJumpIfFalse) + v.emitPop() + + valVar := ctx.GetValueVariable().GetText() + counterVarCtx := ctx.GetCounterVariable() + + hasValVar := valVar != ignorePseudoVariable + var hasCounterVar bool + var counterVar string + + if counterVarCtx != nil { + counterVar = counterVarCtx.GetText() + hasCounterVar = true + } + + if hasValVar && hasCounterVar { + v.emit(runtime.OpLoopNext) + } else if hasValVar { + v.emit(runtime.OpLoopNextValue) + } else if hasCounterVar { + v.emit(runtime.OpLoopNextCounter) + } else { + panic(core.Error(ErrUnexpectedToken, ctx.GetText())) + } + + // declare value variable + valVarIndex := v.declareVariable(valVar) + + var counterVarIndex int + + if hasCounterVar { + // declare counter variable + counterVarIndex = v.declareVariable(counterVar) + } + + v.defineVariable(valVarIndex) + + if hasCounterVar { + v.defineVariable(counterVarIndex) + } } else { + // Create initial value for the loop counter + v.emitConstant(runtime.OpPush, values.NewInt(0)) + + loopStart = len(v.bytecode) + // Condition expression ctx.Expression().Accept(v) @@ -137,7 +181,7 @@ func (v *visitor) VisitForExpression(ctx *fql.ForExpressionContext) interface{} // declare counter variable // and increment it by 1 index := v.declareVariable(counterVar) - v.emitConstant(runtime.OpIncr, values.NewInt(0)) + v.emit(runtime.OpIncr) v.defineVariable(index) } @@ -173,7 +217,8 @@ func (v *visitor) VisitForExpression(ctx *fql.ForExpressionContext) interface{} v.emitLoop(loopStart) v.patchJump(exitJump) - // v.emitPop() + // pop loop counter + v.emitPop() v.endScope() return nil @@ -202,11 +247,11 @@ func (v *visitor) VisitFunctionCallExpression(ctx *fql.FunctionCallExpressionCon name += call.FunctionName().GetText() - exists := v.funcs.Has(name) - - if !exists { - panic(core.Error(core.ErrNotFound, fmt.Sprintf("function: '%s'", name))) - } + //exists := v.funcs.Has(name) + // + //if !exists { + // panic(core.Error(core.ErrNotFound, fmt.Sprintf("function: '%s'", name))) + //} //regularCall := ctx.ErrorOperator() == nil @@ -264,15 +309,38 @@ func (v *visitor) VisitMemberExpression(ctx *fql.MemberExpressionContext) interf } if p.ErrorOperator() != nil { - v.emit(runtime.OpGetPropertyOptional) + v.emit(runtime.OpLoadPropertyOptional) } else { - v.emit(runtime.OpGetProperty) + v.emit(runtime.OpLoadProperty) } } return nil } +func (v *visitor) VisitRangeOperator(ctx *fql.RangeOperatorContext) interface{} { + ctx.GetLeft().Accept(v) + ctx.GetRight().Accept(v) + + v.emit(runtime.OpRange) + + return nil +} + +func (v *visitor) VisitRangeOperand(ctx *fql.RangeOperandContext) interface{} { + if c := ctx.IntegerLiteral(); c != nil { + c.Accept(v) + } else if c := ctx.Variable(); c != nil { + c.Accept(v) + } else if c := ctx.Param(); c != nil { + c.Accept(v) + } else { + panic(core.Error(ErrUnexpectedToken, ctx.GetText())) + } + + return nil +} + func (v *visitor) VisitVariableDeclaration(ctx *fql.VariableDeclarationContext) interface{} { name := ignorePseudoVariable @@ -677,7 +745,7 @@ func (v *visitor) readVariable(name string) { arg := v.resolveLocalVariable(name) if arg > -1 { - v.emit(runtime.OpGetLocal, arg) + v.emit(runtime.OpLoadLocal, arg) return } @@ -688,7 +756,7 @@ func (v *visitor) readVariable(name string) { panic(core.Error(ErrVariableNotFound, name)) } - v.emit(runtime.OpGetGlobal, index) + v.emit(runtime.OpLoadGlobal, index) } func (v *visitor) declareVariable(name string) int { @@ -731,12 +799,12 @@ func (v *visitor) declareVariable(name string) int { // defineVariable defines a variable in the current scope. func (v *visitor) defineVariable(index int) { if v.scope == 0 { - v.emit(runtime.OpSetGlobal, index) + v.emit(runtime.OpStoreGlobal, index) return } - v.emit(runtime.OpSetLocal, index) + v.emit(runtime.OpStoreLocal, index) } // emitConstant emits an opcode with a constant argument. @@ -746,15 +814,9 @@ func (v *visitor) emitConstant(op runtime.Opcode, constant core.Value) { // emitLoop emits a loop instruction. func (v *visitor) emitLoop(loopStart int) { - v.emit(runtime.OpLoop, loopStart) - - jump := len(v.bytecode) - loopStart + 2 - - if jump > math.MaxUint16 { - // panic(core.Error(ErrTooManyLoopIterations)) - } - - v.arguments[loopStart] = jump + pos := v.emitJump(runtime.OpLoop) + jump := pos - loopStart + 2 + v.arguments[pos-1] = jump } // emitJump emits an opcode with a jump offset argument. @@ -792,7 +854,7 @@ func (v *visitor) emit(op runtime.Opcode, args ...int) { func (v *visitor) addConstant(constant core.Value) int { var hash uint64 - if types.IsScalar(constant.Type()) { + if values.IsScalar(constant) { hash = constant.Hash() } diff --git a/pkg/drivers/cdp/dom/document.go b/pkg/drivers/cdp/dom/document.go index 68eeb692..3d9d820a 100644 --- a/pkg/drivers/cdp/dom/document.go +++ b/pkg/drivers/cdp/dom/document.go @@ -100,7 +100,7 @@ func (doc *HTMLDocument) Compare(other core.Value) int64 { case FrameIDType: return values.NewString(string(doc.frameTree.Frame.ID)).Compare(values.NewString(other.String())) default: - return drivers.Compare(doc.Type(), other.Type()) + return drivers.CompareTypes(doc.Type(), other.Type()) } } diff --git a/pkg/drivers/cdp/dom/element.go b/pkg/drivers/cdp/dom/element.go index 33b70be3..457129c9 100644 --- a/pkg/drivers/cdp/dom/element.go +++ b/pkg/drivers/cdp/dom/element.go @@ -94,14 +94,13 @@ func (el *HTMLElement) String() string { } func (el *HTMLElement) Compare(other core.Value) int64 { - switch other.Type() { - case drivers.HTMLElementType: - other := other.(drivers.HTMLElement) + other, ok := other.(drivers.HTMLElement) - return int64(strings.Compare(el.String(), other.String())) - default: - return drivers.Compare(el.Type(), other.Type()) + if !ok { + return drivers.CompareTypes(el.Type(), core.Reflect(other)) } + + return int64(strings.Compare(el.String(), other.String())) } func (el *HTMLElement) Unwrap() interface{} { @@ -126,8 +125,8 @@ func (el *HTMLElement) Iterate(_ context.Context) (core.Iterator, error) { return common.NewIterator(el) } -func (el *HTMLElement) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { - return common.GetInElement(ctx, path, el) +func (el *HTMLElement) GetByKey(ctx context.Context, key string) (core.Value, error) { + return common.GetInElement(ctx, key, el) } func (el *HTMLElement) SetIn(ctx context.Context, path []core.Value, value core.Value) core.PathError { diff --git a/pkg/drivers/cdp/page.go b/pkg/drivers/cdp/page.go index 3a008ebc..cae1c0c0 100644 --- a/pkg/drivers/cdp/page.go +++ b/pkg/drivers/cdp/page.go @@ -208,7 +208,7 @@ func (p *HTMLPage) String() string { } func (p *HTMLPage) Compare(other core.Value) int64 { - tc := drivers.Compare(p.Type(), other.Type()) + tc := drivers.CompareTypes(p.Type(), other.Type()) if tc != 0 { return tc @@ -245,7 +245,7 @@ func (p *HTMLPage) Copy() core.Value { return values.None } -func (p *HTMLPage) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { +func (p *HTMLPage) GetByKey(ctx context.Context, key string) (core.Value, error) { return common.GetInPage(ctx, path, p) } diff --git a/pkg/drivers/common/frames.go b/pkg/drivers/common/frames.go index ec8c9311..ab0f45b2 100644 --- a/pkg/drivers/common/frames.go +++ b/pkg/drivers/common/frames.go @@ -21,7 +21,7 @@ func CollectFrames(ctx context.Context, receiver *values.Array, doc drivers.HTML childDoc, ok := value.(drivers.HTMLDocument) if !ok { - err = core.TypeError(value.Type(), drivers.HTMLDocumentType) + err = core.TypeError(value, drivers.HTMLDocumentType) return false } diff --git a/pkg/drivers/common/getter.go b/pkg/drivers/common/getter.go index 74d6e7d0..216f9d50 100644 --- a/pkg/drivers/common/getter.go +++ b/pkg/drivers/common/getter.go @@ -11,120 +11,96 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/values/types" ) -func GetInPage(ctx context.Context, path []core.Value, page drivers.HTMLPage) (core.Value, core.PathError) { - if len(path) == 0 { +func GetInPage(ctx context.Context, key string, page drivers.HTMLPage) (core.Value, error) { + if len(key) == 0 { return page, nil } - segmentIdx := 0 - segment := path[segmentIdx] + switch key { + case "response": + resp, err := page.GetResponse(ctx) - if segment.Type() == types.String { - segment := segment.(values.String) + if err != nil { + return values.None, err + } - switch segment { - case "response": - resp, err := page.GetResponse(ctx) + return resp, nil + case "mainFrame", "document": + return page.GetMainFrame(), nil + case "frames": + if len(path) == 1 { + out, err := page.GetFrames(ctx) if err != nil { return nil, core.NewPathError( errors.Wrap(err, "get response"), - 0, + segmentIdx, ) } - out, pathErr := resp.GetIn(ctx, path[segmentIdx+1:]) - - if pathErr != nil { - return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) - } - return out, nil - case "mainFrame", "document": - out, pathErr := GetInDocument(ctx, path[segmentIdx+1:], page.GetMainFrame()) - - if pathErr != nil { - return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) - } - - return out, nil - case "frames": - if len(path) == 1 { - out, err := page.GetFrames(ctx) - - if err != nil { - return nil, core.NewPathError( - errors.Wrap(err, "get response"), - segmentIdx, - ) - } - - return out, nil - } + } - segmentIdx = +1 - idx := path[segmentIdx] + segmentIdx = +1 + idx := path[segmentIdx] - if !values.IsNumber(idx) { - return values.None, core.NewPathError( - core.TypeError(idx.Type(), types.Int, types.Float), - segmentIdx, - ) - } - - value, err := page.GetFrame(ctx, values.ToInt(idx)) + if !values.IsNumber(idx) { + return values.None, core.NewPathError( + core.TypeError(idx.Type(), types.Int, types.Float), + segmentIdx, + ) + } - if err != nil { - return values.None, core.NewPathError(err, segmentIdx) - } + value, err := page.GetFrame(ctx, values.ToInt(idx)) - if len(path) == 2 { - return value, nil - } + if err != nil { + return values.None, core.NewPathError(err, segmentIdx) + } - frame, err := drivers.ToDocument(value) + if len(path) == 2 { + return value, nil + } - if err != nil { - return values.None, core.NewPathError(err, segmentIdx) - } + frame, err := drivers.ToDocument(value) - out, pathErr := GetInDocument(ctx, path[segmentIdx+1:], frame) + if err != nil { + return values.None, core.NewPathError(err, segmentIdx) + } - if err != nil { - return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) - } + out, pathErr := GetInDocument(ctx, path[segmentIdx+1:], frame) - return out, nil - case "url", "URL": - return page.GetURL(), nil - case "cookies": - cookies, err := page.GetCookies(ctx) + if err != nil { + return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) + } - if err != nil { - return values.None, core.NewPathError(err, segmentIdx) - } + return out, nil + case "url", "URL": + return page.GetURL(), nil + case "cookies": + cookies, err := page.GetCookies(ctx) - if len(path) == 1 { - return cookies, nil - } + if err != nil { + return values.None, core.NewPathError(err, segmentIdx) + } - out, pathErr := cookies.GetIn(ctx, path[segmentIdx+1:]) + if len(path) == 1 { + return cookies, nil + } - if err != nil { - return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) - } + out, pathErr := cookies.GetIn(ctx, path[segmentIdx+1:]) - return out, nil - case "title": - return page.GetMainFrame().GetTitle(), nil - case "isClosed": - return page.IsClosed(), nil - default: - return GetInDocument(ctx, path, page.GetMainFrame()) + if err != nil { + return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) } - } - return GetInDocument(ctx, path, page.GetMainFrame()) + return out, nil + case "title": + return page.GetMainFrame().GetTitle(), nil + case "isClosed": + return page.IsClosed(), nil + default: + return GetInDocument(ctx, path, page.GetMainFrame()) + } } func GetInDocument(ctx context.Context, path []core.Value, doc drivers.HTMLDocument) (core.Value, core.PathError) { diff --git a/pkg/drivers/common/iterator.go b/pkg/drivers/common/iterator.go index ae190324..1dabcdf4 100644 --- a/pkg/drivers/common/iterator.go +++ b/pkg/drivers/common/iterator.go @@ -23,19 +23,19 @@ func NewIterator( return &Iterator{node, 0}, nil } -func (iterator *Iterator) Next(ctx context.Context) (value core.Value, key core.Value, err error) { - if iterator.node.Length() > iterator.pos { - idx := iterator.pos - val, err := iterator.node.GetChildNode(ctx, idx) - - if err != nil { - return values.None, values.None, err - } +func (iterator *Iterator) HasNext(_ context.Context) (bool, error) { + return iterator.node.Length() > int(iterator.pos), nil +} - iterator.pos++ +func (iterator *Iterator) Next(ctx context.Context) (value core.Value, key core.Value, err error) { + idx := iterator.pos + val, err := iterator.node.GetChildNode(ctx, idx) - return val, idx, nil + if err != nil { + return values.None, values.None, err } - return values.None, values.None, core.ErrNoMoreData + iterator.pos++ + + return val, idx, nil } diff --git a/pkg/drivers/common/setter.go b/pkg/drivers/common/setter.go deleted file mode 100644 index 40e6749d..00000000 --- a/pkg/drivers/common/setter.go +++ /dev/null @@ -1,146 +0,0 @@ -package common - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/drivers" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" -) - -func SetInPage(ctx context.Context, path []core.Value, page drivers.HTMLPage, value core.Value) core.PathError { - if len(path) == 0 { - return nil - } - - return SetInDocument(ctx, path, page.GetMainFrame(), value) -} - -func SetInDocument(ctx context.Context, path []core.Value, doc drivers.HTMLDocument, value core.Value) core.PathError { - if len(path) == 0 { - return nil - } - - return SetInNode(ctx, path, doc, value) -} - -func SetInElement(ctx context.Context, path []core.Value, el drivers.HTMLElement, value core.Value) core.PathError { - if len(path) == 0 { - return nil - } - - segmentIdx := 0 - segment := path[segmentIdx] - - if segment.Type() == types.String { - segment := segment.(values.String) - - switch segment { - case "attributes": - if len(path) > 1 { - attrName := path[1] - err := el.SetAttribute(ctx, values.NewString(attrName.String()), values.NewString(value.String())) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - return nil - } - - err := core.ValidateType(value, types.Object) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - curr, err := el.GetAttributes(ctx) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - // remove all previous attributes - err = el.RemoveAttribute(ctx, curr.Keys()...) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - obj := value.(*values.Object) - obj.ForEach(func(value core.Value, key string) bool { - err = el.SetAttribute(ctx, values.NewString(key), values.NewString(value.String())) - - return err == nil - }) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - return nil - case "style": - if len(path) > 1 { - attrName := path[1] - - err := el.SetStyle(ctx, values.NewString(attrName.String()), values.NewString(value.String())) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - return nil - } - - err := core.ValidateType(value, types.Object) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - styles, err := el.GetStyles(ctx) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - err = el.RemoveStyle(ctx, styles.Keys()...) - - obj := value.(*values.Object) - obj.ForEach(func(value core.Value, key string) bool { - err = el.SetStyle(ctx, values.NewString(key), values.NewString(value.String())) - - return err == nil - }) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - return nil - case "value": - if len(path) > 1 { - return core.NewPathError(ErrInvalidPath, segmentIdx+1) - } - - err := el.SetValue(ctx, value) - - if err != nil { - return core.NewPathError(err, segmentIdx) - } - - return nil - } - } - - return SetInNode(ctx, path, el, value) -} - -func SetInNode(_ context.Context, path []core.Value, _ drivers.HTMLNode, _ core.Value) core.PathError { - if len(path) == 0 { - return nil - } - - return core.NewPathError(ErrReadOnly, 0) -} diff --git a/pkg/drivers/cookie.go b/pkg/drivers/cookie.go index 21989e03..269640a8 100644 --- a/pkg/drivers/cookie.go +++ b/pkg/drivers/cookie.go @@ -58,11 +58,11 @@ func (c HTTPCookie) String() string { } func (c HTTPCookie) Compare(other core.Value) int64 { - if other.Type() != HTTPCookieType { - return Compare(HTTPCookieType, other.Type()) - } + oc, ok := other.(HTTPCookie) - oc := other.(HTTPCookie) + if !ok { + return CompareTypes(HTTPCookieType, core.Reflect(other)) + } if c.Name != oc.Name { return int64(strings.Compare(c.Name, oc.Name)) @@ -162,14 +162,12 @@ func (c HTTPCookie) MarshalJSON() ([]byte, error) { return out, err } -func (c HTTPCookie) GetIn(_ context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { +func (c HTTPCookie) GetByKey(_ context.Context, key string) (core.Value, error) { + if key == "" { return values.None, nil } - segment := path[0] - - switch values.ToString(segment) { + switch key { case "name": return values.NewString(c.Name), nil case "value": diff --git a/pkg/drivers/cookies.go b/pkg/drivers/cookies.go index a8954cba..3d407c11 100644 --- a/pkg/drivers/cookies.go +++ b/pkg/drivers/cookies.go @@ -8,8 +8,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" - "github.com/wI2L/jettison" ) @@ -29,10 +27,6 @@ func (c *HTTPCookies) MarshalJSON() ([]byte, error) { return jettison.MarshalOpts(c.values, jettison.NoHTMLEscaping()) } -func (c *HTTPCookies) Type() core.Type { - return HTTPCookiesType -} - func (c *HTTPCookies) String() string { j, err := c.MarshalJSON() @@ -44,11 +38,12 @@ func (c *HTTPCookies) String() string { } func (c *HTTPCookies) Compare(other core.Value) int64 { - if other.Type() != HTTPCookiesType { - return Compare(HTTPCookiesType, other.Type()) - } + oc, ok := other.(*HTTPCookies) - oc := other.(*HTTPCookies) + if !ok { + // TODO: Implement + return 1 + } switch { case len(c.values) > len(oc.values): @@ -87,7 +82,7 @@ func (c *HTTPCookies) Unwrap() interface{} { func (c *HTTPCookies) Hash() uint64 { hash := fnv.New64a() - hash.Write([]byte(c.Type().String())) + hash.Write([]byte("HTMLCookies")) hash.Write([]byte(":")) hash.Write([]byte("{")) @@ -175,30 +170,8 @@ func (c *HTTPCookies) Set(cookie HTTPCookie) { c.values[cookie.Name] = cookie } -func (c *HTTPCookies) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { - return values.None, nil - } - - segmentIdx := 0 - segment := path[segmentIdx] - - err := core.ValidateType(segment, types.String) - - if err != nil { - return values.None, core.NewPathError(err, segmentIdx) - } - - cookie, found := c.values[segment.String()] - - if found { - if len(path) == 1 { - return cookie, nil - } - - return values.GetIn(ctx, cookie, path[segmentIdx+1:]) - } - +func (c *HTTPCookies) GetByKey(ctx context.Context, key string) (core.Value, error) { + // TODO: Implement return values.None, nil } diff --git a/pkg/drivers/headers.go b/pkg/drivers/headers.go index f3b13c7c..d1e381c6 100644 --- a/pkg/drivers/headers.go +++ b/pkg/drivers/headers.go @@ -47,11 +47,11 @@ func (h *HTTPHeaders) String() string { } func (h *HTTPHeaders) Compare(other core.Value) int64 { - if other.Type() != HTTPHeaderType { - return Compare(HTTPHeaderType, other.Type()) - } + oh, ok := other.(*HTTPHeaders) - oh := other.(*HTTPHeaders) + if !ok { + return CompareTypes(h.Type(), core.Reflect(other)) + } if len(h.values) > len(oh.values) { return 1 @@ -158,15 +158,12 @@ func (h *HTTPHeaders) Get(key string) string { return textproto.MIMEHeader(h.values).Get(key) } -func (h *HTTPHeaders) GetIn(_ context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { +func (h *HTTPHeaders) GetByKey(_ context.Context, key string) (core.Value, error) { + if key == "" { return values.None, nil } - segmentIx := 0 - segment := path[segmentIx] - - return values.NewString(h.Get(string(values.ToString(segment)))), nil + return values.NewString(h.Get(key)), nil } func (h *HTTPHeaders) ForEach(predicate func(value []string, key string) bool) { diff --git a/pkg/drivers/helpers.go b/pkg/drivers/helpers.go index c5d914e9..c291567c 100644 --- a/pkg/drivers/helpers.go +++ b/pkg/drivers/helpers.go @@ -7,13 +7,13 @@ import ( ) func ToPage(value core.Value) (HTMLPage, error) { - err := core.ValidateType(value, HTMLPageType) + page, ok := value.(HTMLPage) - if err != nil { - return nil, err + if !ok { + return nil, core.TypeError(value, HTMLPageType) } - return value.(HTMLPage), nil + return page, nil } func ToDocument(value core.Value) (HTMLDocument, error) { @@ -24,7 +24,7 @@ func ToDocument(value core.Value) (HTMLDocument, error) { return v, nil default: return nil, core.TypeError( - value.Type(), + value, HTMLPageType, HTMLDocumentType, ) @@ -41,7 +41,7 @@ func ToElement(value core.Value) (HTMLElement, error) { return v, nil default: return nil, core.TypeError( - value.Type(), + value, HTMLPageType, HTMLDocumentType, HTMLElementType, @@ -56,7 +56,7 @@ func ToQuerySelector(value core.Value) (QuerySelector, error) { case values.String: return NewCSSSelector(v), nil default: - return QuerySelector{}, core.TypeError(value.Type(), types.String, QuerySelectorType) + return QuerySelector{}, core.TypeError(value, types.String, QuerySelectorType) } } diff --git a/pkg/drivers/http/document.go b/pkg/drivers/http/document.go index c176823d..12a67029 100644 --- a/pkg/drivers/http/document.go +++ b/pkg/drivers/http/document.go @@ -88,7 +88,7 @@ func (doc *HTMLDocument) Compare(other core.Value) int64 { return doc.url.Compare(otherDoc.GetURL()) default: - return drivers.Compare(doc.Type(), other.Type()) + return drivers.CompareTypes(doc.Type(), other.Type()) } } diff --git a/pkg/drivers/http/element.go b/pkg/drivers/http/element.go index a20a706d..16e8b619 100644 --- a/pkg/drivers/http/element.go +++ b/pkg/drivers/http/element.go @@ -56,7 +56,7 @@ func (el *HTMLElement) Compare(other core.Value) int64 { return int64(strings.Compare(el.String(), other.String())) default: - return drivers.Compare(el.Type(), other.Type()) + return drivers.CompareTypes(el.Type(), other.Type()) } } diff --git a/pkg/drivers/http/page.go b/pkg/drivers/http/page.go index ea554da5..f9befb31 100644 --- a/pkg/drivers/http/page.go +++ b/pkg/drivers/http/page.go @@ -55,7 +55,7 @@ func (p *HTMLPage) String() string { } func (p *HTMLPage) Compare(other core.Value) int64 { - tc := drivers.Compare(p.Type(), other.Type()) + tc := drivers.CompareTypes(p.Type(), other.Type()) if tc != 0 { return tc diff --git a/pkg/drivers/request.go b/pkg/drivers/request.go index 679b4ca7..2fd2fdbb 100644 --- a/pkg/drivers/request.go +++ b/pkg/drivers/request.go @@ -2,12 +2,10 @@ package drivers import ( "context" - "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // HTTPRequest HTTP request object. @@ -45,13 +43,11 @@ func (req *HTTPRequest) String() string { } func (req *HTTPRequest) Compare(other core.Value) int64 { - if other.Type() != HTTPRequestType { - return Compare(HTTPResponseType, other.Type()) - } + otherReq, ok := other.(*HTTPRequest) - // this is a safe cast. Only *HTTPRequest implements core.Value. - // HTTPRequest does not. - otherReq := other.(*HTTPRequest) + if !ok { + return CompareTypes(HTTPRequestType, core.Reflect(other)) + } comp := req.Headers.Compare(otherReq.Headers) @@ -82,37 +78,18 @@ func (req *HTTPRequest) Copy() core.Value { return &cop } -func (req *HTTPRequest) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { +func (req *HTTPRequest) GetByKey(ctx context.Context, key string) (core.Value, error) { + if len(key) == 0 { return req, nil } - segmentIdx := 0 - segment := path[segmentIdx] - - if typ := segment.Type(); typ != types.String { - return values.None, core.NewPathError(core.TypeError(typ, types.String), segmentIdx) - } - - field := segment.String() - - switch field { + switch key { case "url", "URL": return values.NewString(req.URL), nil case "method": return values.NewString(req.Method), nil case "headers": - if len(path) == 1 { - return req.Headers, nil - } - - out, pathErr := req.Headers.GetIn(ctx, path[1:]) - - if pathErr != nil { - return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) - } - - return out, nil + return req.Headers, nil case "body": return values.NewBinary(req.Body), nil } diff --git a/pkg/drivers/response.go b/pkg/drivers/response.go index 79171e4f..502b66b3 100644 --- a/pkg/drivers/response.go +++ b/pkg/drivers/response.go @@ -2,12 +2,10 @@ package drivers import ( "context" - "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // HTTPResponse HTTP response object. @@ -42,15 +40,14 @@ func (resp *HTTPResponse) String() string { } func (resp *HTTPResponse) Compare(other core.Value) int64 { - if other.Type() != HTTPResponseType { - return Compare(HTTPResponseType, other.Type()) - } + otherResp, ok := other.(*HTTPResponse) - // this is a safe cast. Only *HTTPResponse implements core.Value. - // HTTPResponse does not. - otherResp := other.(*HTTPResponse) + if !ok { + return CompareTypes(HTTPResponseType, core.Reflect(other)) + } comp := resp.Headers.Compare(otherResp.Headers) + if comp != 0 { return comp } @@ -82,21 +79,12 @@ func (resp *HTTPResponse) MarshalJSON() ([]byte, error) { return jettison.MarshalOpts(responseMarshal(*resp), jettison.NoHTMLEscaping()) } -func (resp *HTTPResponse) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { +func (resp *HTTPResponse) GetByKey(_ context.Context, key string) (core.Value, error) { + if len(key) == 0 { return resp, nil } - segmentIdx := 0 - segment := path[segmentIdx] - - if typ := segment.Type(); typ != types.String { - return values.None, core.NewPathError(core.TypeError(typ, types.String), segmentIdx) - } - - field := segment.String() - - switch field { + switch key { case "url", "URL": return values.NewString(resp.URL), nil case "status": @@ -104,17 +92,7 @@ func (resp *HTTPResponse) GetIn(ctx context.Context, path []core.Value) (core.Va case "statusCode": return values.NewInt(resp.StatusCode), nil case "headers": - if len(path) == 1 { - return resp.Headers, nil - } - - out, pathErr := resp.Headers.GetIn(ctx, path[1:]) - - if pathErr != nil { - return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) - } - - return out, nil + return resp.Headers, nil case "body": return values.NewBinary(resp.Body), nil case "responseTime": diff --git a/pkg/drivers/selector.go b/pkg/drivers/selector.go index 5bc6ab1b..25200864 100644 --- a/pkg/drivers/selector.go +++ b/pkg/drivers/selector.go @@ -77,14 +77,14 @@ func (q QuerySelector) String() string { } func (q QuerySelector) Compare(other core.Value) int64 { - if other.Type() != QuerySelectorType { - return Compare(QuerySelectorType, other.Type()) - } + otherSelector, ok := other.(*QuerySelector) - otherQS := other.(*QuerySelector) + if !ok { + return CompareTypes(QuerySelectorType, core.Reflect(other)) + } - if q.kind == otherQS.Kind() { - return q.value.Compare(values.NewString(otherQS.String())) + if q.kind == otherSelector.Kind() { + return q.value.Compare(values.NewString(otherSelector.String())) } if q.kind == CSSSelector { diff --git a/pkg/drivers/type.go b/pkg/drivers/type.go index 9b39351c..5d672f1c 100644 --- a/pkg/drivers/type.go +++ b/pkg/drivers/type.go @@ -2,16 +2,20 @@ package drivers import "github.com/MontFerret/ferret/pkg/runtime/core" +func createType(name string) core.Type { + return core.NewType("ferret.drivers", name) +} + var ( - HTTPRequestType = core.NewType("ferret.drivers.HTTPRequest") - HTTPResponseType = core.NewType("ferret.drivers.HTTPResponse") - HTTPHeaderType = core.NewType("ferret.drivers.HTTPHeaders") - HTTPCookieType = core.NewType("ferret.drivers.HTTPCookie") - HTTPCookiesType = core.NewType("ferret.drivers.HTTPCookies") - HTMLElementType = core.NewType("ferret.drivers.HTMLElement") - HTMLDocumentType = core.NewType("ferret.drivers.HTMLDocument") - HTMLPageType = core.NewType("ferret.drivers.HTMLPageType") - QuerySelectorType = core.NewType("ferret.drivers.QuerySelector") + HTTPRequestType = createType("HTTPRequest") + HTTPResponseType = createType("HTTPResponse") + HTTPHeaderType = createType("HTTPHeaders") + HTTPCookieType = createType("HTTPCookie") + HTTPCookiesType = createType("HTTPCookies") + HTMLElementType = createType("HTMLElement") + HTMLDocumentType = createType("HTMLDocument") + HTMLPageType = createType("HTMLPageType") + QuerySelectorType = createType("QuerySelector") ) // Comparison table of builtin types @@ -27,7 +31,7 @@ var typeComparisonTable = map[core.Type]uint64{ HTMLPageType: 8, } -func Compare(first, second core.Type) int64 { +func CompareTypes(first, second core.Type) int64 { f, ok := typeComparisonTable[first] if !ok { diff --git a/pkg/drivers/value.go b/pkg/drivers/value.go index 6cc0a4d1..1309e215 100644 --- a/pkg/drivers/value.go +++ b/pkg/drivers/value.go @@ -4,10 +4,8 @@ import ( "context" "io" - "github.com/MontFerret/ferret/pkg/runtime/events" - - "github.com/MontFerret/ferret/pkg/runtime/collections" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/events" "github.com/MontFerret/ferret/pkg/runtime/values" ) @@ -21,9 +19,8 @@ type ( HTMLNode interface { core.Value core.Iterable - core.Getter - core.Setter - collections.Measurable + core.Keyed + core.Measurable io.Closer GetNodeType(ctx context.Context) (values.Int, error) @@ -189,9 +186,8 @@ type ( HTMLPage interface { core.Value core.Iterable - core.Getter - core.Setter - collections.Measurable + core.Keyed + core.Measurable events.Observable io.Closer diff --git a/pkg/parser/case_changing_stream.go b/pkg/parser/case_changing_stream.go index c4044dfe..f057de2b 100644 --- a/pkg/parser/case_changing_stream.go +++ b/pkg/parser/case_changing_stream.go @@ -3,7 +3,7 @@ package parser import ( "unicode" - "github.com/antlr/antlr4/runtime/Go/antlr/v4" + "github.com/antlr4-go/antlr/v4" ) // CaseChangingStream wraps an existing CharStream, but upper cases, or diff --git a/pkg/parser/fql/fql_lexer.go b/pkg/parser/fql/fql_lexer.go index cc3c8731..b44cc6d1 100644 --- a/pkg/parser/fql/fql_lexer.go +++ b/pkg/parser/fql/fql_lexer.go @@ -1,4 +1,4 @@ -// Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT. +// Code generated from antlr/FqlLexer.g4 by ANTLR 4.13.1. DO NOT EDIT. package fql @@ -7,7 +7,7 @@ import ( "sync" "unicode" - "github.com/antlr/antlr4/runtime/Go/antlr/v4" + "github.com/antlr4-go/antlr/v4" ) // Suppress unused import error @@ -22,28 +22,28 @@ type FqlLexer struct { // TODO: EOF string } -var fqllexerLexerStaticData struct { +var FqlLexerLexerStaticData struct { once sync.Once serializedATN []int32 - channelNames []string - modeNames []string - literalNames []string - symbolicNames []string - ruleNames []string - predictionContextCache *antlr.PredictionContextCache + ChannelNames []string + ModeNames []string + LiteralNames []string + SymbolicNames []string + RuleNames []string + PredictionContextCache *antlr.PredictionContextCache atn *antlr.ATN decisionToDFA []*antlr.DFA } func fqllexerLexerInit() { - staticData := &fqllexerLexerStaticData - staticData.channelNames = []string{ + staticData := &FqlLexerLexerStaticData + staticData.ChannelNames = []string{ "DEFAULT_TOKEN_CHANNEL", "HIDDEN", } - staticData.modeNames = []string{ + staticData.ModeNames = []string{ "DEFAULT_MODE", } - staticData.literalNames = []string{ + staticData.LiteralNames = []string{ "", "", "", "", "", "':'", "';'", "'.'", "','", "'['", "']'", "'('", "')'", "'{'", "'}'", "'>'", "'<'", "'=='", "'>='", "'<='", "'!='", "'*'", "'/'", "'%'", "'+'", "'-'", "'--'", "'++'", "", "", "", "'='", "'?'", @@ -53,7 +53,7 @@ func fqllexerLexerInit() { "'WITH'", "'COUNT'", "'ALL'", "'ANY'", "'AGGREGATE'", "'EVENT'", "'LIKE'", "", "'IN'", "'DO'", "'WHILE'", "'@'", } - staticData.symbolicNames = []string{ + staticData.SymbolicNames = []string{ "", "MultiLineComment", "SingleLineComment", "WhiteSpaces", "LineTerminator", "Colon", "SemiColon", "Dot", "Comma", "OpenBracket", "CloseBracket", "OpenParen", "CloseParen", "OpenBrace", "CloseBrace", "Gt", "Lt", "Eq", @@ -66,7 +66,7 @@ func fqllexerLexerInit() { "Param", "Identifier", "IgnoreIdentifier", "StringLiteral", "IntegerLiteral", "FloatLiteral", "NamespaceSegment", "UnknownIdentifier", } - staticData.ruleNames = []string{ + staticData.RuleNames = []string{ "MultiLineComment", "SingleLineComment", "WhiteSpaces", "LineTerminator", "Colon", "SemiColon", "Dot", "Comma", "OpenBracket", "CloseBracket", "OpenParen", "CloseParen", "OpenBrace", "CloseBrace", "Gt", "Lt", "Eq", @@ -81,7 +81,7 @@ func fqllexerLexerInit() { "DecimalIntegerLiteral", "ExponentPart", "Letter", "Symbols", "Underscore", "Digit", "DQSring", "SQString", "BacktickString", "TickString", "NamespaceSeparator", } - staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ 4, 0, 72, 621, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, @@ -374,7 +374,7 @@ func fqllexerLexerInit() { // NewFqlLexer(). You can call this function if you wish to initialize the static state ahead // of time. func FqlLexerInit() { - staticData := &fqllexerLexerStaticData + staticData := &FqlLexerLexerStaticData staticData.once.Do(fqllexerLexerInit) } @@ -383,13 +383,13 @@ func NewFqlLexer(input antlr.CharStream) *FqlLexer { FqlLexerInit() l := new(FqlLexer) l.BaseLexer = antlr.NewBaseLexer(input) - staticData := &fqllexerLexerStaticData - l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) - l.channelNames = staticData.channelNames - l.modeNames = staticData.modeNames - l.RuleNames = staticData.ruleNames - l.LiteralNames = staticData.literalNames - l.SymbolicNames = staticData.symbolicNames + staticData := &FqlLexerLexerStaticData + l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) + l.channelNames = staticData.ChannelNames + l.modeNames = staticData.ModeNames + l.RuleNames = staticData.RuleNames + l.LiteralNames = staticData.LiteralNames + l.SymbolicNames = staticData.SymbolicNames l.GrammarFileName = "FqlLexer.g4" // TODO: l.EOF = antlr.TokenEOF diff --git a/pkg/parser/fql/fql_parser.go b/pkg/parser/fql/fql_parser.go index 3daa028a..416587cc 100644 --- a/pkg/parser/fql/fql_parser.go +++ b/pkg/parser/fql/fql_parser.go @@ -1,4 +1,4 @@ -// Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT. +// Code generated from antlr/FqlParser.g4 by ANTLR 4.13.1. DO NOT EDIT. package fql // FqlParser import ( @@ -6,7 +6,7 @@ import ( "strconv" "sync" - "github.com/antlr/antlr4/runtime/Go/antlr/v4" + "github.com/antlr4-go/antlr/v4" ) // Suppress unused import errors @@ -18,20 +18,20 @@ type FqlParser struct { *antlr.BaseParser } -var fqlparserParserStaticData struct { +var FqlParserParserStaticData struct { once sync.Once serializedATN []int32 - literalNames []string - symbolicNames []string - ruleNames []string - predictionContextCache *antlr.PredictionContextCache + LiteralNames []string + SymbolicNames []string + RuleNames []string + PredictionContextCache *antlr.PredictionContextCache atn *antlr.ATN decisionToDFA []*antlr.DFA } func fqlparserParserInit() { - staticData := &fqlparserParserStaticData - staticData.literalNames = []string{ + staticData := &FqlParserParserStaticData + staticData.LiteralNames = []string{ "", "", "", "", "", "':'", "';'", "'.'", "','", "'['", "']'", "'('", "')'", "'{'", "'}'", "'>'", "'<'", "'=='", "'>='", "'<='", "'!='", "'*'", "'/'", "'%'", "'+'", "'-'", "'--'", "'++'", "", "", "", "'='", "'?'", @@ -41,7 +41,7 @@ func fqlparserParserInit() { "'WITH'", "'COUNT'", "'ALL'", "'ANY'", "'AGGREGATE'", "'EVENT'", "'LIKE'", "", "'IN'", "'DO'", "'WHILE'", "'@'", } - staticData.symbolicNames = []string{ + staticData.SymbolicNames = []string{ "", "MultiLineComment", "SingleLineComment", "WhiteSpaces", "LineTerminator", "Colon", "SemiColon", "Dot", "Comma", "OpenBracket", "CloseBracket", "OpenParen", "CloseParen", "OpenBrace", "CloseBrace", "Gt", "Lt", "Eq", @@ -54,7 +54,7 @@ func fqlparserParserInit() { "Param", "Identifier", "IgnoreIdentifier", "StringLiteral", "IntegerLiteral", "FloatLiteral", "NamespaceSegment", "UnknownIdentifier", } - staticData.ruleNames = []string{ + staticData.RuleNames = []string{ "program", "head", "useExpression", "use", "body", "bodyStatement", "bodyExpression", "variableDeclaration", "returnExpression", "forExpression", "forExpressionSource", "forExpressionClause", "forExpressionStatement", @@ -73,7 +73,7 @@ func fqlparserParserInit() { "inOperator", "likeOperator", "unaryOperator", "regexpOperator", "logicalAndOperator", "logicalOrOperator", "multiplicativeOperator", "additiveOperator", "errorOperator", } - staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ 4, 1, 72, 647, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, @@ -384,7 +384,7 @@ func fqlparserParserInit() { // NewFqlParser(). You can call this function if you wish to initialize the static state ahead // of time. func FqlParserInit() { - staticData := &fqlparserParserStaticData + staticData := &FqlParserParserStaticData staticData.once.Do(fqlparserParserInit) } @@ -393,12 +393,12 @@ func NewFqlParser(input antlr.TokenStream) *FqlParser { FqlParserInit() this := new(FqlParser) this.BaseParser = antlr.NewBaseParser(input) - staticData := &fqlparserParserStaticData - this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) - this.RuleNames = staticData.ruleNames - this.LiteralNames = staticData.literalNames - this.SymbolicNames = staticData.symbolicNames - this.GrammarFileName = "java-escape" + staticData := &FqlParserParserStaticData + this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) + this.RuleNames = staticData.RuleNames + this.LiteralNames = staticData.LiteralNames + this.SymbolicNames = staticData.SymbolicNames + this.GrammarFileName = "FqlParser.g4" return this } @@ -563,28 +563,38 @@ type IProgramContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Body() IBodyContext + AllHead() []IHeadContext + Head(i int) IHeadContext + // IsProgramContext differentiates from other interfaces. IsProgramContext() } type ProgramContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyProgramContext() *ProgramContext { var p = new(ProgramContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_program return p } +func InitEmptyProgramContext(p *ProgramContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_program +} + func (*ProgramContext) IsProgramContext() {} func NewProgramContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ProgramContext { var p = new(ProgramContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_program @@ -682,35 +692,20 @@ func (s *ProgramContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Program() (localctx IProgramContext) { - this := p - _ = this - localctx = NewProgramContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 0, FqlParserRULE_program) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) p.SetState(147) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 0, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { @@ -721,14 +716,30 @@ func (p *FqlParser) Program() (localctx IProgramContext) { } p.SetState(149) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 0, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } { p.SetState(150) p.Body() } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IHeadContext is an interface to support dynamic dispatch. @@ -738,28 +749,36 @@ type IHeadContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + UseExpression() IUseExpressionContext + // IsHeadContext differentiates from other interfaces. IsHeadContext() } type HeadContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyHeadContext() *HeadContext { var p = new(HeadContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_head return p } +func InitEmptyHeadContext(p *HeadContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_head +} + func (*HeadContext) IsHeadContext() {} func NewHeadContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *HeadContext { var p = new(HeadContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_head @@ -816,35 +835,25 @@ func (s *HeadContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Head() (localctx IHeadContext) { - this := p - _ = this - localctx = NewHeadContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 2, FqlParserRULE_head) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(152) p.UseExpression() } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IUseExpressionContext is an interface to support dynamic dispatch. @@ -854,28 +863,36 @@ type IUseExpressionContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Use() IUseContext + // IsUseExpressionContext differentiates from other interfaces. IsUseExpressionContext() } type UseExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyUseExpressionContext() *UseExpressionContext { var p = new(UseExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_useExpression return p } +func InitEmptyUseExpressionContext(p *UseExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_useExpression +} + func (*UseExpressionContext) IsUseExpressionContext() {} func NewUseExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UseExpressionContext { var p = new(UseExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_useExpression @@ -932,35 +949,25 @@ func (s *UseExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) UseExpression() (localctx IUseExpressionContext) { - this := p - _ = this - localctx = NewUseExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 4, FqlParserRULE_useExpression) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(154) p.Use() } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IUseContext is an interface to support dynamic dispatch. @@ -970,28 +977,37 @@ type IUseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Use() antlr.TerminalNode + NamespaceIdentifier() INamespaceIdentifierContext + // IsUseContext differentiates from other interfaces. IsUseContext() } type UseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyUseContext() *UseContext { var p = new(UseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_use return p } +func InitEmptyUseContext(p *UseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_use +} + func (*UseContext) IsUseContext() {} func NewUseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UseContext { var p = new(UseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_use @@ -1052,39 +1068,33 @@ func (s *UseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Use() (localctx IUseContext) { - this := p - _ = this - localctx = NewUseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 6, FqlParserRULE_use) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(156) p.Match(FqlParserUse) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(157) p.NamespaceIdentifier() } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IBodyContext is an interface to support dynamic dispatch. @@ -1094,28 +1104,38 @@ type IBodyContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + BodyExpression() IBodyExpressionContext + AllBodyStatement() []IBodyStatementContext + BodyStatement(i int) IBodyStatementContext + // IsBodyContext differentiates from other interfaces. IsBodyContext() } type BodyContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyBodyContext() *BodyContext { var p = new(BodyContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_body return p } +func InitEmptyBodyContext(p *BodyContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_body +} + func (*BodyContext) IsBodyContext() {} func NewBodyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *BodyContext { var p = new(BodyContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_body @@ -1213,35 +1233,20 @@ func (s *BodyContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Body() (localctx IBodyContext) { - this := p - _ = this - localctx = NewBodyContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 8, FqlParserRULE_body) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) p.SetState(162) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 1, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { @@ -1252,14 +1257,30 @@ func (p *FqlParser) Body() (localctx IBodyContext) { } p.SetState(164) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 1, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } { p.SetState(165) p.BodyExpression() } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IBodyStatementContext is an interface to support dynamic dispatch. @@ -1269,28 +1290,38 @@ type IBodyStatementContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + VariableDeclaration() IVariableDeclarationContext + FunctionCallExpression() IFunctionCallExpressionContext + WaitForExpression() IWaitForExpressionContext + // IsBodyStatementContext differentiates from other interfaces. IsBodyStatementContext() } type BodyStatementContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyBodyStatementContext() *BodyStatementContext { var p = new(BodyStatementContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_bodyStatement return p } +func InitEmptyBodyStatementContext(p *BodyStatementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_bodyStatement +} + func (*BodyStatementContext) IsBodyStatementContext() {} func NewBodyStatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *BodyStatementContext { var p = new(BodyStatementContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_bodyStatement @@ -1379,31 +1410,15 @@ func (s *BodyStatementContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) BodyStatement() (localctx IBodyStatementContext) { - this := p - _ = this - localctx = NewBodyStatementContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 10, FqlParserRULE_bodyStatement) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(170) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 2, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -1425,9 +1440,21 @@ func (p *FqlParser) BodyStatement() (localctx IBodyStatementContext) { p.WaitForExpression() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IBodyExpressionContext is an interface to support dynamic dispatch. @@ -1437,28 +1464,37 @@ type IBodyExpressionContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + ReturnExpression() IReturnExpressionContext + ForExpression() IForExpressionContext + // IsBodyExpressionContext differentiates from other interfaces. IsBodyExpressionContext() } type BodyExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyBodyExpressionContext() *BodyExpressionContext { var p = new(BodyExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_bodyExpression return p } +func InitEmptyBodyExpressionContext(p *BodyExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_bodyExpression +} + func (*BodyExpressionContext) IsBodyExpressionContext() {} func NewBodyExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *BodyExpressionContext { var p = new(BodyExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_bodyExpression @@ -1531,30 +1567,13 @@ func (s *BodyExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface } func (p *FqlParser) BodyExpression() (localctx IBodyExpressionContext) { - this := p - _ = this - localctx = NewBodyExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 12, FqlParserRULE_bodyExpression) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(174) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserReturn: @@ -1572,10 +1591,21 @@ func (p *FqlParser) BodyExpression() (localctx IBodyExpressionContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IVariableDeclarationContext is an interface to support dynamic dispatch. @@ -1591,29 +1621,42 @@ type IVariableDeclarationContext interface { // SetId sets the id token. SetId(antlr.Token) + // Getter signatures + Let() antlr.TerminalNode + Assign() antlr.TerminalNode + Expression() IExpressionContext + Identifier() antlr.TerminalNode + IgnoreIdentifier() antlr.TerminalNode + SafeReservedWord() ISafeReservedWordContext + // IsVariableDeclarationContext differentiates from other interfaces. IsVariableDeclarationContext() } type VariableDeclarationContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser id antlr.Token } func NewEmptyVariableDeclarationContext() *VariableDeclarationContext { var p = new(VariableDeclarationContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_variableDeclaration return p } +func InitEmptyVariableDeclarationContext(p *VariableDeclarationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_variableDeclaration +} + func (*VariableDeclarationContext) IsVariableDeclarationContext() {} func NewVariableDeclarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VariableDeclarationContext { var p = new(VariableDeclarationContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_variableDeclaration @@ -1706,37 +1749,26 @@ func (s *VariableDeclarationContext) Accept(visitor antlr.ParseTreeVisitor) inte } func (p *FqlParser) VariableDeclaration() (localctx IVariableDeclarationContext) { - this := p - _ = this - localctx = NewVariableDeclarationContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 14, FqlParserRULE_variableDeclaration) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(185) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 4, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 4, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { p.SetState(176) p.Match(FqlParserLet) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(177) @@ -1759,6 +1791,10 @@ func (p *FqlParser) VariableDeclaration() (localctx IVariableDeclarationContext) { p.SetState(178) p.Match(FqlParserAssign) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(179) @@ -1770,6 +1806,10 @@ func (p *FqlParser) VariableDeclaration() (localctx IVariableDeclarationContext) { p.SetState(180) p.Match(FqlParserLet) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(181) @@ -1778,15 +1818,31 @@ func (p *FqlParser) VariableDeclaration() (localctx IVariableDeclarationContext) { p.SetState(182) p.Match(FqlParserAssign) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(183) p.expression(0) } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IReturnExpressionContext is an interface to support dynamic dispatch. @@ -1796,28 +1852,38 @@ type IReturnExpressionContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Return() antlr.TerminalNode + Expression() IExpressionContext + Distinct() antlr.TerminalNode + // IsReturnExpressionContext differentiates from other interfaces. IsReturnExpressionContext() } type ReturnExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyReturnExpressionContext() *ReturnExpressionContext { var p = new(ReturnExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_returnExpression return p } +func InitEmptyReturnExpressionContext(p *ReturnExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_returnExpression +} + func (*ReturnExpressionContext) IsReturnExpressionContext() {} func NewReturnExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ReturnExpressionContext { var p = new(ReturnExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_returnExpression @@ -1882,49 +1948,49 @@ func (s *ReturnExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interfa } func (p *FqlParser) ReturnExpression() (localctx IReturnExpressionContext) { - this := p - _ = this - localctx = NewReturnExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 16, FqlParserRULE_returnExpression) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(187) p.Match(FqlParserReturn) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(189) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 5, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 5, p.GetParserRuleContext()) == 1 { { p.SetState(188) p.Match(FqlParserDistinct) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } + } else if p.HasError() { // JIM + goto errorExit } { p.SetState(191) p.expression(0) } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IForExpressionContext is an interface to support dynamic dispatch. @@ -1946,12 +2012,27 @@ type IForExpressionContext interface { // SetCounterVariable sets the counterVariable token. SetCounterVariable(antlr.Token) + // Getter signatures + For() antlr.TerminalNode + In() antlr.TerminalNode + ForExpressionSource() IForExpressionSourceContext + ForExpressionReturn() IForExpressionReturnContext + AllIdentifier() []antlr.TerminalNode + Identifier(i int) antlr.TerminalNode + IgnoreIdentifier() antlr.TerminalNode + Comma() antlr.TerminalNode + AllForExpressionBody() []IForExpressionBodyContext + ForExpressionBody(i int) IForExpressionBodyContext + While() antlr.TerminalNode + Expression() IExpressionContext + Do() antlr.TerminalNode + // IsForExpressionContext differentiates from other interfaces. IsForExpressionContext() } type ForExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser valueVariable antlr.Token counterVariable antlr.Token @@ -1959,17 +2040,22 @@ type ForExpressionContext struct { func NewEmptyForExpressionContext() *ForExpressionContext { var p = new(ForExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_forExpression return p } +func InitEmptyForExpressionContext(p *ForExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_forExpression +} + func (*ForExpressionContext) IsForExpressionContext() {} func NewForExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForExpressionContext { var p = new(ForExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_forExpression @@ -2139,39 +2225,28 @@ func (s *ForExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { - this := p - _ = this - localctx = NewForExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 18, FqlParserRULE_forExpression) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.SetState(224) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 10, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 10, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { p.SetState(193) p.Match(FqlParserFor) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(194) @@ -2193,12 +2268,19 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { } p.SetState(197) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserComma { { p.SetState(195) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(196) @@ -2206,12 +2288,20 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { var _m = p.Match(FqlParserIdentifier) localctx.(*ForExpressionContext).counterVariable = _m + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } } { p.SetState(199) p.Match(FqlParserIn) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(200) @@ -2219,8 +2309,13 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { } p.SetState(204) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 7, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 7, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { @@ -2231,7 +2326,13 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { } p.SetState(206) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 7, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 7, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } { p.SetState(207) @@ -2243,6 +2344,10 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { { p.SetState(209) p.Match(FqlParserFor) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(210) @@ -2264,18 +2369,29 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { } p.SetState(212) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserDo { { p.SetState(211) p.Match(FqlParserDo) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } } { p.SetState(214) p.Match(FqlParserWhile) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(215) @@ -2283,8 +2399,13 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { } p.SetState(219) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 9, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 9, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { @@ -2295,16 +2416,34 @@ func (p *FqlParser) ForExpression() (localctx IForExpressionContext) { } p.SetState(221) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 9, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 9, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } { p.SetState(222) p.ForExpressionReturn() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IForExpressionSourceContext is an interface to support dynamic dispatch. @@ -2314,28 +2453,42 @@ type IForExpressionSourceContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + FunctionCallExpression() IFunctionCallExpressionContext + ArrayLiteral() IArrayLiteralContext + ObjectLiteral() IObjectLiteralContext + Variable() IVariableContext + MemberExpression() IMemberExpressionContext + RangeOperator() IRangeOperatorContext + Param() IParamContext + // IsForExpressionSourceContext differentiates from other interfaces. IsForExpressionSourceContext() } type ForExpressionSourceContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyForExpressionSourceContext() *ForExpressionSourceContext { var p = new(ForExpressionSourceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_forExpressionSource return p } +func InitEmptyForExpressionSourceContext(p *ForExpressionSourceContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_forExpressionSource +} + func (*ForExpressionSourceContext) IsForExpressionSourceContext() {} func NewForExpressionSourceContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForExpressionSourceContext { var p = new(ForExpressionSourceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_forExpressionSource @@ -2488,31 +2641,15 @@ func (s *ForExpressionSourceContext) Accept(visitor antlr.ParseTreeVisitor) inte } func (p *FqlParser) ForExpressionSource() (localctx IForExpressionSourceContext) { - this := p - _ = this - localctx = NewForExpressionSourceContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 20, FqlParserRULE_forExpressionSource) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(233) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 11, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 11, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -2562,9 +2699,21 @@ func (p *FqlParser) ForExpressionSource() (localctx IForExpressionSourceContext) p.Param() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IForExpressionClauseContext is an interface to support dynamic dispatch. @@ -2574,28 +2723,39 @@ type IForExpressionClauseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + LimitClause() ILimitClauseContext + SortClause() ISortClauseContext + FilterClause() IFilterClauseContext + CollectClause() ICollectClauseContext + // IsForExpressionClauseContext differentiates from other interfaces. IsForExpressionClauseContext() } type ForExpressionClauseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyForExpressionClauseContext() *ForExpressionClauseContext { var p = new(ForExpressionClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_forExpressionClause return p } +func InitEmptyForExpressionClauseContext(p *ForExpressionClauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_forExpressionClause +} + func (*ForExpressionClauseContext) IsForExpressionClauseContext() {} func NewForExpressionClauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForExpressionClauseContext { var p = new(ForExpressionClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_forExpressionClause @@ -2700,30 +2860,13 @@ func (s *ForExpressionClauseContext) Accept(visitor antlr.ParseTreeVisitor) inte } func (p *FqlParser) ForExpressionClause() (localctx IForExpressionClauseContext) { - this := p - _ = this - localctx = NewForExpressionClauseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 22, FqlParserRULE_forExpressionClause) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(239) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserLimit: @@ -2755,10 +2898,21 @@ func (p *FqlParser) ForExpressionClause() (localctx IForExpressionClauseContext) } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IForExpressionStatementContext is an interface to support dynamic dispatch. @@ -2768,28 +2922,37 @@ type IForExpressionStatementContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + VariableDeclaration() IVariableDeclarationContext + FunctionCallExpression() IFunctionCallExpressionContext + // IsForExpressionStatementContext differentiates from other interfaces. IsForExpressionStatementContext() } type ForExpressionStatementContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyForExpressionStatementContext() *ForExpressionStatementContext { var p = new(ForExpressionStatementContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_forExpressionStatement return p } +func InitEmptyForExpressionStatementContext(p *ForExpressionStatementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_forExpressionStatement +} + func (*ForExpressionStatementContext) IsForExpressionStatementContext() {} func NewForExpressionStatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForExpressionStatementContext { var p = new(ForExpressionStatementContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_forExpressionStatement @@ -2862,31 +3025,15 @@ func (s *ForExpressionStatementContext) Accept(visitor antlr.ParseTreeVisitor) i } func (p *FqlParser) ForExpressionStatement() (localctx IForExpressionStatementContext) { - this := p - _ = this - localctx = NewForExpressionStatementContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 24, FqlParserRULE_forExpressionStatement) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(243) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 13, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 13, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -2901,9 +3048,21 @@ func (p *FqlParser) ForExpressionStatement() (localctx IForExpressionStatementCo p.FunctionCallExpression() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IForExpressionBodyContext is an interface to support dynamic dispatch. @@ -2913,28 +3072,37 @@ type IForExpressionBodyContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + ForExpressionStatement() IForExpressionStatementContext + ForExpressionClause() IForExpressionClauseContext + // IsForExpressionBodyContext differentiates from other interfaces. IsForExpressionBodyContext() } type ForExpressionBodyContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyForExpressionBodyContext() *ForExpressionBodyContext { var p = new(ForExpressionBodyContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_forExpressionBody return p } +func InitEmptyForExpressionBodyContext(p *ForExpressionBodyContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_forExpressionBody +} + func (*ForExpressionBodyContext) IsForExpressionBodyContext() {} func NewForExpressionBodyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForExpressionBodyContext { var p = new(ForExpressionBodyContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_forExpressionBody @@ -3007,31 +3175,15 @@ func (s *ForExpressionBodyContext) Accept(visitor antlr.ParseTreeVisitor) interf } func (p *FqlParser) ForExpressionBody() (localctx IForExpressionBodyContext) { - this := p - _ = this - localctx = NewForExpressionBodyContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 26, FqlParserRULE_forExpressionBody) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(247) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 14, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 14, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -3046,9 +3198,21 @@ func (p *FqlParser) ForExpressionBody() (localctx IForExpressionBodyContext) { p.ForExpressionClause() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IForExpressionReturnContext is an interface to support dynamic dispatch. @@ -3058,28 +3222,37 @@ type IForExpressionReturnContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + ReturnExpression() IReturnExpressionContext + ForExpression() IForExpressionContext + // IsForExpressionReturnContext differentiates from other interfaces. IsForExpressionReturnContext() } type ForExpressionReturnContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyForExpressionReturnContext() *ForExpressionReturnContext { var p = new(ForExpressionReturnContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_forExpressionReturn return p } +func InitEmptyForExpressionReturnContext(p *ForExpressionReturnContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_forExpressionReturn +} + func (*ForExpressionReturnContext) IsForExpressionReturnContext() {} func NewForExpressionReturnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForExpressionReturnContext { var p = new(ForExpressionReturnContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_forExpressionReturn @@ -3152,30 +3325,13 @@ func (s *ForExpressionReturnContext) Accept(visitor antlr.ParseTreeVisitor) inte } func (p *FqlParser) ForExpressionReturn() (localctx IForExpressionReturnContext) { - this := p - _ = this - localctx = NewForExpressionReturnContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 28, FqlParserRULE_forExpressionReturn) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(251) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserReturn: @@ -3193,10 +3349,21 @@ func (p *FqlParser) ForExpressionReturn() (localctx IForExpressionReturnContext) } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IFilterClauseContext is an interface to support dynamic dispatch. @@ -3206,28 +3373,37 @@ type IFilterClauseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Filter() antlr.TerminalNode + Expression() IExpressionContext + // IsFilterClauseContext differentiates from other interfaces. IsFilterClauseContext() } type FilterClauseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyFilterClauseContext() *FilterClauseContext { var p = new(FilterClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_filterClause return p } +func InitEmptyFilterClauseContext(p *FilterClauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_filterClause +} + func (*FilterClauseContext) IsFilterClauseContext() {} func NewFilterClauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FilterClauseContext { var p = new(FilterClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_filterClause @@ -3288,39 +3464,33 @@ func (s *FilterClauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) FilterClause() (localctx IFilterClauseContext) { - this := p - _ = this - localctx = NewFilterClauseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 30, FqlParserRULE_filterClause) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(253) p.Match(FqlParserFilter) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(254) p.expression(0) } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ILimitClauseContext is an interface to support dynamic dispatch. @@ -3330,28 +3500,39 @@ type ILimitClauseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Limit() antlr.TerminalNode + AllLimitClauseValue() []ILimitClauseValueContext + LimitClauseValue(i int) ILimitClauseValueContext + Comma() antlr.TerminalNode + // IsLimitClauseContext differentiates from other interfaces. IsLimitClauseContext() } type LimitClauseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyLimitClauseContext() *LimitClauseContext { var p = new(LimitClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_limitClause return p } +func InitEmptyLimitClauseContext(p *LimitClauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_limitClause +} + func (*LimitClauseContext) IsLimitClauseContext() {} func NewLimitClauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LimitClauseContext { var p = new(LimitClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_limitClause @@ -3441,33 +3622,18 @@ func (s *LimitClauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) LimitClause() (localctx ILimitClauseContext) { - this := p - _ = this - localctx = NewLimitClauseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 32, FqlParserRULE_limitClause) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(256) p.Match(FqlParserLimit) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(257) @@ -3475,12 +3641,19 @@ func (p *FqlParser) LimitClause() (localctx ILimitClauseContext) { } p.SetState(260) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserComma { { p.SetState(258) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(259) @@ -3489,7 +3662,17 @@ func (p *FqlParser) LimitClause() (localctx ILimitClauseContext) { } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ILimitClauseValueContext is an interface to support dynamic dispatch. @@ -3499,28 +3682,40 @@ type ILimitClauseValueContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + IntegerLiteral() IIntegerLiteralContext + Param() IParamContext + Variable() IVariableContext + FunctionCallExpression() IFunctionCallExpressionContext + MemberExpression() IMemberExpressionContext + // IsLimitClauseValueContext differentiates from other interfaces. IsLimitClauseValueContext() } type LimitClauseValueContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyLimitClauseValueContext() *LimitClauseValueContext { var p = new(LimitClauseValueContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_limitClauseValue return p } +func InitEmptyLimitClauseValueContext(p *LimitClauseValueContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_limitClauseValue +} + func (*LimitClauseValueContext) IsLimitClauseValueContext() {} func NewLimitClauseValueContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LimitClauseValueContext { var p = new(LimitClauseValueContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_limitClauseValue @@ -3641,31 +3836,15 @@ func (s *LimitClauseValueContext) Accept(visitor antlr.ParseTreeVisitor) interfa } func (p *FqlParser) LimitClauseValue() (localctx ILimitClauseValueContext) { - this := p - _ = this - localctx = NewLimitClauseValueContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 34, FqlParserRULE_limitClauseValue) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(267) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 17, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 17, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -3701,9 +3880,21 @@ func (p *FqlParser) LimitClauseValue() (localctx ILimitClauseValueContext) { p.MemberExpression() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ISortClauseContext is an interface to support dynamic dispatch. @@ -3713,28 +3904,40 @@ type ISortClauseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Sort() antlr.TerminalNode + AllSortClauseExpression() []ISortClauseExpressionContext + SortClauseExpression(i int) ISortClauseExpressionContext + AllComma() []antlr.TerminalNode + Comma(i int) antlr.TerminalNode + // IsSortClauseContext differentiates from other interfaces. IsSortClauseContext() } type SortClauseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptySortClauseContext() *SortClauseContext { var p = new(SortClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_sortClause return p } +func InitEmptySortClauseContext(p *SortClauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_sortClause +} + func (*SortClauseContext) IsSortClauseContext() {} func NewSortClauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SortClauseContext { var p = new(SortClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_sortClause @@ -3828,33 +4031,18 @@ func (s *SortClauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) SortClause() (localctx ISortClauseContext) { - this := p - _ = this - localctx = NewSortClauseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 36, FqlParserRULE_sortClause) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(269) p.Match(FqlParserSort) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(270) @@ -3862,12 +4050,19 @@ func (p *FqlParser) SortClause() (localctx ISortClauseContext) { } p.SetState(275) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) for _la == FqlParserComma { { p.SetState(271) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(272) @@ -3876,10 +4071,23 @@ func (p *FqlParser) SortClause() (localctx ISortClauseContext) { p.SetState(277) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ISortClauseExpressionContext is an interface to support dynamic dispatch. @@ -3889,28 +4097,37 @@ type ISortClauseExpressionContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Expression() IExpressionContext + SortDirection() antlr.TerminalNode + // IsSortClauseExpressionContext differentiates from other interfaces. IsSortClauseExpressionContext() } type SortClauseExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptySortClauseExpressionContext() *SortClauseExpressionContext { var p = new(SortClauseExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_sortClauseExpression return p } +func InitEmptySortClauseExpressionContext(p *SortClauseExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_sortClauseExpression +} + func (*SortClauseExpressionContext) IsSortClauseExpressionContext() {} func NewSortClauseExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SortClauseExpressionContext { var p = new(SortClauseExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_sortClauseExpression @@ -3971,28 +4188,8 @@ func (s *SortClauseExpressionContext) Accept(visitor antlr.ParseTreeVisitor) int } func (p *FqlParser) SortClauseExpression() (localctx ISortClauseExpressionContext) { - this := p - _ = this - localctx = NewSortClauseExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 38, FqlParserRULE_sortClauseExpression) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(278) @@ -4001,15 +4198,31 @@ func (p *FqlParser) SortClauseExpression() (localctx ISortClauseExpressionContex p.SetState(280) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 19, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 19, p.GetParserRuleContext()) == 1 { { p.SetState(279) p.Match(FqlParserSortDirection) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } + } else if p.HasError() { // JIM + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ICollectClauseContext is an interface to support dynamic dispatch. @@ -4019,28 +4232,40 @@ type ICollectClauseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Collect() antlr.TerminalNode + CollectCounter() ICollectCounterContext + CollectAggregator() ICollectAggregatorContext + CollectGrouping() ICollectGroupingContext + CollectGroupVariable() ICollectGroupVariableContext + // IsCollectClauseContext differentiates from other interfaces. IsCollectClauseContext() } type CollectClauseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyCollectClauseContext() *CollectClauseContext { var p = new(CollectClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_collectClause return p } +func InitEmptyCollectClauseContext(p *CollectClauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_collectClause +} + func (*CollectClauseContext) IsCollectClauseContext() {} func NewCollectClauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CollectClauseContext { var p = new(CollectClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_collectClause @@ -4149,36 +4374,24 @@ func (s *CollectClauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) CollectClause() (localctx ICollectClauseContext) { - this := p - _ = this - localctx = NewCollectClauseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 40, FqlParserRULE_collectClause) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(300) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 20, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 20, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { p.SetState(282) p.Match(FqlParserCollect) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(283) @@ -4190,6 +4403,10 @@ func (p *FqlParser) CollectClause() (localctx ICollectClauseContext) { { p.SetState(284) p.Match(FqlParserCollect) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(285) @@ -4201,6 +4418,10 @@ func (p *FqlParser) CollectClause() (localctx ICollectClauseContext) { { p.SetState(286) p.Match(FqlParserCollect) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(287) @@ -4216,6 +4437,10 @@ func (p *FqlParser) CollectClause() (localctx ICollectClauseContext) { { p.SetState(290) p.Match(FqlParserCollect) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(291) @@ -4231,6 +4456,10 @@ func (p *FqlParser) CollectClause() (localctx ICollectClauseContext) { { p.SetState(294) p.Match(FqlParserCollect) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(295) @@ -4246,15 +4475,31 @@ func (p *FqlParser) CollectClause() (localctx ICollectClauseContext) { { p.SetState(298) p.Match(FqlParserCollect) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(299) p.CollectGrouping() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ICollectSelectorContext is an interface to support dynamic dispatch. @@ -4264,28 +4509,38 @@ type ICollectSelectorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Identifier() antlr.TerminalNode + Assign() antlr.TerminalNode + Expression() IExpressionContext + // IsCollectSelectorContext differentiates from other interfaces. IsCollectSelectorContext() } type CollectSelectorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyCollectSelectorContext() *CollectSelectorContext { var p = new(CollectSelectorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_collectSelector return p } +func InitEmptyCollectSelectorContext(p *CollectSelectorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_collectSelector +} + func (*CollectSelectorContext) IsCollectSelectorContext() {} func NewCollectSelectorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CollectSelectorContext { var p = new(CollectSelectorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_collectSelector @@ -4350,43 +4605,41 @@ func (s *CollectSelectorContext) Accept(visitor antlr.ParseTreeVisitor) interfac } func (p *FqlParser) CollectSelector() (localctx ICollectSelectorContext) { - this := p - _ = this - localctx = NewCollectSelectorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 42, FqlParserRULE_collectSelector) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(302) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(303) p.Match(FqlParserAssign) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(304) p.expression(0) } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ICollectGroupingContext is an interface to support dynamic dispatch. @@ -4396,28 +4649,39 @@ type ICollectGroupingContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + AllCollectSelector() []ICollectSelectorContext + CollectSelector(i int) ICollectSelectorContext + AllComma() []antlr.TerminalNode + Comma(i int) antlr.TerminalNode + // IsCollectGroupingContext differentiates from other interfaces. IsCollectGroupingContext() } type CollectGroupingContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyCollectGroupingContext() *CollectGroupingContext { var p = new(CollectGroupingContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_collectGrouping return p } +func InitEmptyCollectGroupingContext(p *CollectGroupingContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_collectGrouping +} + func (*CollectGroupingContext) IsCollectGroupingContext() {} func NewCollectGroupingContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CollectGroupingContext { var p = new(CollectGroupingContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_collectGrouping @@ -4507,29 +4771,10 @@ func (s *CollectGroupingContext) Accept(visitor antlr.ParseTreeVisitor) interfac } func (p *FqlParser) CollectGrouping() (localctx ICollectGroupingContext) { - this := p - _ = this - localctx = NewCollectGroupingContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 44, FqlParserRULE_collectGrouping) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(306) @@ -4537,12 +4782,19 @@ func (p *FqlParser) CollectGrouping() (localctx ICollectGroupingContext) { } p.SetState(311) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) for _la == FqlParserComma { { p.SetState(307) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(308) @@ -4551,10 +4803,23 @@ func (p *FqlParser) CollectGrouping() (localctx ICollectGroupingContext) { p.SetState(313) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ICollectAggregatorContext is an interface to support dynamic dispatch. @@ -4564,28 +4829,40 @@ type ICollectAggregatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Aggregate() antlr.TerminalNode + AllCollectAggregateSelector() []ICollectAggregateSelectorContext + CollectAggregateSelector(i int) ICollectAggregateSelectorContext + AllComma() []antlr.TerminalNode + Comma(i int) antlr.TerminalNode + // IsCollectAggregatorContext differentiates from other interfaces. IsCollectAggregatorContext() } type CollectAggregatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyCollectAggregatorContext() *CollectAggregatorContext { var p = new(CollectAggregatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_collectAggregator return p } +func InitEmptyCollectAggregatorContext(p *CollectAggregatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_collectAggregator +} + func (*CollectAggregatorContext) IsCollectAggregatorContext() {} func NewCollectAggregatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CollectAggregatorContext { var p = new(CollectAggregatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_collectAggregator @@ -4679,33 +4956,18 @@ func (s *CollectAggregatorContext) Accept(visitor antlr.ParseTreeVisitor) interf } func (p *FqlParser) CollectAggregator() (localctx ICollectAggregatorContext) { - this := p - _ = this - localctx = NewCollectAggregatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 46, FqlParserRULE_collectAggregator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(314) p.Match(FqlParserAggregate) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(315) @@ -4713,12 +4975,19 @@ func (p *FqlParser) CollectAggregator() (localctx ICollectAggregatorContext) { } p.SetState(320) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) for _la == FqlParserComma { { p.SetState(316) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(317) @@ -4727,10 +4996,23 @@ func (p *FqlParser) CollectAggregator() (localctx ICollectAggregatorContext) { p.SetState(322) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ICollectAggregateSelectorContext is an interface to support dynamic dispatch. @@ -4740,28 +5022,38 @@ type ICollectAggregateSelectorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Identifier() antlr.TerminalNode + Assign() antlr.TerminalNode + FunctionCallExpression() IFunctionCallExpressionContext + // IsCollectAggregateSelectorContext differentiates from other interfaces. IsCollectAggregateSelectorContext() } type CollectAggregateSelectorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyCollectAggregateSelectorContext() *CollectAggregateSelectorContext { var p = new(CollectAggregateSelectorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_collectAggregateSelector return p } +func InitEmptyCollectAggregateSelectorContext(p *CollectAggregateSelectorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_collectAggregateSelector +} + func (*CollectAggregateSelectorContext) IsCollectAggregateSelectorContext() {} func NewCollectAggregateSelectorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CollectAggregateSelectorContext { var p = new(CollectAggregateSelectorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_collectAggregateSelector @@ -4826,43 +5118,41 @@ func (s *CollectAggregateSelectorContext) Accept(visitor antlr.ParseTreeVisitor) } func (p *FqlParser) CollectAggregateSelector() (localctx ICollectAggregateSelectorContext) { - this := p - _ = this - localctx = NewCollectAggregateSelectorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 48, FqlParserRULE_collectAggregateSelector) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(323) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(324) p.Match(FqlParserAssign) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(325) p.FunctionCallExpression() } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ICollectGroupVariableContext is an interface to support dynamic dispatch. @@ -4872,28 +5162,40 @@ type ICollectGroupVariableContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Into() antlr.TerminalNode + CollectSelector() ICollectSelectorContext + AllIdentifier() []antlr.TerminalNode + Identifier(i int) antlr.TerminalNode + Keep() antlr.TerminalNode + // IsCollectGroupVariableContext differentiates from other interfaces. IsCollectGroupVariableContext() } type CollectGroupVariableContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyCollectGroupVariableContext() *CollectGroupVariableContext { var p = new(CollectGroupVariableContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_collectGroupVariable return p } +func InitEmptyCollectGroupVariableContext(p *CollectGroupVariableContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_collectGroupVariable +} + func (*CollectGroupVariableContext) IsCollectGroupVariableContext() {} func NewCollectGroupVariableContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CollectGroupVariableContext { var p = new(CollectGroupVariableContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_collectGroupVariable @@ -4966,36 +5268,24 @@ func (s *CollectGroupVariableContext) Accept(visitor antlr.ParseTreeVisitor) int } func (p *FqlParser) CollectGroupVariable() (localctx ICollectGroupVariableContext) { - this := p - _ = this - localctx = NewCollectGroupVariableContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 50, FqlParserRULE_collectGroupVariable) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(335) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 24, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 24, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { p.SetState(327) p.Match(FqlParserInto) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(328) @@ -5007,29 +5297,59 @@ func (p *FqlParser) CollectGroupVariable() (localctx ICollectGroupVariableContex { p.SetState(329) p.Match(FqlParserInto) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(330) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(333) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 23, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 23, p.GetParserRuleContext()) == 1 { { p.SetState(331) p.Match(FqlParserKeep) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(332) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } + } else if p.HasError() { // JIM + goto errorExit } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ICollectCounterContext is an interface to support dynamic dispatch. @@ -5039,28 +5359,39 @@ type ICollectCounterContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + With() antlr.TerminalNode + Count() antlr.TerminalNode + Into() antlr.TerminalNode + Identifier() antlr.TerminalNode + // IsCollectCounterContext differentiates from other interfaces. IsCollectCounterContext() } type CollectCounterContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyCollectCounterContext() *CollectCounterContext { var p = new(CollectCounterContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_collectCounter return p } +func InitEmptyCollectCounterContext(p *CollectCounterContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_collectCounter +} + func (*CollectCounterContext) IsCollectCounterContext() {} func NewCollectCounterContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CollectCounterContext { var p = new(CollectCounterContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_collectCounter @@ -5117,47 +5448,53 @@ func (s *CollectCounterContext) Accept(visitor antlr.ParseTreeVisitor) interface } func (p *FqlParser) CollectCounter() (localctx ICollectCounterContext) { - this := p - _ = this - localctx = NewCollectCounterContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 52, FqlParserRULE_collectCounter) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(337) p.Match(FqlParserWith) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(338) p.Match(FqlParserCount) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(339) p.Match(FqlParserInto) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(340) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IWaitForExpressionContext is an interface to support dynamic dispatch. @@ -5167,28 +5504,43 @@ type IWaitForExpressionContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Waitfor() antlr.TerminalNode + Event() antlr.TerminalNode + WaitForEventName() IWaitForEventNameContext + In() antlr.TerminalNode + WaitForEventSource() IWaitForEventSourceContext + OptionsClause() IOptionsClauseContext + FilterClause() IFilterClauseContext + TimeoutClause() ITimeoutClauseContext + // IsWaitForExpressionContext differentiates from other interfaces. IsWaitForExpressionContext() } type WaitForExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyWaitForExpressionContext() *WaitForExpressionContext { var p = new(WaitForExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_waitForExpression return p } +func InitEmptyWaitForExpressionContext(p *WaitForExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_waitForExpression +} + func (*WaitForExpressionContext) IsWaitForExpressionContext() {} func NewWaitForExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *WaitForExpressionContext { var p = new(WaitForExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_waitForExpression @@ -5321,36 +5673,24 @@ func (s *WaitForExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interf } func (p *FqlParser) WaitForExpression() (localctx IWaitForExpressionContext) { - this := p - _ = this - localctx = NewWaitForExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 54, FqlParserRULE_waitForExpression) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(342) p.Match(FqlParserWaitfor) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(343) p.Match(FqlParserEvent) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(344) @@ -5359,6 +5699,10 @@ func (p *FqlParser) WaitForExpression() (localctx IWaitForExpressionContext) { { p.SetState(345) p.Match(FqlParserIn) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(346) @@ -5367,35 +5711,51 @@ func (p *FqlParser) WaitForExpression() (localctx IWaitForExpressionContext) { p.SetState(348) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 25, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 25, p.GetParserRuleContext()) == 1 { { p.SetState(347) p.OptionsClause() } + } else if p.HasError() { // JIM + goto errorExit } p.SetState(351) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 26, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 26, p.GetParserRuleContext()) == 1 { { p.SetState(350) p.FilterClause() } + } else if p.HasError() { // JIM + goto errorExit } p.SetState(354) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 27, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 27, p.GetParserRuleContext()) == 1 { { p.SetState(353) p.TimeoutClause() } + } else if p.HasError() { // JIM + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IWaitForEventNameContext is an interface to support dynamic dispatch. @@ -5405,28 +5765,40 @@ type IWaitForEventNameContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + StringLiteral() IStringLiteralContext + Variable() IVariableContext + Param() IParamContext + FunctionCallExpression() IFunctionCallExpressionContext + MemberExpression() IMemberExpressionContext + // IsWaitForEventNameContext differentiates from other interfaces. IsWaitForEventNameContext() } type WaitForEventNameContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyWaitForEventNameContext() *WaitForEventNameContext { var p = new(WaitForEventNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_waitForEventName return p } +func InitEmptyWaitForEventNameContext(p *WaitForEventNameContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_waitForEventName +} + func (*WaitForEventNameContext) IsWaitForEventNameContext() {} func NewWaitForEventNameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *WaitForEventNameContext { var p = new(WaitForEventNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_waitForEventName @@ -5547,31 +5919,15 @@ func (s *WaitForEventNameContext) Accept(visitor antlr.ParseTreeVisitor) interfa } func (p *FqlParser) WaitForEventName() (localctx IWaitForEventNameContext) { - this := p - _ = this - localctx = NewWaitForEventNameContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 56, FqlParserRULE_waitForEventName) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(361) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 28, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 28, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -5607,9 +5963,21 @@ func (p *FqlParser) WaitForEventName() (localctx IWaitForEventNameContext) { p.MemberExpression() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IWaitForEventSourceContext is an interface to support dynamic dispatch. @@ -5619,28 +5987,38 @@ type IWaitForEventSourceContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + FunctionCallExpression() IFunctionCallExpressionContext + Variable() IVariableContext + MemberExpression() IMemberExpressionContext + // IsWaitForEventSourceContext differentiates from other interfaces. IsWaitForEventSourceContext() } type WaitForEventSourceContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyWaitForEventSourceContext() *WaitForEventSourceContext { var p = new(WaitForEventSourceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_waitForEventSource return p } +func InitEmptyWaitForEventSourceContext(p *WaitForEventSourceContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_waitForEventSource +} + func (*WaitForEventSourceContext) IsWaitForEventSourceContext() {} func NewWaitForEventSourceContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *WaitForEventSourceContext { var p = new(WaitForEventSourceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_waitForEventSource @@ -5729,31 +6107,15 @@ func (s *WaitForEventSourceContext) Accept(visitor antlr.ParseTreeVisitor) inter } func (p *FqlParser) WaitForEventSource() (localctx IWaitForEventSourceContext) { - this := p - _ = this - localctx = NewWaitForEventSourceContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 58, FqlParserRULE_waitForEventSource) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(366) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 29, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 29, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -5775,9 +6137,21 @@ func (p *FqlParser) WaitForEventSource() (localctx IWaitForEventSourceContext) { p.MemberExpression() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IOptionsClauseContext is an interface to support dynamic dispatch. @@ -5787,28 +6161,37 @@ type IOptionsClauseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Options() antlr.TerminalNode + ObjectLiteral() IObjectLiteralContext + // IsOptionsClauseContext differentiates from other interfaces. IsOptionsClauseContext() } type OptionsClauseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyOptionsClauseContext() *OptionsClauseContext { var p = new(OptionsClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_optionsClause return p } +func InitEmptyOptionsClauseContext(p *OptionsClauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_optionsClause +} + func (*OptionsClauseContext) IsOptionsClauseContext() {} func NewOptionsClauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OptionsClauseContext { var p = new(OptionsClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_optionsClause @@ -5869,39 +6252,33 @@ func (s *OptionsClauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) OptionsClause() (localctx IOptionsClauseContext) { - this := p - _ = this - localctx = NewOptionsClauseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 60, FqlParserRULE_optionsClause) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(368) p.Match(FqlParserOptions) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(369) p.ObjectLiteral() } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ITimeoutClauseContext is an interface to support dynamic dispatch. @@ -5911,28 +6288,41 @@ type ITimeoutClauseContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Timeout() antlr.TerminalNode + IntegerLiteral() IIntegerLiteralContext + Variable() IVariableContext + Param() IParamContext + MemberExpression() IMemberExpressionContext + FunctionCall() IFunctionCallContext + // IsTimeoutClauseContext differentiates from other interfaces. IsTimeoutClauseContext() } type TimeoutClauseContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyTimeoutClauseContext() *TimeoutClauseContext { var p = new(TimeoutClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_timeoutClause return p } +func InitEmptyTimeoutClauseContext(p *TimeoutClauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_timeoutClause +} + func (*TimeoutClauseContext) IsTimeoutClauseContext() {} func NewTimeoutClauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TimeoutClauseContext { var p = new(TimeoutClauseContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_timeoutClause @@ -6057,36 +6447,24 @@ func (s *TimeoutClauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) TimeoutClause() (localctx ITimeoutClauseContext) { - this := p - _ = this - localctx = NewTimeoutClauseContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 62, FqlParserRULE_timeoutClause) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(371) p.Match(FqlParserTimeout) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(377) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 30, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 30, p.GetParserRuleContext()) { case 1: { p.SetState(372) @@ -6117,9 +6495,21 @@ func (p *FqlParser) TimeoutClause() (localctx ITimeoutClauseContext) { p.FunctionCall() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IParamContext is an interface to support dynamic dispatch. @@ -6129,28 +6519,38 @@ type IParamContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Param() antlr.TerminalNode + Identifier() antlr.TerminalNode + SafeReservedWord() ISafeReservedWordContext + // IsParamContext differentiates from other interfaces. IsParamContext() } type ParamContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyParamContext() *ParamContext { var p = new(ParamContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_param return p } +func InitEmptyParamContext(p *ParamContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_param +} + func (*ParamContext) IsParamContext() {} func NewParamContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParamContext { var p = new(ParamContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_param @@ -6215,40 +6615,32 @@ func (s *ParamContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Param() (localctx IParamContext) { - this := p - _ = this - localctx = NewParamContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 64, FqlParserRULE_param) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(383) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 31, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 31, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { p.SetState(379) p.Match(FqlParserParam) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(380) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } case 2: @@ -6256,15 +6648,31 @@ func (p *FqlParser) Param() (localctx IParamContext) { { p.SetState(381) p.Match(FqlParserParam) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(382) p.SafeReservedWord() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IVariableContext is an interface to support dynamic dispatch. @@ -6274,28 +6682,37 @@ type IVariableContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Identifier() antlr.TerminalNode + SafeReservedWord() ISafeReservedWordContext + // IsVariableContext differentiates from other interfaces. IsVariableContext() } type VariableContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyVariableContext() *VariableContext { var p = new(VariableContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_variable return p } +func InitEmptyVariableContext(p *VariableContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_variable +} + func (*VariableContext) IsVariableContext() {} func NewVariableContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VariableContext { var p = new(VariableContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_variable @@ -6356,30 +6773,13 @@ func (s *VariableContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Variable() (localctx IVariableContext) { - this := p - _ = this - localctx = NewVariableContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 66, FqlParserRULE_variable) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(387) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserIdentifier: @@ -6387,6 +6787,10 @@ func (p *FqlParser) Variable() (localctx IVariableContext) { { p.SetState(385) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } case FqlParserAnd, FqlParserOr, FqlParserOptions, FqlParserTimeout, FqlParserDistinct, FqlParserFilter, FqlParserCurrent, FqlParserSort, FqlParserLimit, FqlParserCollect, FqlParserSortDirection, FqlParserInto, FqlParserKeep, FqlParserWith, FqlParserCount, FqlParserAll, FqlParserAny, FqlParserAggregate, FqlParserEvent: @@ -6397,10 +6801,21 @@ func (p *FqlParser) Variable() (localctx IVariableContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ILiteralContext is an interface to support dynamic dispatch. @@ -6410,28 +6825,42 @@ type ILiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + ArrayLiteral() IArrayLiteralContext + ObjectLiteral() IObjectLiteralContext + BooleanLiteral() IBooleanLiteralContext + StringLiteral() IStringLiteralContext + FloatLiteral() IFloatLiteralContext + IntegerLiteral() IIntegerLiteralContext + NoneLiteral() INoneLiteralContext + // IsLiteralContext differentiates from other interfaces. IsLiteralContext() } type LiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyLiteralContext() *LiteralContext { var p = new(LiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_literal return p } +func InitEmptyLiteralContext(p *LiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_literal +} + func (*LiteralContext) IsLiteralContext() {} func NewLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LiteralContext { var p = new(LiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_literal @@ -6584,30 +7013,13 @@ func (s *LiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Literal() (localctx ILiteralContext) { - this := p - _ = this - localctx = NewLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 68, FqlParserRULE_literal) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(396) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserOpenBracket: @@ -6660,10 +7072,21 @@ func (p *FqlParser) Literal() (localctx ILiteralContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IArrayLiteralContext is an interface to support dynamic dispatch. @@ -6673,28 +7096,38 @@ type IArrayLiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + OpenBracket() antlr.TerminalNode + CloseBracket() antlr.TerminalNode + ArgumentList() IArgumentListContext + // IsArrayLiteralContext differentiates from other interfaces. IsArrayLiteralContext() } type ArrayLiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyArrayLiteralContext() *ArrayLiteralContext { var p = new(ArrayLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_arrayLiteral return p } +func InitEmptyArrayLiteralContext(p *ArrayLiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_arrayLiteral +} + func (*ArrayLiteralContext) IsArrayLiteralContext() {} func NewArrayLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ArrayLiteralContext { var p = new(ArrayLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_arrayLiteral @@ -6759,36 +7192,24 @@ func (s *ArrayLiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) ArrayLiteral() (localctx IArrayLiteralContext) { - this := p - _ = this - localctx = NewArrayLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 70, FqlParserRULE_arrayLiteral) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(398) p.Match(FqlParserOpenBracket) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(400) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if (int64((_la-9)) & ^0x3f) == 0 && ((int64(1)<<(_la-9))&8935141660637626389) != 0 { @@ -6801,9 +7222,23 @@ func (p *FqlParser) ArrayLiteral() (localctx IArrayLiteralContext) { { p.SetState(402) p.Match(FqlParserCloseBracket) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IObjectLiteralContext is an interface to support dynamic dispatch. @@ -6813,28 +7248,41 @@ type IObjectLiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + OpenBrace() antlr.TerminalNode + CloseBrace() antlr.TerminalNode + AllPropertyAssignment() []IPropertyAssignmentContext + PropertyAssignment(i int) IPropertyAssignmentContext + AllComma() []antlr.TerminalNode + Comma(i int) antlr.TerminalNode + // IsObjectLiteralContext differentiates from other interfaces. IsObjectLiteralContext() } type ObjectLiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyObjectLiteralContext() *ObjectLiteralContext { var p = new(ObjectLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_objectLiteral return p } +func InitEmptyObjectLiteralContext(p *ObjectLiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_objectLiteral +} + func (*ObjectLiteralContext) IsObjectLiteralContext() {} func NewObjectLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ObjectLiteralContext { var p = new(ObjectLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_objectLiteral @@ -6932,38 +7380,26 @@ func (s *ObjectLiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) ObjectLiteral() (localctx IObjectLiteralContext) { - this := p - _ = this - localctx = NewObjectLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 72, FqlParserRULE_objectLiteral) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) { p.SetState(404) p.Match(FqlParserOpenBrace) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(416) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if (int64((_la-9)) & ^0x3f) == 0 && ((int64(1)<<(_la-9))&864691128389599233) != 0 { @@ -6973,13 +7409,22 @@ func (p *FqlParser) ObjectLiteral() (localctx IObjectLiteralContext) { } p.SetState(410) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 35, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 35, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { p.SetState(406) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(407) @@ -6989,16 +7434,29 @@ func (p *FqlParser) ObjectLiteral() (localctx IObjectLiteralContext) { } p.SetState(412) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 35, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 35, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } p.SetState(414) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserComma { { p.SetState(413) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } } @@ -7007,9 +7465,23 @@ func (p *FqlParser) ObjectLiteral() (localctx IObjectLiteralContext) { { p.SetState(418) p.Match(FqlParserCloseBrace) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IBooleanLiteralContext is an interface to support dynamic dispatch. @@ -7019,28 +7491,36 @@ type IBooleanLiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + BooleanLiteral() antlr.TerminalNode + // IsBooleanLiteralContext differentiates from other interfaces. IsBooleanLiteralContext() } type BooleanLiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyBooleanLiteralContext() *BooleanLiteralContext { var p = new(BooleanLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_booleanLiteral return p } +func InitEmptyBooleanLiteralContext(p *BooleanLiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_booleanLiteral +} + func (*BooleanLiteralContext) IsBooleanLiteralContext() {} func NewBooleanLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *BooleanLiteralContext { var p = new(BooleanLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_booleanLiteral @@ -7085,35 +7565,29 @@ func (s *BooleanLiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface } func (p *FqlParser) BooleanLiteral() (localctx IBooleanLiteralContext) { - this := p - _ = this - localctx = NewBooleanLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 74, FqlParserRULE_booleanLiteral) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(420) p.Match(FqlParserBooleanLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IStringLiteralContext is an interface to support dynamic dispatch. @@ -7123,28 +7597,36 @@ type IStringLiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + StringLiteral() antlr.TerminalNode + // IsStringLiteralContext differentiates from other interfaces. IsStringLiteralContext() } type StringLiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyStringLiteralContext() *StringLiteralContext { var p = new(StringLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_stringLiteral return p } +func InitEmptyStringLiteralContext(p *StringLiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_stringLiteral +} + func (*StringLiteralContext) IsStringLiteralContext() {} func NewStringLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StringLiteralContext { var p = new(StringLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_stringLiteral @@ -7189,35 +7671,29 @@ func (s *StringLiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) StringLiteral() (localctx IStringLiteralContext) { - this := p - _ = this - localctx = NewStringLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 76, FqlParserRULE_stringLiteral) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(422) p.Match(FqlParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IFloatLiteralContext is an interface to support dynamic dispatch. @@ -7227,28 +7703,36 @@ type IFloatLiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + FloatLiteral() antlr.TerminalNode + // IsFloatLiteralContext differentiates from other interfaces. IsFloatLiteralContext() } type FloatLiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyFloatLiteralContext() *FloatLiteralContext { var p = new(FloatLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_floatLiteral return p } +func InitEmptyFloatLiteralContext(p *FloatLiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_floatLiteral +} + func (*FloatLiteralContext) IsFloatLiteralContext() {} func NewFloatLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FloatLiteralContext { var p = new(FloatLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_floatLiteral @@ -7293,35 +7777,29 @@ func (s *FloatLiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) FloatLiteral() (localctx IFloatLiteralContext) { - this := p - _ = this - localctx = NewFloatLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 78, FqlParserRULE_floatLiteral) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(424) p.Match(FqlParserFloatLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IIntegerLiteralContext is an interface to support dynamic dispatch. @@ -7331,28 +7809,36 @@ type IIntegerLiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + IntegerLiteral() antlr.TerminalNode + // IsIntegerLiteralContext differentiates from other interfaces. IsIntegerLiteralContext() } type IntegerLiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyIntegerLiteralContext() *IntegerLiteralContext { var p = new(IntegerLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_integerLiteral return p } +func InitEmptyIntegerLiteralContext(p *IntegerLiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_integerLiteral +} + func (*IntegerLiteralContext) IsIntegerLiteralContext() {} func NewIntegerLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *IntegerLiteralContext { var p = new(IntegerLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_integerLiteral @@ -7397,35 +7883,29 @@ func (s *IntegerLiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface } func (p *FqlParser) IntegerLiteral() (localctx IIntegerLiteralContext) { - this := p - _ = this - localctx = NewIntegerLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 80, FqlParserRULE_integerLiteral) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(426) p.Match(FqlParserIntegerLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // INoneLiteralContext is an interface to support dynamic dispatch. @@ -7435,28 +7915,37 @@ type INoneLiteralContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Null() antlr.TerminalNode + None() antlr.TerminalNode + // IsNoneLiteralContext differentiates from other interfaces. IsNoneLiteralContext() } type NoneLiteralContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyNoneLiteralContext() *NoneLiteralContext { var p = new(NoneLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_noneLiteral return p } +func InitEmptyNoneLiteralContext(p *NoneLiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_noneLiteral +} + func (*NoneLiteralContext) IsNoneLiteralContext() {} func NewNoneLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NoneLiteralContext { var p = new(NoneLiteralContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_noneLiteral @@ -7505,29 +7994,10 @@ func (s *NoneLiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) NoneLiteral() (localctx INoneLiteralContext) { - this := p - _ = this - localctx = NewNoneLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 82, FqlParserRULE_noneLiteral) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(428) @@ -7541,7 +8011,17 @@ func (p *FqlParser) NoneLiteral() (localctx INoneLiteralContext) { } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IPropertyAssignmentContext is an interface to support dynamic dispatch. @@ -7551,28 +8031,40 @@ type IPropertyAssignmentContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + PropertyName() IPropertyNameContext + Colon() antlr.TerminalNode + Expression() IExpressionContext + ComputedPropertyName() IComputedPropertyNameContext + Variable() IVariableContext + // IsPropertyAssignmentContext differentiates from other interfaces. IsPropertyAssignmentContext() } type PropertyAssignmentContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyPropertyAssignmentContext() *PropertyAssignmentContext { var p = new(PropertyAssignmentContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_propertyAssignment return p } +func InitEmptyPropertyAssignmentContext(p *PropertyAssignmentContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_propertyAssignment +} + func (*PropertyAssignmentContext) IsPropertyAssignmentContext() {} func NewPropertyAssignmentContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PropertyAssignmentContext { var p = new(PropertyAssignmentContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_propertyAssignment @@ -7681,31 +8173,15 @@ func (s *PropertyAssignmentContext) Accept(visitor antlr.ParseTreeVisitor) inter } func (p *FqlParser) PropertyAssignment() (localctx IPropertyAssignmentContext) { - this := p - _ = this - localctx = NewPropertyAssignmentContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 84, FqlParserRULE_propertyAssignment) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(439) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 38, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 38, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -7715,6 +8191,10 @@ func (p *FqlParser) PropertyAssignment() (localctx IPropertyAssignmentContext) { { p.SetState(431) p.Match(FqlParserColon) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(432) @@ -7730,6 +8210,10 @@ func (p *FqlParser) PropertyAssignment() (localctx IPropertyAssignmentContext) { { p.SetState(435) p.Match(FqlParserColon) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(436) @@ -7743,9 +8227,21 @@ func (p *FqlParser) PropertyAssignment() (localctx IPropertyAssignmentContext) { p.Variable() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IComputedPropertyNameContext is an interface to support dynamic dispatch. @@ -7755,28 +8251,38 @@ type IComputedPropertyNameContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + OpenBracket() antlr.TerminalNode + Expression() IExpressionContext + CloseBracket() antlr.TerminalNode + // IsComputedPropertyNameContext differentiates from other interfaces. IsComputedPropertyNameContext() } type ComputedPropertyNameContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyComputedPropertyNameContext() *ComputedPropertyNameContext { var p = new(ComputedPropertyNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_computedPropertyName return p } +func InitEmptyComputedPropertyNameContext(p *ComputedPropertyNameContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_computedPropertyName +} + func (*ComputedPropertyNameContext) IsComputedPropertyNameContext() {} func NewComputedPropertyNameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ComputedPropertyNameContext { var p = new(ComputedPropertyNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_computedPropertyName @@ -7841,32 +8347,16 @@ func (s *ComputedPropertyNameContext) Accept(visitor antlr.ParseTreeVisitor) int } func (p *FqlParser) ComputedPropertyName() (localctx IComputedPropertyNameContext) { - this := p - _ = this - localctx = NewComputedPropertyNameContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 86, FqlParserRULE_computedPropertyName) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(441) p.Match(FqlParserOpenBracket) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(442) @@ -7875,9 +8365,23 @@ func (p *FqlParser) ComputedPropertyName() (localctx IComputedPropertyNameContex { p.SetState(443) p.Match(FqlParserCloseBracket) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IPropertyNameContext is an interface to support dynamic dispatch. @@ -7887,28 +8391,40 @@ type IPropertyNameContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Identifier() antlr.TerminalNode + StringLiteral() IStringLiteralContext + Param() IParamContext + SafeReservedWord() ISafeReservedWordContext + UnsafeReservedWord() IUnsafeReservedWordContext + // IsPropertyNameContext differentiates from other interfaces. IsPropertyNameContext() } type PropertyNameContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyPropertyNameContext() *PropertyNameContext { var p = new(PropertyNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_propertyName return p } +func InitEmptyPropertyNameContext(p *PropertyNameContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_propertyName +} + func (*PropertyNameContext) IsPropertyNameContext() {} func NewPropertyNameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PropertyNameContext { var p = new(PropertyNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_propertyName @@ -8017,30 +8533,13 @@ func (s *PropertyNameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) PropertyName() (localctx IPropertyNameContext) { - this := p - _ = this - localctx = NewPropertyNameContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 88, FqlParserRULE_propertyName) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(450) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserIdentifier: @@ -8048,6 +8547,10 @@ func (p *FqlParser) PropertyName() (localctx IPropertyNameContext) { { p.SetState(445) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } case FqlParserStringLiteral: @@ -8079,10 +8582,21 @@ func (p *FqlParser) PropertyName() (localctx IPropertyNameContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // INamespaceIdentifierContext is an interface to support dynamic dispatch. @@ -8092,28 +8606,37 @@ type INamespaceIdentifierContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Namespace() INamespaceContext + Identifier() antlr.TerminalNode + // IsNamespaceIdentifierContext differentiates from other interfaces. IsNamespaceIdentifierContext() } type NamespaceIdentifierContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyNamespaceIdentifierContext() *NamespaceIdentifierContext { var p = new(NamespaceIdentifierContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_namespaceIdentifier return p } +func InitEmptyNamespaceIdentifierContext(p *NamespaceIdentifierContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_namespaceIdentifier +} + func (*NamespaceIdentifierContext) IsNamespaceIdentifierContext() {} func NewNamespaceIdentifierContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NamespaceIdentifierContext { var p = new(NamespaceIdentifierContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_namespaceIdentifier @@ -8174,28 +8697,8 @@ func (s *NamespaceIdentifierContext) Accept(visitor antlr.ParseTreeVisitor) inte } func (p *FqlParser) NamespaceIdentifier() (localctx INamespaceIdentifierContext) { - this := p - _ = this - localctx = NewNamespaceIdentifierContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 90, FqlParserRULE_namespaceIdentifier) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(452) @@ -8204,9 +8707,23 @@ func (p *FqlParser) NamespaceIdentifier() (localctx INamespaceIdentifierContext) { p.SetState(453) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // INamespaceContext is an interface to support dynamic dispatch. @@ -8216,28 +8733,37 @@ type INamespaceContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + AllNamespaceSegment() []antlr.TerminalNode + NamespaceSegment(i int) antlr.TerminalNode + // IsNamespaceContext differentiates from other interfaces. IsNamespaceContext() } type NamespaceContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyNamespaceContext() *NamespaceContext { var p = new(NamespaceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_namespace return p } +func InitEmptyNamespaceContext(p *NamespaceContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_namespace +} + func (*NamespaceContext) IsNamespaceContext() {} func NewNamespaceContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NamespaceContext { var p = new(NamespaceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_namespace @@ -8286,46 +8812,47 @@ func (s *NamespaceContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) Namespace() (localctx INamespaceContext) { - this := p - _ = this - localctx = NewNamespaceContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 92, FqlParserRULE_namespace) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) p.SetState(458) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) for _la == FqlParserNamespaceSegment { { p.SetState(455) p.Match(FqlParserNamespaceSegment) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(460) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IMemberExpressionContext is an interface to support dynamic dispatch. @@ -8335,28 +8862,38 @@ type IMemberExpressionContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + MemberExpressionSource() IMemberExpressionSourceContext + AllMemberExpressionPath() []IMemberExpressionPathContext + MemberExpressionPath(i int) IMemberExpressionPathContext + // IsMemberExpressionContext differentiates from other interfaces. IsMemberExpressionContext() } type MemberExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyMemberExpressionContext() *MemberExpressionContext { var p = new(MemberExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_memberExpression return p } +func InitEmptyMemberExpressionContext(p *MemberExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_memberExpression +} + func (*MemberExpressionContext) IsMemberExpressionContext() {} func NewMemberExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MemberExpressionContext { var p = new(MemberExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_memberExpression @@ -8454,28 +8991,8 @@ func (s *MemberExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interfa } func (p *FqlParser) MemberExpression() (localctx IMemberExpressionContext) { - this := p - _ = this - localctx = NewMemberExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 94, FqlParserRULE_memberExpression) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) @@ -8485,6 +9002,9 @@ func (p *FqlParser) MemberExpression() (localctx IMemberExpressionContext) { } p.SetState(463) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _alt = 1 for ok := true; ok; ok = _alt != 2 && _alt != antlr.ATNInvalidAltNumber { switch _alt { @@ -8495,15 +9015,29 @@ func (p *FqlParser) MemberExpression() (localctx IMemberExpressionContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } p.SetState(465) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 41, p.GetParserRuleContext()) + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 41, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IMemberExpressionSourceContext is an interface to support dynamic dispatch. @@ -8513,28 +9047,40 @@ type IMemberExpressionSourceContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Variable() IVariableContext + Param() IParamContext + ArrayLiteral() IArrayLiteralContext + ObjectLiteral() IObjectLiteralContext + FunctionCall() IFunctionCallContext + // IsMemberExpressionSourceContext differentiates from other interfaces. IsMemberExpressionSourceContext() } type MemberExpressionSourceContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyMemberExpressionSourceContext() *MemberExpressionSourceContext { var p = new(MemberExpressionSourceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_memberExpressionSource return p } +func InitEmptyMemberExpressionSourceContext(p *MemberExpressionSourceContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_memberExpressionSource +} + func (*MemberExpressionSourceContext) IsMemberExpressionSourceContext() {} func NewMemberExpressionSourceContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MemberExpressionSourceContext { var p = new(MemberExpressionSourceContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_memberExpressionSource @@ -8655,31 +9201,15 @@ func (s *MemberExpressionSourceContext) Accept(visitor antlr.ParseTreeVisitor) i } func (p *FqlParser) MemberExpressionSource() (localctx IMemberExpressionSourceContext) { - this := p - _ = this - localctx = NewMemberExpressionSourceContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 96, FqlParserRULE_memberExpressionSource) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(472) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 42, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 42, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { @@ -8715,9 +9245,21 @@ func (p *FqlParser) MemberExpressionSource() (localctx IMemberExpressionSourceCo p.FunctionCall() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IFunctionCallExpressionContext is an interface to support dynamic dispatch. @@ -8727,28 +9269,37 @@ type IFunctionCallExpressionContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + FunctionCall() IFunctionCallContext + ErrorOperator() IErrorOperatorContext + // IsFunctionCallExpressionContext differentiates from other interfaces. IsFunctionCallExpressionContext() } type FunctionCallExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyFunctionCallExpressionContext() *FunctionCallExpressionContext { var p = new(FunctionCallExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_functionCallExpression return p } +func InitEmptyFunctionCallExpressionContext(p *FunctionCallExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_functionCallExpression +} + func (*FunctionCallExpressionContext) IsFunctionCallExpressionContext() {} func NewFunctionCallExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FunctionCallExpressionContext { var p = new(FunctionCallExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_functionCallExpression @@ -8821,28 +9372,8 @@ func (s *FunctionCallExpressionContext) Accept(visitor antlr.ParseTreeVisitor) i } func (p *FqlParser) FunctionCallExpression() (localctx IFunctionCallExpressionContext) { - this := p - _ = this - localctx = NewFunctionCallExpressionContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 98, FqlParserRULE_functionCallExpression) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(474) @@ -8851,15 +9382,27 @@ func (p *FqlParser) FunctionCallExpression() (localctx IFunctionCallExpressionCo p.SetState(476) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 43, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 43, p.GetParserRuleContext()) == 1 { { p.SetState(475) p.ErrorOperator() } + } else if p.HasError() { // JIM + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IFunctionCallContext is an interface to support dynamic dispatch. @@ -8869,28 +9412,40 @@ type IFunctionCallContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Namespace() INamespaceContext + FunctionName() IFunctionNameContext + OpenParen() antlr.TerminalNode + CloseParen() antlr.TerminalNode + ArgumentList() IArgumentListContext + // IsFunctionCallContext differentiates from other interfaces. IsFunctionCallContext() } type FunctionCallContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyFunctionCallContext() *FunctionCallContext { var p = new(FunctionCallContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_functionCall return p } +func InitEmptyFunctionCallContext(p *FunctionCallContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_functionCall +} + func (*FunctionCallContext) IsFunctionCallContext() {} func NewFunctionCallContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FunctionCallContext { var p = new(FunctionCallContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_functionCall @@ -8987,29 +9542,10 @@ func (s *FunctionCallContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) FunctionCall() (localctx IFunctionCallContext) { - this := p - _ = this - localctx = NewFunctionCallContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 100, FqlParserRULE_functionCall) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(478) @@ -9022,9 +9558,16 @@ func (p *FqlParser) FunctionCall() (localctx IFunctionCallContext) { { p.SetState(480) p.Match(FqlParserOpenParen) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(482) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if (int64((_la-9)) & ^0x3f) == 0 && ((int64(1)<<(_la-9))&8935141660637626389) != 0 { @@ -9037,9 +9580,23 @@ func (p *FqlParser) FunctionCall() (localctx IFunctionCallContext) { { p.SetState(484) p.Match(FqlParserCloseParen) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IFunctionNameContext is an interface to support dynamic dispatch. @@ -9049,28 +9606,38 @@ type IFunctionNameContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Identifier() antlr.TerminalNode + SafeReservedWord() ISafeReservedWordContext + UnsafeReservedWord() IUnsafeReservedWordContext + // IsFunctionNameContext differentiates from other interfaces. IsFunctionNameContext() } type FunctionNameContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyFunctionNameContext() *FunctionNameContext { var p = new(FunctionNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_functionName return p } +func InitEmptyFunctionNameContext(p *FunctionNameContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_functionName +} + func (*FunctionNameContext) IsFunctionNameContext() {} func NewFunctionNameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FunctionNameContext { var p = new(FunctionNameContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_functionName @@ -9147,30 +9714,13 @@ func (s *FunctionNameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) FunctionName() (localctx IFunctionNameContext) { - this := p - _ = this - localctx = NewFunctionNameContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 102, FqlParserRULE_functionName) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(489) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserIdentifier: @@ -9178,6 +9728,10 @@ func (p *FqlParser) FunctionName() (localctx IFunctionNameContext) { { p.SetState(486) p.Match(FqlParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } case FqlParserAnd, FqlParserOr, FqlParserOptions, FqlParserTimeout, FqlParserDistinct, FqlParserFilter, FqlParserCurrent, FqlParserSort, FqlParserLimit, FqlParserCollect, FqlParserSortDirection, FqlParserInto, FqlParserKeep, FqlParserWith, FqlParserCount, FqlParserAll, FqlParserAny, FqlParserAggregate, FqlParserEvent: @@ -9195,10 +9749,21 @@ func (p *FqlParser) FunctionName() (localctx IFunctionNameContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IArgumentListContext is an interface to support dynamic dispatch. @@ -9208,28 +9773,39 @@ type IArgumentListContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + AllExpression() []IExpressionContext + Expression(i int) IExpressionContext + AllComma() []antlr.TerminalNode + Comma(i int) antlr.TerminalNode + // IsArgumentListContext differentiates from other interfaces. IsArgumentListContext() } type ArgumentListContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyArgumentListContext() *ArgumentListContext { var p = new(ArgumentListContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_argumentList return p } +func InitEmptyArgumentListContext(p *ArgumentListContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_argumentList +} + func (*ArgumentListContext) IsArgumentListContext() {} func NewArgumentListContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ArgumentListContext { var p = new(ArgumentListContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_argumentList @@ -9319,29 +9895,10 @@ func (s *ArgumentListContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) ArgumentList() (localctx IArgumentListContext) { - this := p - _ = this - localctx = NewArgumentListContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 104, FqlParserRULE_argumentList) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) @@ -9351,13 +9908,22 @@ func (p *FqlParser) ArgumentList() (localctx IArgumentListContext) { } p.SetState(496) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 46, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 46, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { p.SetState(492) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(493) @@ -9367,21 +9933,44 @@ func (p *FqlParser) ArgumentList() (localctx IArgumentListContext) { } p.SetState(498) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 46, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 46, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } p.SetState(500) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserComma { { p.SetState(499) p.Match(FqlParserComma) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IMemberExpressionPathContext is an interface to support dynamic dispatch. @@ -9391,28 +9980,39 @@ type IMemberExpressionPathContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Dot() antlr.TerminalNode + PropertyName() IPropertyNameContext + ErrorOperator() IErrorOperatorContext + ComputedPropertyName() IComputedPropertyNameContext + // IsMemberExpressionPathContext differentiates from other interfaces. IsMemberExpressionPathContext() } type MemberExpressionPathContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyMemberExpressionPathContext() *MemberExpressionPathContext { var p = new(MemberExpressionPathContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_memberExpressionPath return p } +func InitEmptyMemberExpressionPathContext(p *MemberExpressionPathContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_memberExpressionPath +} + func (*MemberExpressionPathContext) IsMemberExpressionPathContext() {} func NewMemberExpressionPathContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MemberExpressionPathContext { var p = new(MemberExpressionPathContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_memberExpressionPath @@ -9505,36 +10105,24 @@ func (s *MemberExpressionPathContext) Accept(visitor antlr.ParseTreeVisitor) int } func (p *FqlParser) MemberExpressionPath() (localctx IMemberExpressionPathContext) { - this := p - _ = this - localctx = NewMemberExpressionPathContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 106, FqlParserRULE_memberExpressionPath) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(513) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 50, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 50, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) p.SetState(503) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserQuestionMark { @@ -9547,6 +10135,10 @@ func (p *FqlParser) MemberExpressionPath() (localctx IMemberExpressionPathContex { p.SetState(505) p.Match(FqlParserDot) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(506) @@ -9557,6 +10149,9 @@ func (p *FqlParser) MemberExpressionPath() (localctx IMemberExpressionPathContex p.EnterOuterAlt(localctx, 2) p.SetState(510) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserQuestionMark { @@ -9567,6 +10162,10 @@ func (p *FqlParser) MemberExpressionPath() (localctx IMemberExpressionPathContex { p.SetState(508) p.Match(FqlParserDot) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } } @@ -9575,9 +10174,21 @@ func (p *FqlParser) MemberExpressionPath() (localctx IMemberExpressionPathContex p.ComputedPropertyName() } + case antlr.ATNInvalidAltNumber: + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ISafeReservedWordContext is an interface to support dynamic dispatch. @@ -9587,28 +10198,54 @@ type ISafeReservedWordContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + And() antlr.TerminalNode + Or() antlr.TerminalNode + Distinct() antlr.TerminalNode + Filter() antlr.TerminalNode + Sort() antlr.TerminalNode + Limit() antlr.TerminalNode + Collect() antlr.TerminalNode + SortDirection() antlr.TerminalNode + Into() antlr.TerminalNode + Keep() antlr.TerminalNode + With() antlr.TerminalNode + Count() antlr.TerminalNode + All() antlr.TerminalNode + Any() antlr.TerminalNode + Aggregate() antlr.TerminalNode + Event() antlr.TerminalNode + Timeout() antlr.TerminalNode + Options() antlr.TerminalNode + Current() antlr.TerminalNode + // IsSafeReservedWordContext differentiates from other interfaces. IsSafeReservedWordContext() } type SafeReservedWordContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptySafeReservedWordContext() *SafeReservedWordContext { var p = new(SafeReservedWordContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_safeReservedWord return p } +func InitEmptySafeReservedWordContext(p *SafeReservedWordContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_safeReservedWord +} + func (*SafeReservedWordContext) IsSafeReservedWordContext() {} func NewSafeReservedWordContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SafeReservedWordContext { var p = new(SafeReservedWordContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_safeReservedWord @@ -9725,29 +10362,10 @@ func (s *SafeReservedWordContext) Accept(visitor antlr.ParseTreeVisitor) interfa } func (p *FqlParser) SafeReservedWord() (localctx ISafeReservedWordContext) { - this := p - _ = this - localctx = NewSafeReservedWordContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 108, FqlParserRULE_safeReservedWord) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(515) @@ -9761,7 +10379,17 @@ func (p *FqlParser) SafeReservedWord() (localctx ISafeReservedWordContext) { } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IUnsafeReservedWordContext is an interface to support dynamic dispatch. @@ -9771,28 +10399,48 @@ type IUnsafeReservedWordContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Return() antlr.TerminalNode + None() antlr.TerminalNode + Null() antlr.TerminalNode + Let() antlr.TerminalNode + Use() antlr.TerminalNode + Waitfor() antlr.TerminalNode + While() antlr.TerminalNode + Do() antlr.TerminalNode + In() antlr.TerminalNode + Like() antlr.TerminalNode + Not() antlr.TerminalNode + For() antlr.TerminalNode + BooleanLiteral() antlr.TerminalNode + // IsUnsafeReservedWordContext differentiates from other interfaces. IsUnsafeReservedWordContext() } type UnsafeReservedWordContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyUnsafeReservedWordContext() *UnsafeReservedWordContext { var p = new(UnsafeReservedWordContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_unsafeReservedWord return p } +func InitEmptyUnsafeReservedWordContext(p *UnsafeReservedWordContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_unsafeReservedWord +} + func (*UnsafeReservedWordContext) IsUnsafeReservedWordContext() {} func NewUnsafeReservedWordContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UnsafeReservedWordContext { var p = new(UnsafeReservedWordContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_unsafeReservedWord @@ -9885,29 +10533,10 @@ func (s *UnsafeReservedWordContext) Accept(visitor antlr.ParseTreeVisitor) inter } func (p *FqlParser) UnsafeReservedWord() (localctx IUnsafeReservedWordContext) { - this := p - _ = this - localctx = NewUnsafeReservedWordContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 110, FqlParserRULE_unsafeReservedWord) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(517) @@ -9921,7 +10550,17 @@ func (p *FqlParser) UnsafeReservedWord() (localctx IUnsafeReservedWordContext) { } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IRangeOperatorContext is an interface to support dynamic dispatch. @@ -9943,12 +10582,17 @@ type IRangeOperatorContext interface { // SetRight sets the right rule contexts. SetRight(IRangeOperandContext) + // Getter signatures + Range() antlr.TerminalNode + AllRangeOperand() []IRangeOperandContext + RangeOperand(i int) IRangeOperandContext + // IsRangeOperatorContext differentiates from other interfaces. IsRangeOperatorContext() } type RangeOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser left IRangeOperandContext right IRangeOperandContext @@ -9956,17 +10600,22 @@ type RangeOperatorContext struct { func NewEmptyRangeOperatorContext() *RangeOperatorContext { var p = new(RangeOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_rangeOperator return p } +func InitEmptyRangeOperatorContext(p *RangeOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_rangeOperator +} + func (*RangeOperatorContext) IsRangeOperatorContext() {} func NewRangeOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RangeOperatorContext { var p = new(RangeOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_rangeOperator @@ -10060,28 +10709,8 @@ func (s *RangeOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) RangeOperator() (localctx IRangeOperatorContext) { - this := p - _ = this - localctx = NewRangeOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 112, FqlParserRULE_rangeOperator) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(519) @@ -10093,6 +10722,10 @@ func (p *FqlParser) RangeOperator() (localctx IRangeOperatorContext) { { p.SetState(520) p.Match(FqlParserRange) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(521) @@ -10102,7 +10735,17 @@ func (p *FqlParser) RangeOperator() (localctx IRangeOperatorContext) { localctx.(*RangeOperatorContext).right = _x } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IRangeOperandContext is an interface to support dynamic dispatch. @@ -10112,28 +10755,38 @@ type IRangeOperandContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + IntegerLiteral() IIntegerLiteralContext + Variable() IVariableContext + Param() IParamContext + // IsRangeOperandContext differentiates from other interfaces. IsRangeOperandContext() } type RangeOperandContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyRangeOperandContext() *RangeOperandContext { var p = new(RangeOperandContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_rangeOperand return p } +func InitEmptyRangeOperandContext(p *RangeOperandContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_rangeOperand +} + func (*RangeOperandContext) IsRangeOperandContext() {} func NewRangeOperandContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RangeOperandContext { var p = new(RangeOperandContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_rangeOperand @@ -10222,30 +10875,13 @@ func (s *RangeOperandContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) RangeOperand() (localctx IRangeOperandContext) { - this := p - _ = this - localctx = NewRangeOperandContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 114, FqlParserRULE_rangeOperand) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.SetState(526) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserIntegerLiteral: @@ -10270,10 +10906,21 @@ func (p *FqlParser) RangeOperand() (localctx IRangeOperandContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IExpressionContext is an interface to support dynamic dispatch. @@ -10319,12 +10966,22 @@ type IExpressionContext interface { // SetOnFalse sets the onFalse rule contexts. SetOnFalse(IExpressionContext) + // Getter signatures + UnaryOperator() IUnaryOperatorContext + AllExpression() []IExpressionContext + Expression(i int) IExpressionContext + Predicate() IPredicateContext + LogicalAndOperator() ILogicalAndOperatorContext + LogicalOrOperator() ILogicalOrOperatorContext + Colon() antlr.TerminalNode + QuestionMark() antlr.TerminalNode + // IsExpressionContext differentiates from other interfaces. IsExpressionContext() } type ExpressionContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser left IExpressionContext condition IExpressionContext @@ -10336,17 +10993,22 @@ type ExpressionContext struct { func NewEmptyExpressionContext() *ExpressionContext { var p = new(ExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_expression return p } +func InitEmptyExpressionContext(p *ExpressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_expression +} + func (*ExpressionContext) IsExpressionContext() {} func NewExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionContext { var p = new(ExpressionContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_expression @@ -10528,10 +11190,8 @@ func (p *FqlParser) Expression() (localctx IExpressionContext) { } func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { - this := p - _ = this - var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + _parentState := p.GetState() localctx = NewExpressionContext(p, p.GetParserRuleContext(), _parentState) var _prevctx IExpressionContext = localctx @@ -10540,28 +11200,16 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { p.EnterRecursionRule(localctx, 116, FqlParserRULE_expression, _p) var _la int - defer func() { - p.UnrollRecursionContexts(_parentctx) - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) p.SetState(533) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 52, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 52, p.GetParserRuleContext()) { case 1: { p.SetState(529) @@ -10581,12 +11229,19 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { p.predicate(0) } + case antlr.ATNInvalidAltNumber: + goto errorExit } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) p.SetState(552) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 55, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 55, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { if p.GetParseListeners() != nil { @@ -10595,7 +11250,11 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { _prevctx = localctx p.SetState(550) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 54, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 54, p.GetParserRuleContext()) { case 1: localctx = NewExpressionContext(p, _parentctx, _parentState) localctx.(*ExpressionContext).left = _prevctx @@ -10603,7 +11262,8 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { p.SetState(535) if !(p.Precpred(p.GetParserRuleContext(), 4)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) + goto errorExit } { p.SetState(536) @@ -10624,7 +11284,8 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { p.SetState(539) if !(p.Precpred(p.GetParserRuleContext(), 3)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) + goto errorExit } { p.SetState(540) @@ -10645,7 +11306,8 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { p.SetState(543) if !(p.Precpred(p.GetParserRuleContext(), 2)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) + goto errorExit } { p.SetState(544) @@ -10653,9 +11315,16 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { var _m = p.Match(FqlParserQuestionMark) localctx.(*ExpressionContext).ternaryOperator = _m + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(546) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if (int64((_la-9)) & ^0x3f) == 0 && ((int64(1)<<(_la-9))&8935141660637626389) != 0 { @@ -10671,6 +11340,10 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { { p.SetState(548) p.Match(FqlParserColon) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(549) @@ -10680,15 +11353,33 @@ func (p *FqlParser) expression(_p int) (localctx IExpressionContext) { localctx.(*ExpressionContext).onFalse = _x } + case antlr.ATNInvalidAltNumber: + goto errorExit } } p.SetState(554) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 55, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 55, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.UnrollRecursionContexts(_parentctx) return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IPredicateContext is an interface to support dynamic dispatch. @@ -10710,12 +11401,21 @@ type IPredicateContext interface { // SetRight sets the right rule contexts. SetRight(IPredicateContext) + // Getter signatures + ExpressionAtom() IExpressionAtomContext + EqualityOperator() IEqualityOperatorContext + AllPredicate() []IPredicateContext + Predicate(i int) IPredicateContext + ArrayOperator() IArrayOperatorContext + InOperator() IInOperatorContext + LikeOperator() ILikeOperatorContext + // IsPredicateContext differentiates from other interfaces. IsPredicateContext() } type PredicateContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser left IPredicateContext right IPredicateContext @@ -10723,17 +11423,22 @@ type PredicateContext struct { func NewEmptyPredicateContext() *PredicateContext { var p = new(PredicateContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_predicate return p } +func InitEmptyPredicateContext(p *PredicateContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_predicate +} + func (*PredicateContext) IsPredicateContext() {} func NewPredicateContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PredicateContext { var p = new(PredicateContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_predicate @@ -10907,33 +11612,14 @@ func (p *FqlParser) Predicate() (localctx IPredicateContext) { } func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { - this := p - _ = this - var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + _parentState := p.GetState() localctx = NewPredicateContext(p, p.GetParserRuleContext(), _parentState) var _prevctx IPredicateContext = localctx var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. _startState := 118 p.EnterRecursionRule(localctx, 118, FqlParserRULE_predicate, _p) - - defer func() { - p.UnrollRecursionContexts(_parentctx) - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) @@ -10945,8 +11631,13 @@ func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) p.SetState(576) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 57, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 57, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { if p.GetParseListeners() != nil { @@ -10955,7 +11646,11 @@ func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { _prevctx = localctx p.SetState(574) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 56, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 56, p.GetParserRuleContext()) { case 1: localctx = NewPredicateContext(p, _parentctx, _parentState) localctx.(*PredicateContext).left = _prevctx @@ -10963,7 +11658,8 @@ func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { p.SetState(558) if !(p.Precpred(p.GetParserRuleContext(), 5)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) + goto errorExit } { p.SetState(559) @@ -10984,7 +11680,8 @@ func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { p.SetState(562) if !(p.Precpred(p.GetParserRuleContext(), 4)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) + goto errorExit } { p.SetState(563) @@ -11005,7 +11702,8 @@ func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { p.SetState(566) if !(p.Precpred(p.GetParserRuleContext(), 3)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) + goto errorExit } { p.SetState(567) @@ -11026,7 +11724,8 @@ func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { p.SetState(570) if !(p.Precpred(p.GetParserRuleContext(), 2)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) + goto errorExit } { p.SetState(571) @@ -11040,15 +11739,33 @@ func (p *FqlParser) predicate(_p int) (localctx IPredicateContext) { localctx.(*PredicateContext).right = _x } + case antlr.ATNInvalidAltNumber: + goto errorExit } } p.SetState(578) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 57, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 57, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.UnrollRecursionContexts(_parentctx) return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IExpressionAtomContext is an interface to support dynamic dispatch. @@ -11070,12 +11787,31 @@ type IExpressionAtomContext interface { // SetRight sets the right rule contexts. SetRight(IExpressionAtomContext) + // Getter signatures + FunctionCallExpression() IFunctionCallExpressionContext + RangeOperator() IRangeOperatorContext + Literal() ILiteralContext + Variable() IVariableContext + MemberExpression() IMemberExpressionContext + Param() IParamContext + OpenParen() antlr.TerminalNode + CloseParen() antlr.TerminalNode + ForExpression() IForExpressionContext + WaitForExpression() IWaitForExpressionContext + Expression() IExpressionContext + ErrorOperator() IErrorOperatorContext + MultiplicativeOperator() IMultiplicativeOperatorContext + AllExpressionAtom() []IExpressionAtomContext + ExpressionAtom(i int) IExpressionAtomContext + AdditiveOperator() IAdditiveOperatorContext + RegexpOperator() IRegexpOperatorContext + // IsExpressionAtomContext differentiates from other interfaces. IsExpressionAtomContext() } type ExpressionAtomContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser left IExpressionAtomContext right IExpressionAtomContext @@ -11083,17 +11819,22 @@ type ExpressionAtomContext struct { func NewEmptyExpressionAtomContext() *ExpressionAtomContext { var p = new(ExpressionAtomContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_expressionAtom return p } +func InitEmptyExpressionAtomContext(p *ExpressionAtomContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_expressionAtom +} + func (*ExpressionAtomContext) IsExpressionAtomContext() {} func NewExpressionAtomContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionAtomContext { var p = new(ExpressionAtomContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_expressionAtom @@ -11403,39 +12144,24 @@ func (p *FqlParser) ExpressionAtom() (localctx IExpressionAtomContext) { } func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { - this := p - _ = this - var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + _parentState := p.GetState() localctx = NewExpressionAtomContext(p, p.GetParserRuleContext(), _parentState) var _prevctx IExpressionAtomContext = localctx var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. _startState := 120 p.EnterRecursionRule(localctx, 120, FqlParserRULE_expressionAtom, _p) - - defer func() { - p.UnrollRecursionContexts(_parentctx) - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - var _alt int p.EnterOuterAlt(localctx, 1) p.SetState(596) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 60, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 60, p.GetParserRuleContext()) { case 1: { p.SetState(580) @@ -11476,10 +12202,18 @@ func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { { p.SetState(586) p.Match(FqlParserOpenParen) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(590) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 58, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 58, p.GetParserRuleContext()) { case 1: { p.SetState(587) @@ -11498,28 +12232,43 @@ func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { p.expression(0) } + case antlr.ATNInvalidAltNumber: + goto errorExit } { p.SetState(592) p.Match(FqlParserCloseParen) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } p.SetState(594) p.GetErrorHandler().Sync(p) - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 59, p.GetParserRuleContext()) == 1 { + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 59, p.GetParserRuleContext()) == 1 { { p.SetState(593) p.ErrorOperator() } + } else if p.HasError() { // JIM + goto errorExit } + case antlr.ATNInvalidAltNumber: + goto errorExit } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) p.SetState(612) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 62, p.GetParserRuleContext()) - + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 62, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { if p.GetParseListeners() != nil { @@ -11528,7 +12277,11 @@ func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { _prevctx = localctx p.SetState(610) p.GetErrorHandler().Sync(p) - switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 61, p.GetParserRuleContext()) { + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 61, p.GetParserRuleContext()) { case 1: localctx = NewExpressionAtomContext(p, _parentctx, _parentState) localctx.(*ExpressionAtomContext).left = _prevctx @@ -11536,7 +12289,8 @@ func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { p.SetState(598) if !(p.Precpred(p.GetParserRuleContext(), 10)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 10)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 10)", "")) + goto errorExit } { p.SetState(599) @@ -11557,7 +12311,8 @@ func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { p.SetState(602) if !(p.Precpred(p.GetParserRuleContext(), 9)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 9)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 9)", "")) + goto errorExit } { p.SetState(603) @@ -11578,7 +12333,8 @@ func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { p.SetState(606) if !(p.Precpred(p.GetParserRuleContext(), 8)) { - panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 8)", "")) + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 8)", "")) + goto errorExit } { p.SetState(607) @@ -11592,15 +12348,33 @@ func (p *FqlParser) expressionAtom(_p int) (localctx IExpressionAtomContext) { localctx.(*ExpressionAtomContext).right = _x } + case antlr.ATNInvalidAltNumber: + goto errorExit } } p.SetState(614) p.GetErrorHandler().Sync(p) - _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 62, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 62, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.UnrollRecursionContexts(_parentctx) return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IArrayOperatorContext is an interface to support dynamic dispatch. @@ -11616,29 +12390,41 @@ type IArrayOperatorContext interface { // SetOperator sets the operator token. SetOperator(antlr.Token) + // Getter signatures + All() antlr.TerminalNode + Any() antlr.TerminalNode + None() antlr.TerminalNode + InOperator() IInOperatorContext + EqualityOperator() IEqualityOperatorContext + // IsArrayOperatorContext differentiates from other interfaces. IsArrayOperatorContext() } type ArrayOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser operator antlr.Token } func NewEmptyArrayOperatorContext() *ArrayOperatorContext { var p = new(ArrayOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_arrayOperator return p } +func InitEmptyArrayOperatorContext(p *ArrayOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_arrayOperator +} + func (*ArrayOperatorContext) IsArrayOperatorContext() {} func NewArrayOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ArrayOperatorContext { var p = new(ArrayOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_arrayOperator @@ -11727,29 +12513,10 @@ func (s *ArrayOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) ArrayOperator() (localctx IArrayOperatorContext) { - this := p - _ = this - localctx = NewArrayOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 122, FqlParserRULE_arrayOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(615) @@ -11771,6 +12538,9 @@ func (p *FqlParser) ArrayOperator() (localctx IArrayOperatorContext) { } p.SetState(618) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } switch p.GetTokenStream().LA(1) { case FqlParserNot, FqlParserIn: @@ -11786,10 +12556,21 @@ func (p *FqlParser) ArrayOperator() (localctx IArrayOperatorContext) { } default: - panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IEqualityOperatorContext is an interface to support dynamic dispatch. @@ -11799,28 +12580,41 @@ type IEqualityOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Gt() antlr.TerminalNode + Lt() antlr.TerminalNode + Eq() antlr.TerminalNode + Gte() antlr.TerminalNode + Lte() antlr.TerminalNode + Neq() antlr.TerminalNode + // IsEqualityOperatorContext differentiates from other interfaces. IsEqualityOperatorContext() } type EqualityOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyEqualityOperatorContext() *EqualityOperatorContext { var p = new(EqualityOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_equalityOperator return p } +func InitEmptyEqualityOperatorContext(p *EqualityOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_equalityOperator +} + func (*EqualityOperatorContext) IsEqualityOperatorContext() {} func NewEqualityOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *EqualityOperatorContext { var p = new(EqualityOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_equalityOperator @@ -11885,29 +12679,10 @@ func (s *EqualityOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interfa } func (p *FqlParser) EqualityOperator() (localctx IEqualityOperatorContext) { - this := p - _ = this - localctx = NewEqualityOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 124, FqlParserRULE_equalityOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(620) @@ -11921,7 +12696,17 @@ func (p *FqlParser) EqualityOperator() (localctx IEqualityOperatorContext) { } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IInOperatorContext is an interface to support dynamic dispatch. @@ -11931,28 +12716,37 @@ type IInOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + In() antlr.TerminalNode + Not() antlr.TerminalNode + // IsInOperatorContext differentiates from other interfaces. IsInOperatorContext() } type InOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyInOperatorContext() *InOperatorContext { var p = new(InOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_inOperator return p } +func InitEmptyInOperatorContext(p *InOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_inOperator +} + func (*InOperatorContext) IsInOperatorContext() {} func NewInOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *InOperatorContext { var p = new(InOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_inOperator @@ -12001,47 +12795,49 @@ func (s *InOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *FqlParser) InOperator() (localctx IInOperatorContext) { - this := p - _ = this - localctx = NewInOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 126, FqlParserRULE_inOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) p.SetState(623) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserNot { { p.SetState(622) p.Match(FqlParserNot) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } } { p.SetState(625) p.Match(FqlParserIn) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ILikeOperatorContext is an interface to support dynamic dispatch. @@ -12051,28 +12847,37 @@ type ILikeOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Like() antlr.TerminalNode + Not() antlr.TerminalNode + // IsLikeOperatorContext differentiates from other interfaces. IsLikeOperatorContext() } type LikeOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyLikeOperatorContext() *LikeOperatorContext { var p = new(LikeOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_likeOperator return p } +func InitEmptyLikeOperatorContext(p *LikeOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_likeOperator +} + func (*LikeOperatorContext) IsLikeOperatorContext() {} func NewLikeOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LikeOperatorContext { var p = new(LikeOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_likeOperator @@ -12121,47 +12926,49 @@ func (s *LikeOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } func (p *FqlParser) LikeOperator() (localctx ILikeOperatorContext) { - this := p - _ = this - localctx = NewLikeOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 128, FqlParserRULE_likeOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) p.SetState(628) p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } _la = p.GetTokenStream().LA(1) if _la == FqlParserNot { { p.SetState(627) p.Match(FqlParserNot) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } } { p.SetState(630) p.Match(FqlParserLike) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IUnaryOperatorContext is an interface to support dynamic dispatch. @@ -12171,28 +12978,38 @@ type IUnaryOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Not() antlr.TerminalNode + Plus() antlr.TerminalNode + Minus() antlr.TerminalNode + // IsUnaryOperatorContext differentiates from other interfaces. IsUnaryOperatorContext() } type UnaryOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyUnaryOperatorContext() *UnaryOperatorContext { var p = new(UnaryOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_unaryOperator return p } +func InitEmptyUnaryOperatorContext(p *UnaryOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_unaryOperator +} + func (*UnaryOperatorContext) IsUnaryOperatorContext() {} func NewUnaryOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UnaryOperatorContext { var p = new(UnaryOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_unaryOperator @@ -12245,29 +13062,10 @@ func (s *UnaryOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) UnaryOperator() (localctx IUnaryOperatorContext) { - this := p - _ = this - localctx = NewUnaryOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 130, FqlParserRULE_unaryOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(632) @@ -12281,7 +13079,17 @@ func (p *FqlParser) UnaryOperator() (localctx IUnaryOperatorContext) { } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IRegexpOperatorContext is an interface to support dynamic dispatch. @@ -12291,28 +13099,37 @@ type IRegexpOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + RegexMatch() antlr.TerminalNode + RegexNotMatch() antlr.TerminalNode + // IsRegexpOperatorContext differentiates from other interfaces. IsRegexpOperatorContext() } type RegexpOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyRegexpOperatorContext() *RegexpOperatorContext { var p = new(RegexpOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_regexpOperator return p } +func InitEmptyRegexpOperatorContext(p *RegexpOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_regexpOperator +} + func (*RegexpOperatorContext) IsRegexpOperatorContext() {} func NewRegexpOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RegexpOperatorContext { var p = new(RegexpOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_regexpOperator @@ -12361,29 +13178,10 @@ func (s *RegexpOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface } func (p *FqlParser) RegexpOperator() (localctx IRegexpOperatorContext) { - this := p - _ = this - localctx = NewRegexpOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 132, FqlParserRULE_regexpOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(634) @@ -12397,7 +13195,17 @@ func (p *FqlParser) RegexpOperator() (localctx IRegexpOperatorContext) { } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ILogicalAndOperatorContext is an interface to support dynamic dispatch. @@ -12407,28 +13215,36 @@ type ILogicalAndOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + And() antlr.TerminalNode + // IsLogicalAndOperatorContext differentiates from other interfaces. IsLogicalAndOperatorContext() } type LogicalAndOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyLogicalAndOperatorContext() *LogicalAndOperatorContext { var p = new(LogicalAndOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_logicalAndOperator return p } +func InitEmptyLogicalAndOperatorContext(p *LogicalAndOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_logicalAndOperator +} + func (*LogicalAndOperatorContext) IsLogicalAndOperatorContext() {} func NewLogicalAndOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LogicalAndOperatorContext { var p = new(LogicalAndOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_logicalAndOperator @@ -12473,35 +13289,29 @@ func (s *LogicalAndOperatorContext) Accept(visitor antlr.ParseTreeVisitor) inter } func (p *FqlParser) LogicalAndOperator() (localctx ILogicalAndOperatorContext) { - this := p - _ = this - localctx = NewLogicalAndOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 134, FqlParserRULE_logicalAndOperator) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(636) p.Match(FqlParserAnd) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // ILogicalOrOperatorContext is an interface to support dynamic dispatch. @@ -12511,28 +13321,36 @@ type ILogicalOrOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Or() antlr.TerminalNode + // IsLogicalOrOperatorContext differentiates from other interfaces. IsLogicalOrOperatorContext() } type LogicalOrOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyLogicalOrOperatorContext() *LogicalOrOperatorContext { var p = new(LogicalOrOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_logicalOrOperator return p } +func InitEmptyLogicalOrOperatorContext(p *LogicalOrOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_logicalOrOperator +} + func (*LogicalOrOperatorContext) IsLogicalOrOperatorContext() {} func NewLogicalOrOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LogicalOrOperatorContext { var p = new(LogicalOrOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_logicalOrOperator @@ -12577,35 +13395,29 @@ func (s *LogicalOrOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interf } func (p *FqlParser) LogicalOrOperator() (localctx ILogicalOrOperatorContext) { - this := p - _ = this - localctx = NewLogicalOrOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 136, FqlParserRULE_logicalOrOperator) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(638) p.Match(FqlParserOr) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IMultiplicativeOperatorContext is an interface to support dynamic dispatch. @@ -12615,28 +13427,38 @@ type IMultiplicativeOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Multi() antlr.TerminalNode + Div() antlr.TerminalNode + Mod() antlr.TerminalNode + // IsMultiplicativeOperatorContext differentiates from other interfaces. IsMultiplicativeOperatorContext() } type MultiplicativeOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyMultiplicativeOperatorContext() *MultiplicativeOperatorContext { var p = new(MultiplicativeOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_multiplicativeOperator return p } +func InitEmptyMultiplicativeOperatorContext(p *MultiplicativeOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_multiplicativeOperator +} + func (*MultiplicativeOperatorContext) IsMultiplicativeOperatorContext() {} func NewMultiplicativeOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MultiplicativeOperatorContext { var p = new(MultiplicativeOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_multiplicativeOperator @@ -12689,29 +13511,10 @@ func (s *MultiplicativeOperatorContext) Accept(visitor antlr.ParseTreeVisitor) i } func (p *FqlParser) MultiplicativeOperator() (localctx IMultiplicativeOperatorContext) { - this := p - _ = this - localctx = NewMultiplicativeOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 138, FqlParserRULE_multiplicativeOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(640) @@ -12725,7 +13528,17 @@ func (p *FqlParser) MultiplicativeOperator() (localctx IMultiplicativeOperatorCo } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IAdditiveOperatorContext is an interface to support dynamic dispatch. @@ -12735,28 +13548,37 @@ type IAdditiveOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + Plus() antlr.TerminalNode + Minus() antlr.TerminalNode + // IsAdditiveOperatorContext differentiates from other interfaces. IsAdditiveOperatorContext() } type AdditiveOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyAdditiveOperatorContext() *AdditiveOperatorContext { var p = new(AdditiveOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_additiveOperator return p } +func InitEmptyAdditiveOperatorContext(p *AdditiveOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_additiveOperator +} + func (*AdditiveOperatorContext) IsAdditiveOperatorContext() {} func NewAdditiveOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *AdditiveOperatorContext { var p = new(AdditiveOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_additiveOperator @@ -12805,29 +13627,10 @@ func (s *AdditiveOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interfa } func (p *FqlParser) AdditiveOperator() (localctx IAdditiveOperatorContext) { - this := p - _ = this - localctx = NewAdditiveOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 140, FqlParserRULE_additiveOperator) var _la int - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(642) @@ -12841,7 +13644,17 @@ func (p *FqlParser) AdditiveOperator() (localctx IAdditiveOperatorContext) { } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } // IErrorOperatorContext is an interface to support dynamic dispatch. @@ -12851,28 +13664,36 @@ type IErrorOperatorContext interface { // GetParser returns the parser. GetParser() antlr.Parser + // Getter signatures + QuestionMark() antlr.TerminalNode + // IsErrorOperatorContext differentiates from other interfaces. IsErrorOperatorContext() } type ErrorOperatorContext struct { - *antlr.BaseParserRuleContext + antlr.BaseParserRuleContext parser antlr.Parser } func NewEmptyErrorOperatorContext() *ErrorOperatorContext { var p = new(ErrorOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) p.RuleIndex = FqlParserRULE_errorOperator return p } +func InitEmptyErrorOperatorContext(p *ErrorOperatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = FqlParserRULE_errorOperator +} + func (*ErrorOperatorContext) IsErrorOperatorContext() {} func NewErrorOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ErrorOperatorContext { var p = new(ErrorOperatorContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) p.parser = parser p.RuleIndex = FqlParserRULE_errorOperator @@ -12917,35 +13738,29 @@ func (s *ErrorOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *FqlParser) ErrorOperator() (localctx IErrorOperatorContext) { - this := p - _ = this - localctx = NewErrorOperatorContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 142, FqlParserRULE_errorOperator) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - p.EnterOuterAlt(localctx, 1) { p.SetState(644) p.Match(FqlParserQuestionMark) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() return localctx + goto errorExit // Trick to prevent compiler error if the label is not used } func (p *FqlParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool { @@ -12977,9 +13792,6 @@ func (p *FqlParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int } func (p *FqlParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int) bool { - this := p - _ = this - switch predIndex { case 0: return p.Precpred(p.GetParserRuleContext(), 4) @@ -12996,9 +13808,6 @@ func (p *FqlParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int } func (p *FqlParser) Predicate_Sempred(localctx antlr.RuleContext, predIndex int) bool { - this := p - _ = this - switch predIndex { case 3: return p.Precpred(p.GetParserRuleContext(), 5) @@ -13018,9 +13827,6 @@ func (p *FqlParser) Predicate_Sempred(localctx antlr.RuleContext, predIndex int) } func (p *FqlParser) ExpressionAtom_Sempred(localctx antlr.RuleContext, predIndex int) bool { - this := p - _ = this - switch predIndex { case 7: return p.Precpred(p.GetParserRuleContext(), 10) diff --git a/pkg/parser/fql/fqlparser_base_listener.go b/pkg/parser/fql/fqlparser_base_listener.go index f1da9bf3..2d8674b1 100644 --- a/pkg/parser/fql/fqlparser_base_listener.go +++ b/pkg/parser/fql/fqlparser_base_listener.go @@ -1,7 +1,7 @@ -// Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT. +// Code generated from antlr/FqlParser.g4 by ANTLR 4.13.1. DO NOT EDIT. package fql // FqlParser -import "github.com/antlr/antlr4/runtime/Go/antlr/v4" +import "github.com/antlr4-go/antlr/v4" // BaseFqlParserListener is a complete listener for a parse tree produced by FqlParser. type BaseFqlParserListener struct{} diff --git a/pkg/parser/fql/fqlparser_base_visitor.go b/pkg/parser/fql/fqlparser_base_visitor.go index edf319f9..6ce54b02 100644 --- a/pkg/parser/fql/fqlparser_base_visitor.go +++ b/pkg/parser/fql/fqlparser_base_visitor.go @@ -1,7 +1,7 @@ -// Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT. +// Code generated from antlr/FqlParser.g4 by ANTLR 4.13.1. DO NOT EDIT. package fql // FqlParser -import "github.com/antlr/antlr4/runtime/Go/antlr/v4" +import "github.com/antlr4-go/antlr/v4" type BaseFqlParserVisitor struct { *antlr.BaseParseTreeVisitor diff --git a/pkg/parser/fql/fqlparser_listener.go b/pkg/parser/fql/fqlparser_listener.go index dcf88577..241b36be 100644 --- a/pkg/parser/fql/fqlparser_listener.go +++ b/pkg/parser/fql/fqlparser_listener.go @@ -1,7 +1,7 @@ -// Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT. +// Code generated from antlr/FqlParser.g4 by ANTLR 4.13.1. DO NOT EDIT. package fql // FqlParser -import "github.com/antlr/antlr4/runtime/Go/antlr/v4" +import "github.com/antlr4-go/antlr/v4" // FqlParserListener is a complete listener for a parse tree produced by FqlParser. type FqlParserListener interface { diff --git a/pkg/parser/fql/fqlparser_visitor.go b/pkg/parser/fql/fqlparser_visitor.go index 1c1d18af..c9d659f9 100644 --- a/pkg/parser/fql/fqlparser_visitor.go +++ b/pkg/parser/fql/fqlparser_visitor.go @@ -1,7 +1,7 @@ -// Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT. +// Code generated from antlr/FqlParser.g4 by ANTLR 4.13.1. DO NOT EDIT. package fql // FqlParser -import "github.com/antlr/antlr4/runtime/Go/antlr/v4" +import "github.com/antlr4-go/antlr/v4" // A complete Visitor for a parse tree produced by FqlParser. type FqlParserVisitor interface { diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index c8f251ba..8320955d 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -2,7 +2,7 @@ package parser import ( - "github.com/antlr/antlr4/runtime/Go/antlr/v4" + antlr "github.com/antlr4-go/antlr/v4" "github.com/MontFerret/ferret/pkg/parser/fql" ) diff --git a/pkg/runtime/collections/adapters.go b/pkg/runtime/collections/adapters.go deleted file mode 100644 index c82fdd5a..00000000 --- a/pkg/runtime/collections/adapters.go +++ /dev/null @@ -1,77 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type ( - coreIterableAdapter struct { - valVar string - keyVar string - iterable core.Iterable - } - - coreIteratorAdapter struct { - valVar string - keyVar string - iterator core.Iterator - } -) - -func FromCoreIterable(valVar, keyVar string, iterable core.Iterable) (Iterable, error) { - if valVar == "" { - return nil, core.Error(core.ErrMissedArgument, "value variable") - } - - if iterable == nil { - return nil, core.Error(core.ErrMissedArgument, "iterable") - } - - return &coreIterableAdapter{valVar, keyVar, iterable}, nil -} - -func (c *coreIterableAdapter) Iterate(ctx context.Context, _ *core.Scope) (Iterator, error) { - iter, err := c.iterable.Iterate(ctx) - - if err != nil { - return nil, err - } - - return FromCoreIterator(c.valVar, c.keyVar, iter) -} - -func FromCoreIterator(valVar, keyVar string, iterator core.Iterator) (Iterator, error) { - if valVar == "" { - return nil, core.Error(core.ErrMissedArgument, "value variable") - } - - if iterator == nil { - return nil, core.Error(core.ErrMissedArgument, "iterator") - } - - return &coreIteratorAdapter{valVar, keyVar, iterator}, nil -} - -func (iterator *coreIteratorAdapter) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - val, key, err := iterator.iterator.Next(ctx) - - if err != nil { - return nil, err - } - - nextScope := scope.Fork() - - if err := nextScope.SetVariable(iterator.valVar, val); err != nil { - return nil, err - } - - if iterator.keyVar != "" { - if err := nextScope.SetVariable(iterator.keyVar, key); err != nil { - return nil, err - } - } - - return nextScope, nil -} diff --git a/pkg/runtime/collections/collection.go b/pkg/runtime/collections/collection.go deleted file mode 100644 index a2aba696..00000000 --- a/pkg/runtime/collections/collection.go +++ /dev/null @@ -1,28 +0,0 @@ -package collections - -import ( - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -type ( - // Measurable represents an interface of a value that can has length. - Measurable interface { - Length() values.Int - } - - IndexedCollection interface { - core.Value - Measurable - Get(idx values.Int) core.Value - Set(idx values.Int, value core.Value) error - } - - KeyedCollection interface { - core.Value - Measurable - Keys() []values.String - Get(key values.String) (core.Value, values.Boolean) - Set(key values.String, value core.Value) - } -) diff --git a/pkg/runtime/collections/filter.go b/pkg/runtime/collections/filter.go deleted file mode 100644 index f4ef7eeb..00000000 --- a/pkg/runtime/collections/filter.go +++ /dev/null @@ -1,48 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type ( - FilterPredicate func(ctx context.Context, scope *core.Scope) (bool, error) - - FilterIterator struct { - values Iterator - predicate FilterPredicate - } -) - -func NewFilterIterator(values Iterator, predicate FilterPredicate) (*FilterIterator, error) { - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "result") - } - - if predicate == nil { - return nil, core.Error(core.ErrMissedArgument, "predicate") - } - - return &FilterIterator{values: values, predicate: predicate}, nil -} - -func (iterator *FilterIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - for { - nextScope, err := iterator.values.Next(ctx, scope.Fork()) - - if err != nil { - return nil, err - } - - take, err := iterator.predicate(ctx, nextScope) - - if err != nil { - return nil, err - } - - if take { - return nextScope, nil - } - } -} diff --git a/pkg/runtime/collections/filter_test.go b/pkg/runtime/collections/filter_test.go deleted file mode 100644 index ebb2a6ec..00000000 --- a/pkg/runtime/collections/filter_test.go +++ /dev/null @@ -1,210 +0,0 @@ -package collections_test - -import ( - "context" - "encoding/json" - "math" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func TestFilter(t *testing.T) { - Convey("Should filter out non-even result", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - predicate := func(_ context.Context, scope *core.Scope) (bool, error) { - i := float64(scope.MustGetVariable(collections.DefaultValueVar).Unwrap().(int)) - calc := i / 2 - - return calc == math.Floor(calc), nil - } - - iter, err := collections.NewFilterIterator( - sliceIterator(arr), - predicate, - ) - - So(err, ShouldBeNil) - - scope, _ := core.NewRootScope() - res, err := collections.ToSlice(context.Background(), scope, iter) - - So(err, ShouldBeNil) - So(res, ShouldHaveLength, 2) - }) - - Convey("Should filter out non-even groupKeys", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - predicate := func(_ context.Context, scope *core.Scope) (bool, error) { - i := float64(scope.MustGetVariable(collections.DefaultKeyVar).Unwrap().(int)) - - if i == 0 { - return false, nil - } - - calc := i / 2 - - return calc == math.Floor(calc), nil - } - - iter, err := collections.NewFilterIterator( - sliceIterator(arr), - predicate, - ) - - So(err, ShouldBeNil) - - scope, _ := core.NewRootScope() - res, err := collections.ToSlice(context.Background(), scope, iter) - - So(err, ShouldBeNil) - - So(res, ShouldHaveLength, 2) - }) - - Convey("Should filter out result all result", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - predicate := func(_ context.Context, _ *core.Scope) (bool, error) { - return false, nil - } - - iter, err := collections.NewFilterIterator( - sliceIterator(arr), - predicate, - ) - - So(err, ShouldBeNil) - - scope, _ := core.NewRootScope() - res, err := collections.ToSlice(context.Background(), scope, iter) - - So(err, ShouldBeNil) - So(res, ShouldHaveLength, 0) - }) - - Convey("Should pass through all result", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - predicate := func(_ context.Context, _ *core.Scope) (bool, error) { - return true, nil - } - - iter, err := collections.NewFilterIterator( - sliceIterator(arr), - predicate, - ) - - So(err, ShouldBeNil) - - scope, _ := core.NewRootScope() - res, err := collections.ToSlice(context.Background(), scope, iter) - - So(err, ShouldBeNil) - So(res, ShouldHaveLength, len(arr)) - }) - - Convey("Should return an error when exhausted", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - predicate := func(_ context.Context, _ *core.Scope) (bool, error) { - return true, nil - } - - iter, err := collections.NewFilterIterator( - sliceIterator(arr), - predicate, - ) - - So(err, ShouldBeNil) - - scope, _ := core.NewRootScope() - _, err = collections.ToSlice(context.Background(), scope, iter) - - So(err, ShouldBeNil) - - item, err := iter.Next(context.Background(), scope) - - So(item, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - }) - - Convey("Should iterate over nested filter", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - // i < 5 - predicate1 := func(_ context.Context, scope *core.Scope) (bool, error) { - return scope.MustGetVariable(collections.DefaultValueVar).Compare(values.NewInt(5)) == -1, nil - } - - // i > 2 - predicate2 := func(_ context.Context, scope *core.Scope) (bool, error) { - return scope.MustGetVariable(collections.DefaultValueVar).Compare(values.NewInt(2)) == 1, nil - } - - it, _ := collections.NewFilterIterator( - sliceIterator(arr), - predicate1, - ) - - iter, err := collections.NewFilterIterator( - it, - predicate2, - ) - - So(err, ShouldBeNil) - - scope, _ := core.NewRootScope() - sets, err := collections.ToSlice(context.Background(), scope, iter) - - So(err, ShouldBeNil) - - res := toArrayOfValues(sets) - - js, _ := json.Marshal(res) - - So(string(js), ShouldEqual, `[3,4]`) - }) -} diff --git a/pkg/runtime/collections/helpers.go b/pkg/runtime/collections/helpers.go deleted file mode 100644 index 7c8e1318..00000000 --- a/pkg/runtime/collections/helpers.go +++ /dev/null @@ -1,69 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type ( - IterableFn struct { - fn func(ctx context.Context, scope *core.Scope) (Iterator, error) - } - - IteratorFn struct { - fn func(ctx context.Context, scope *core.Scope) (*core.Scope, error) - } -) - -func AsIterable(fn func(ctx context.Context, scope *core.Scope) (Iterator, error)) Iterable { - return &IterableFn{fn} -} - -func (i *IterableFn) Iterate(ctx context.Context, scope *core.Scope) (Iterator, error) { - return i.fn(ctx, scope) -} - -func AsIterator(fn func(ctx context.Context, scope *core.Scope) (*core.Scope, error)) Iterator { - return &IteratorFn{fn} -} - -func (i *IteratorFn) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - return i.fn(ctx, scope) -} - -func ToSlice(ctx context.Context, scope *core.Scope, iterator Iterator) ([]*core.Scope, error) { - res := make([]*core.Scope, 0, 10) - - for { - nextScope, err := iterator.Next(ctx, scope.Fork()) - - if err != nil { - if core.IsNoMoreData(err) { - return res, nil - } - - return nil, err - } - - res = append(res, nextScope) - } -} - -func ForEach(ctx context.Context, scope *core.Scope, iter Iterator, predicate func(ctx context.Context, scope *core.Scope) bool) error { - for { - nextScope, err := iter.Next(ctx, scope) - - if err != nil { - if core.IsNoMoreData(err) { - return nil - } - - return err - } - - if !predicate(ctx, nextScope) { - return nil - } - } -} diff --git a/pkg/runtime/collections/indexed.go b/pkg/runtime/collections/indexed.go deleted file mode 100644 index dc8ca1b1..00000000 --- a/pkg/runtime/collections/indexed.go +++ /dev/null @@ -1,67 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -const ( - DefaultValueVar = "value" - DefaultKeyVar = "key" -) - -type IndexedIterator struct { - valVar string - keyVar string - values IndexedCollection - pos int -} - -func NewIndexedIterator( - valVar, - keyVar string, - values IndexedCollection, -) (Iterator, error) { - if valVar == "" { - return nil, core.Error(core.ErrMissedArgument, "value variable") - } - - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "result") - } - - return &IndexedIterator{valVar, keyVar, values, 0}, nil -} - -func NewDefaultIndexedIterator( - values IndexedCollection, -) (Iterator, error) { - return NewIndexedIterator(DefaultValueVar, DefaultKeyVar, values) -} - -func (iterator *IndexedIterator) Next(_ context.Context, scope *core.Scope) (*core.Scope, error) { - if int(iterator.values.Length()) > iterator.pos { - idx := values.NewInt(iterator.pos) - val := iterator.values.Get(idx) - - iterator.pos++ - - nextScope := scope.Fork() - - if err := nextScope.SetVariable(iterator.valVar, val); err != nil { - return nil, err - } - - if iterator.keyVar != "" { - if err := nextScope.SetVariable(iterator.keyVar, idx); err != nil { - return nil, err - } - } - - return nextScope, nil - } - - return nil, core.ErrNoMoreData -} diff --git a/pkg/runtime/collections/indexed_test.go b/pkg/runtime/collections/indexed_test.go deleted file mode 100644 index bdebb5af..00000000 --- a/pkg/runtime/collections/indexed_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func arrayIterator(arr *values.Array) collections.Iterator { - iterator, _ := collections.NewDefaultIndexedIterator(arr) - - return iterator -} - -func TestArrayIterator(t *testing.T) { - Convey("Should iterate over an array", t, func() { - arr := values.NewArrayWith( - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - ) - - iter := arrayIterator(arr) - - res := make([]core.Value, 0, arr.Length()) - - pos := 0 - - ctx := context.Background() - scope, _ := core.NewRootScope() - - for { - nextScope, err := iter.Next(ctx, scope.Fork()) - - if err != nil { - if core.IsNoMoreData(err) { - break - } - - So(err, ShouldBeNil) - } - - res = append(res, nextScope.MustGetVariable(collections.DefaultValueVar)) - - pos++ - } - - So(res, ShouldHaveLength, arr.Length()) - }) - - Convey("Should iterate over an array in the same order", t, func() { - arr := values.NewArrayWith( - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - ) - - iter := arrayIterator(arr) - - res := make([]core.Value, 0, arr.Length()) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - for { - nextScope, err := iter.Next(ctx, scope.Fork()) - - if err != nil { - if core.IsNoMoreData(err) { - break - } - - So(err, ShouldBeNil) - } - - res = append(res, nextScope.MustGetVariable(collections.DefaultValueVar)) - } - - arr.ForEach(func(expected core.Value, idx int) bool { - actual := res[idx] - - So(actual, ShouldEqual, expected) - - return true - }) - }) - - Convey("Should return an error when exhausted", t, func() { - arr := values.NewArrayWith( - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - ) - - iter := arrayIterator(arr) - - res := make([]core.Value, 0, arr.Length()) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - for { - nextScope, err := iter.Next(ctx, scope.Fork()) - - if err != nil { - if core.IsNoMoreData(err) { - break - } - - So(err, ShouldBeNil) - } - - res = append(res, nextScope.MustGetVariable(collections.DefaultValueVar)) - } - - item, err := iter.Next(ctx, scope) - - So(item, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - So(res, ShouldHaveLength, int(arr.Length())) - }) - - Convey("Should NOT iterate over an empty array", t, func() { - arr := values.NewArray(10) - - iter := arrayIterator(arr) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - nextScope, err := iter.Next(ctx, scope) - - So(err, ShouldEqual, core.ErrNoMoreData) - So(nextScope, ShouldBeNil) - }) -} diff --git a/pkg/runtime/collections/iterator.go b/pkg/runtime/collections/iterator.go deleted file mode 100644 index 927b195b..00000000 --- a/pkg/runtime/collections/iterator.go +++ /dev/null @@ -1,17 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type ( - Iterator interface { - Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) - } - - Iterable interface { - Iterate(ctx context.Context, scope *core.Scope) (Iterator, error) - } -) diff --git a/pkg/runtime/collections/keyed.go b/pkg/runtime/collections/keyed.go deleted file mode 100644 index f3a24dd6..00000000 --- a/pkg/runtime/collections/keyed.go +++ /dev/null @@ -1,65 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -type KeyedIterator struct { - valVar string - keyVar string - values KeyedCollection - keys []values.String - pos int -} - -func NewKeyedIterator( - valVar, - keyVar string, - values KeyedCollection, -) (Iterator, error) { - if valVar == "" { - return nil, core.Error(core.ErrMissedArgument, "value variable") - } - - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "result") - } - - return &KeyedIterator{valVar, keyVar, values, nil, 0}, nil -} - -func NewDefaultKeyedIterator(input KeyedCollection) (Iterator, error) { - return NewKeyedIterator(DefaultValueVar, DefaultKeyVar, input) -} - -func (iterator *KeyedIterator) Next(_ context.Context, scope *core.Scope) (*core.Scope, error) { - if iterator.keys == nil { - iterator.keys = iterator.values.Keys() - } - - if len(iterator.keys) > iterator.pos { - key := iterator.keys[iterator.pos] - val, _ := iterator.values.Get(key) - - iterator.pos++ - - nextScope := scope.Fork() - - if err := nextScope.SetVariable(iterator.valVar, val); err != nil { - return nil, err - } - - if iterator.keyVar != "" { - if err := nextScope.SetVariable(iterator.keyVar, key); err != nil { - return nil, err - } - } - - return nextScope, nil - } - - return nil, core.ErrNoMoreData -} diff --git a/pkg/runtime/collections/keyed_test.go b/pkg/runtime/collections/keyed_test.go deleted file mode 100644 index 17930409..00000000 --- a/pkg/runtime/collections/keyed_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func objectIterator(obj *values.Object) collections.Iterator { - iter, _ := collections.NewDefaultKeyedIterator(obj) - - return iter -} - -func TestObjectIterator(t *testing.T) { - Convey("Should iterate over a map", t, func() { - m := values.NewObjectWith( - values.NewObjectProperty("one", values.NewInt(1)), - values.NewObjectProperty("two", values.NewInt(2)), - values.NewObjectProperty("three", values.NewInt(3)), - values.NewObjectProperty("four", values.NewInt(4)), - values.NewObjectProperty("five", values.NewInt(5)), - ) - - iter := objectIterator(m) - - res := make([]core.Value, 0, m.Length()) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - for { - nextScope, err := iter.Next(ctx, scope) - - if err != nil { - if core.IsNoMoreData(err) { - break - } - - So(err, ShouldBeNil) - } - - key := nextScope.MustGetVariable(collections.DefaultKeyVar) - item := nextScope.MustGetVariable(collections.DefaultValueVar) - - expected, exists := m.Get(values.NewString(key.String())) - - So(bool(exists), ShouldBeTrue) - So(expected, ShouldEqual, item) - - res = append(res, item) - } - - So(res, ShouldHaveLength, m.Length()) - }) - - Convey("Should return an error when exhausted", t, func() { - m := values.NewObjectWith( - values.NewObjectProperty("one", values.NewInt(1)), - values.NewObjectProperty("two", values.NewInt(2)), - values.NewObjectProperty("three", values.NewInt(3)), - values.NewObjectProperty("four", values.NewInt(4)), - values.NewObjectProperty("five", values.NewInt(5)), - ) - - iter := objectIterator(m) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(res, ShouldNotBeNil) - - nextScope, err := iter.Next(ctx, scope) - - So(nextScope, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - }) - - Convey("Should NOT iterate over a empty map", t, func() { - m := values.NewObject() - - iter := objectIterator(m) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - nextScope, err := iter.Next(ctx, scope) - - So(nextScope, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - }) -} diff --git a/pkg/runtime/collections/limit.go b/pkg/runtime/collections/limit.go deleted file mode 100644 index 9243bb7f..00000000 --- a/pkg/runtime/collections/limit.go +++ /dev/null @@ -1,62 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type LimitIterator struct { - values Iterator - count int - offset int - currCount int -} - -func NewLimitIterator(values Iterator, count, offset int) (*LimitIterator, error) { - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "result") - } - - return &LimitIterator{values, count, offset, 0}, nil -} - -func (iterator *LimitIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - if err := iterator.verifyOffset(ctx, scope); err != nil { - return nil, err - } - - iterator.currCount++ - - if iterator.counter() <= iterator.count { - return iterator.values.Next(ctx, scope) - } - - return nil, core.ErrNoMoreData -} - -func (iterator *LimitIterator) counter() int { - return iterator.currCount - iterator.offset -} - -func (iterator *LimitIterator) verifyOffset(ctx context.Context, scope *core.Scope) error { - if iterator.offset == 0 { - return nil - } - - for iterator.offset > iterator.currCount { - _, err := iterator.values.Next(ctx, scope.Fork()) - - if err != nil { - if core.IsNoMoreData(err) { - iterator.currCount = iterator.offset - } - - return err - } - - iterator.currCount++ - } - - return nil -} diff --git a/pkg/runtime/collections/limit_test.go b/pkg/runtime/collections/limit_test.go deleted file mode 100644 index deecca0b..00000000 --- a/pkg/runtime/collections/limit_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func TestLimit(t *testing.T) { - Convey("Should limit iteration", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - iter, err := collections.NewLimitIterator( - sliceIterator(arr), - 1, - 0, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(len(res), ShouldEqual, 1) - }) - - Convey("Should limit iteration (2)", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - iter, err := collections.NewLimitIterator( - sliceIterator(arr), - 2, - 0, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(len(res), ShouldEqual, 2) - }) - - Convey("Should limit iteration with offset", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - offset := 2 - iter, err := collections.NewLimitIterator( - sliceIterator(arr), - 2, - offset, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(len(res), ShouldEqual, 2) - - for idx, nextScope := range res { - expected := arr[idx+offset] - current := nextScope.MustGetVariable(collections.DefaultValueVar) - - So(expected, ShouldEqual, current) - } - }) - - Convey("Should limit iteration with offset at the end", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - offset := 3 - - iter, err := collections.NewLimitIterator( - sliceIterator(arr), - 2, - offset, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(len(res), ShouldEqual, 2) - - for idx, nextScope := range res { - expected := arr[idx+offset] - current := nextScope.MustGetVariable(collections.DefaultValueVar) - - So(expected, ShouldEqual, current) - } - }) - - Convey("Should limit iteration with offset with going out of bounds", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - offset := 4 - - iter, err := collections.NewLimitIterator( - sliceIterator(arr), - 2, - offset, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(len(res), ShouldEqual, 1) - }) -} diff --git a/pkg/runtime/collections/map.go b/pkg/runtime/collections/map.go deleted file mode 100644 index ae07934b..00000000 --- a/pkg/runtime/collections/map.go +++ /dev/null @@ -1,74 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -type MapIterator struct { - valVar string - keyVar string - values map[string]core.Value - keys []string - pos int -} - -func NewMapIterator( - valVar, - keyVar string, - values map[string]core.Value, -) (Iterator, error) { - if valVar == "" { - return nil, core.Error(core.ErrMissedArgument, "value variable") - } - - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "result") - } - - return &MapIterator{valVar, keyVar, values, nil, 0}, nil -} - -func NewDefaultMapIterator(values map[string]core.Value) (Iterator, error) { - return NewMapIterator(DefaultValueVar, DefaultKeyVar, values) -} - -func (iterator *MapIterator) Next(_ context.Context, scope *core.Scope) (*core.Scope, error) { - // lazy initialization - if iterator.keys == nil { - keys := make([]string, len(iterator.values)) - - i := 0 - for k := range iterator.values { - keys[i] = k - i++ - } - - iterator.keys = keys - } - - if len(iterator.keys) > iterator.pos { - key := iterator.keys[iterator.pos] - val := iterator.values[key] - - iterator.pos++ - - nextScope := scope.Fork() - - if err := nextScope.SetVariable(iterator.valVar, val); err != nil { - return nil, err - } - - if iterator.keyVar != "" { - if err := nextScope.SetVariable(iterator.keyVar, values.NewString(key)); err != nil { - return nil, err - } - } - - return nextScope, nil - } - - return nil, core.ErrNoMoreData -} diff --git a/pkg/runtime/collections/map_test.go b/pkg/runtime/collections/map_test.go deleted file mode 100644 index e042a0f4..00000000 --- a/pkg/runtime/collections/map_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func mapIterator(m map[string]core.Value) collections.Iterator { - iter, _ := collections.NewDefaultMapIterator(m) - - return iter -} - -func TestMapIterator(t *testing.T) { - Convey("Should iterate over a map", t, func() { - m := map[string]core.Value{ - "one": values.NewInt(1), - "two": values.NewInt(2), - "three": values.NewInt(3), - "four": values.NewInt(4), - "five": values.NewInt(5), - } - - iter := mapIterator(m) - - res := make([]core.Value, 0, len(m)) - ctx := context.Background() - scope, _ := core.NewRootScope() - - for { - nextScope, err := iter.Next(ctx, scope) - - if err != nil { - if core.IsNoMoreData(err) { - break - } - - So(err, ShouldBeNil) - } - - key := nextScope.MustGetVariable(collections.DefaultKeyVar) - item := nextScope.MustGetVariable(collections.DefaultValueVar) - - expected, exists := m[key.String()] - - So(exists, ShouldBeTrue) - So(expected, ShouldEqual, item) - - res = append(res, item) - } - - So(res, ShouldHaveLength, len(m)) - }) - - Convey("Should return an error when exhausted", t, func() { - m := map[string]core.Value{ - "one": values.NewInt(1), - "two": values.NewInt(2), - "three": values.NewInt(3), - "four": values.NewInt(4), - "five": values.NewInt(5), - } - - iter := mapIterator(m) - ctx := context.Background() - scope, _ := core.NewRootScope() - - _, err := collections.ToSlice(ctx, scope, iter) - So(err, ShouldBeNil) - - item, err := iter.Next(ctx, scope) - - So(item, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - }) - - Convey("Should NOT iterate over a empty map", t, func() { - m := make(map[string]core.Value) - - iter := mapIterator(m) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - item, err := iter.Next(ctx, scope) - - So(item, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - }) -} diff --git a/pkg/runtime/collections/slice.go b/pkg/runtime/collections/slice.go deleted file mode 100644 index 81002d0e..00000000 --- a/pkg/runtime/collections/slice.go +++ /dev/null @@ -1,56 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -type SliceIterator struct { - valVar string - keyVar string - values []core.Value - pos int -} - -func NewSliceIterator( - valVar, - keyVar string, - values []core.Value, -) (Iterator, error) { - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "result") - } - - return &SliceIterator{valVar, keyVar, values, 0}, nil -} - -func NewDefaultSliceIterator(input []core.Value) (Iterator, error) { - return NewSliceIterator(DefaultValueVar, DefaultKeyVar, input) -} - -func (iterator *SliceIterator) Next(_ context.Context, scope *core.Scope) (*core.Scope, error) { - if len(iterator.values) > iterator.pos { - idx := iterator.pos - val := iterator.values[idx] - - iterator.pos++ - - nextScope := scope.Fork() - - if err := nextScope.SetVariable(iterator.valVar, val); err != nil { - return nil, err - } - - if iterator.keyVar != "" { - if err := nextScope.SetVariable(iterator.keyVar, values.NewInt(idx)); err != nil { - return nil, err - } - } - - return nextScope, nil - } - - return nil, core.ErrNoMoreData -} diff --git a/pkg/runtime/collections/slice_test.go b/pkg/runtime/collections/slice_test.go deleted file mode 100644 index a7cb844c..00000000 --- a/pkg/runtime/collections/slice_test.go +++ /dev/null @@ -1,123 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func sliceIterator(value []core.Value) collections.Iterator { - iter, _ := collections.NewDefaultSliceIterator(value) - - return iter -} - -func TestSliceIterator(t *testing.T) { - Convey("Should iterate over a slice", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - iter := sliceIterator(arr) - - res := make([]core.Value, 0, len(arr)) - ctx := context.Background() - scope, _ := core.NewRootScope() - - pos := 0 - - for { - nextScope, err := iter.Next(ctx, scope) - - if err != nil { - if core.IsNoMoreData(err) { - break - } - - So(err, ShouldBeNil) - } - - key := nextScope.MustGetVariable(collections.DefaultKeyVar) - item := nextScope.MustGetVariable(collections.DefaultValueVar) - - So(key.Unwrap(), ShouldEqual, pos) - - res = append(res, item) - - pos++ - } - - So(res, ShouldHaveLength, len(arr)) - }) - - Convey("Should iterate over a slice in the same order", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - iter := sliceIterator(arr) - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - for idx := range arr { - expected := arr[idx] - nextScope := res[idx] - actual := nextScope.MustGetVariable(collections.DefaultValueVar) - - So(actual, ShouldEqual, expected) - } - }) - - Convey("Should return an error when exhausted", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - } - - iter := sliceIterator(arr) - ctx := context.Background() - scope, _ := core.NewRootScope() - - _, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - item, err := iter.Next(ctx, scope) - - So(item, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - }) - - Convey("Should NOT iterate over an empty slice", t, func() { - arr := []core.Value{} - - iter := sliceIterator(arr) - ctx := context.Background() - scope, _ := core.NewRootScope() - - item, err := iter.Next(ctx, scope) - - So(item, ShouldBeNil) - So(err, ShouldEqual, core.ErrNoMoreData) - }) -} diff --git a/pkg/runtime/collections/sort.go b/pkg/runtime/collections/sort.go deleted file mode 100644 index e6db1714..00000000 --- a/pkg/runtime/collections/sort.go +++ /dev/null @@ -1,161 +0,0 @@ -package collections - -import ( - "context" - "sort" - "strings" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type ( - SortDirection int - - Comparator func(ctx context.Context, first, second *core.Scope) (int64, error) - - Sorter struct { - fn Comparator - direction SortDirection - } - - SortIterator struct { - values Iterator - sorters []*Sorter - ready bool - result []*core.Scope - pos int - } -) - -const ( - SortDirectionAsc SortDirection = 1 - SortDirectionDesc SortDirection = -1 -) - -func SortDirectionFromString(str string) SortDirection { - if strings.EqualFold(str, "DESC") { - return SortDirectionDesc - } - - return SortDirectionAsc -} - -func IsValidSortDirection(direction SortDirection) bool { - switch direction { - case SortDirectionAsc, SortDirectionDesc: - return true - default: - return false - } -} - -func NewSorter(fn Comparator, direction SortDirection) (*Sorter, error) { - if fn == nil { - return nil, core.Error(core.ErrMissedArgument, "fn") - } - - if !IsValidSortDirection(direction) { - return nil, core.Error(core.ErrInvalidArgument, "direction") - } - - return &Sorter{fn, direction}, nil -} - -func NewSortIterator( - values Iterator, - comparators ...*Sorter, -) (*SortIterator, error) { - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "values") - } - - if len(comparators) == 0 { - return nil, core.Error(core.ErrMissedArgument, "comparator") - } - - return &SortIterator{ - values, - comparators, - false, - nil, - 0, - }, nil -} - -func (iterator *SortIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - // we need to initialize the iterator - if !iterator.ready { - iterator.ready = true - sorted, err := iterator.sort(ctx, scope) - - if err != nil { - return nil, err - } - - iterator.result = sorted - } - - if len(iterator.result) > iterator.pos { - idx := iterator.pos - val := iterator.result[idx] - - iterator.pos++ - - return val, nil - } - - return nil, core.ErrNoMoreData -} - -func (iterator *SortIterator) sort(ctx context.Context, scope *core.Scope) ([]*core.Scope, error) { - scopes, err := ToSlice(ctx, scope, iterator.values) - - if err != nil { - return nil, err - } - - var failure error - - sort.SliceStable(scopes, func(i, j int) bool { - // ignore next execution - if failure != nil { - return false - } - - var out bool - - for _, comp := range iterator.sorters { - left := scopes[i] - right := scopes[j] - - eq, err := comp.fn(ctx, left, right) - - if err != nil { - failure = err - out = false - - break - } - - eq *= int64(comp.direction) - - if eq == -1 { - out = true - break - } - - if eq == 1 { - out = false - break - } - } - - return out - }) - - if failure != nil { - return nil, failure - } - - return scopes, nil -} diff --git a/pkg/runtime/collections/sort_test.go b/pkg/runtime/collections/sort_test.go deleted file mode 100644 index a86becbf..00000000 --- a/pkg/runtime/collections/sort_test.go +++ /dev/null @@ -1,354 +0,0 @@ -package collections_test - -import ( - "context" - "encoding/json" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func toValues(scopes []*core.Scope) []core.Value { - res := make([]core.Value, 0, len(scopes)) - - for _, scope := range scopes { - res = append(res, scope.MustGetVariable(collections.DefaultValueVar)) - } - - return res -} - -func toArrayOfValues(scopes []*core.Scope) *values.Array { - return values.NewArrayWith(toValues(scopes)...) -} - -func TestSort(t *testing.T) { - Convey("Should sort asc", t, func() { - arr := []core.Value{ - values.NewInt(5), - values.NewInt(1), - values.NewInt(3), - values.NewInt(4), - values.NewInt(2), - } - - s, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - return first.MustGetVariable(collections.DefaultValueVar).Compare(second.MustGetVariable(collections.DefaultValueVar)), nil - }, - collections.SortDirectionAsc, - ) - - iter, err := collections.NewSortIterator( - sliceIterator(arr), - s, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - numbers := []int{1, 2, 3, 4, 5} - - for idx, num := range numbers { - So(res[idx].MustGetVariable(collections.DefaultValueVar).Unwrap(), ShouldEqual, num) - } - }) - - Convey("Should sort desc", t, func() { - arr := []core.Value{ - values.NewInt(5), - values.NewInt(1), - values.NewInt(3), - values.NewInt(4), - values.NewInt(2), - } - - s, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - return first.MustGetVariable(collections.DefaultValueVar).Compare(second.MustGetVariable(collections.DefaultValueVar)), nil - }, - collections.SortDirectionDesc, - ) - - iter, err := collections.NewSortIterator( - sliceIterator(arr), - s, - ) - - So(err, ShouldBeNil) - ctx := context.Background() - scope, _ := core.NewRootScope() - - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - numbers := []int{5, 4, 3, 2, 1} - - for idx, num := range numbers { - So(res[idx].MustGetVariable(collections.DefaultValueVar).Unwrap(), ShouldEqual, num) - } - }) - - Convey("Should sort asc with multiple sorters", t, func() { - makeObj := func(one, two int) *values.Object { - obj := values.NewObject() - - obj.Set("one", values.NewInt(one)) - obj.Set("two", values.NewInt(two)) - - return obj - } - - arr := []core.Value{ - makeObj(1, 2), - makeObj(1, 1), - makeObj(3, 1), - makeObj(4, 2), - makeObj(2, 1), - makeObj(3, 2), - makeObj(4, 1), - makeObj(2, 2), - } - - s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - - return o1.Compare(o2), nil - }, - collections.SortDirectionAsc, - ) - - s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - - return o1.Compare(o2), nil - }, - collections.SortDirectionAsc, - ) - - iter, err := collections.NewSortIterator( - sliceIterator(arr), - s1, - s2, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - sets, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - res := toValues(sets) - - j, _ := json.Marshal(res) - - So(string(j), ShouldEqual, `[{"one":1,"two":1},{"one":1,"two":2},{"one":2,"two":1},{"one":2,"two":2},{"one":3,"two":1},{"one":3,"two":2},{"one":4,"two":1},{"one":4,"two":2}]`) - }) - - Convey("Should sort desc with multiple sorters", t, func() { - makeObj := func(one, two int) *values.Object { - obj := values.NewObject() - - obj.Set("one", values.NewInt(one)) - obj.Set("two", values.NewInt(two)) - - return obj - } - - arr := []core.Value{ - makeObj(1, 2), - makeObj(1, 1), - makeObj(3, 1), - makeObj(4, 2), - makeObj(2, 1), - makeObj(3, 2), - makeObj(4, 1), - makeObj(2, 2), - } - - s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - - return o1.Compare(o2), nil - }, - collections.SortDirectionDesc, - ) - - s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - - return o1.Compare(o2), nil - }, - collections.SortDirectionDesc, - ) - - iter, err := collections.NewSortIterator( - sliceIterator(arr), - s1, - s2, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - sets, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - res := toValues(sets) - - j, _ := json.Marshal(res) - - So(string(j), ShouldEqual, `[{"one":4,"two":2},{"one":4,"two":1},{"one":3,"two":2},{"one":3,"two":1},{"one":2,"two":2},{"one":2,"two":1},{"one":1,"two":2},{"one":1,"two":1}]`) - }) - - Convey("Should sort asc and desc with multiple sorters", t, func() { - makeObj := func(one, two int) *values.Object { - obj := values.NewObject() - - obj.Set("one", values.NewInt(one)) - obj.Set("two", values.NewInt(two)) - - return obj - } - - arr := []core.Value{ - makeObj(1, 2), - makeObj(1, 1), - makeObj(3, 1), - makeObj(4, 2), - makeObj(2, 1), - makeObj(3, 2), - makeObj(4, 1), - makeObj(2, 2), - } - - s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - - return o1.Compare(o2), nil - }, - collections.SortDirectionAsc, - ) - - s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - - return o1.Compare(o2), nil - }, - collections.SortDirectionDesc, - ) - - iter, err := collections.NewSortIterator( - sliceIterator(arr), - s1, - s2, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - sets, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - res := toValues(sets) - - j, _ := json.Marshal(res) - - So(string(j), ShouldEqual, `[{"one":1,"two":2},{"one":1,"two":1},{"one":2,"two":2},{"one":2,"two":1},{"one":3,"two":2},{"one":3,"two":1},{"one":4,"two":2},{"one":4,"two":1}]`) - }) - - Convey("Should sort desc and asc with multiple sorters", t, func() { - makeObj := func(one, two int) *values.Object { - obj := values.NewObject() - - obj.Set("one", values.NewInt(one)) - obj.Set("two", values.NewInt(two)) - - return obj - } - - arr := []core.Value{ - makeObj(1, 2), - makeObj(1, 1), - makeObj(3, 1), - makeObj(4, 2), - makeObj(2, 1), - makeObj(3, 2), - makeObj(4, 1), - makeObj(2, 2), - } - - s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") - - return o1.Compare(o2), nil - }, - collections.SortDirectionDesc, - ) - - s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int64, error) { - o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") - - return o1.Compare(o2), nil - }, - collections.SortDirectionAsc, - ) - - src, err := collections.NewSortIterator( - sliceIterator(arr), - s1, - s2, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - sets, err := collections.ToSlice(ctx, scope, src) - - So(err, ShouldBeNil) - - res := toValues(sets) - - j, _ := json.Marshal(res) - - So(string(j), ShouldEqual, `[{"one":4,"two":1},{"one":4,"two":2},{"one":3,"two":1},{"one":3,"two":2},{"one":2,"two":1},{"one":2,"two":2},{"one":1,"two":1},{"one":1,"two":2}]`) - }) -} diff --git a/pkg/runtime/collections/tap.go b/pkg/runtime/collections/tap.go deleted file mode 100644 index 28ace051..00000000 --- a/pkg/runtime/collections/tap.go +++ /dev/null @@ -1,40 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type TapIterator struct { - values Iterator - predicate core.Expression -} - -func NewTapIterator(values Iterator, predicate core.Expression) (Iterator, error) { - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "values") - } - - if predicate == nil { - return nil, core.Error(core.ErrMissedArgument, "predicate") - } - - return &TapIterator{values, predicate}, nil -} - -func (iterator *TapIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - nextScope, err := iterator.values.Next(ctx, scope) - - if err != nil { - return nil, err - } - - _, err = iterator.predicate.Exec(ctx, nextScope) - - if err != nil { - return nil, err - } - - return nextScope, nil -} diff --git a/pkg/runtime/collections/tap_test.go b/pkg/runtime/collections/tap_test.go deleted file mode 100644 index 279724eb..00000000 --- a/pkg/runtime/collections/tap_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func tapIterator(values collections.Iterator, predicate core.Expression) collections.Iterator { - iter, _ := collections.NewTapIterator(values, predicate) - - return iter -} - -type TestExpression struct { - fn func(ctx context.Context, scope *core.Scope) (core.Value, error) -} - -func (exp *TestExpression) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) { - return exp.fn(ctx, scope) -} - -type ErrorIterator struct{} - -func (iterator *ErrorIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - return nil, core.ErrInvalidOperation -} - -func TestTapIterator(t *testing.T) { - Convey("Should iterate over a given iterator and execute a predicate", t, func() { - arr := values.NewArrayWith( - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - ) - - counter := 0 - - iter := tapIterator(arrayIterator(arr), &TestExpression{ - fn: func(ctx context.Context, scope *core.Scope) (core.Value, error) { - counter++ - - return values.None, nil - }, - }) - - ctx := context.Background() - scope, _ := core.NewRootScope() - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(res, ShouldHaveLength, int(arr.Length())) - So(counter, ShouldEqual, int(arr.Length())) - }) - - Convey("Should stop when a predicate return an error", t, func() { - arr := values.NewArrayWith( - values.NewInt(1), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(5), - ) - - counter := 0 - - iter := tapIterator(arrayIterator(arr), &TestExpression{ - fn: func(ctx context.Context, scope *core.Scope) (core.Value, error) { - counter++ - - return values.None, core.ErrInvalidOperation - }, - }) - - ctx := context.Background() - scope, _ := core.NewRootScope() - _, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldNotBeNil) - So(counter, ShouldEqual, 1) - }) - - Convey("Should not invoke a predicate when underlying iterator returns error", t, func() { - counter := 0 - - iter := tapIterator(&ErrorIterator{}, &TestExpression{ - fn: func(ctx context.Context, scope *core.Scope) (core.Value, error) { - counter++ - - return values.None, core.ErrInvalidOperation - }, - }) - - ctx := context.Background() - scope, _ := core.NewRootScope() - _, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldNotBeNil) - So(counter, ShouldEqual, 0) - }) - - Convey("Should not invoke a predicate when underlying iterator is empty", t, func() { - arr := values.NewArray(0) - - counter := 0 - - iter := tapIterator(arrayIterator(arr), &TestExpression{ - fn: func(ctx context.Context, scope *core.Scope) (core.Value, error) { - counter++ - - return values.None, core.ErrInvalidOperation - }, - }) - - ctx := context.Background() - scope, _ := core.NewRootScope() - res, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - So(res, ShouldHaveLength, 0) - So(counter, ShouldEqual, 0) - }) -} diff --git a/pkg/runtime/collections/unique.go b/pkg/runtime/collections/unique.go deleted file mode 100644 index d507248f..00000000 --- a/pkg/runtime/collections/unique.go +++ /dev/null @@ -1,55 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type ( - UniqueIterator struct { - values Iterator - hashes map[uint64]bool - hashKey string - } -) - -func NewUniqueIterator(values Iterator, hashKey string) (*UniqueIterator, error) { - if values == nil { - return nil, core.Error(core.ErrMissedArgument, "source") - } - - return &UniqueIterator{ - values: values, - hashes: make(map[uint64]bool), - hashKey: hashKey, - }, nil -} - -func (iterator *UniqueIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - for { - nextScope, err := iterator.values.Next(ctx, scope.Fork()) - - if err != nil { - return nil, err - } - - v, err := nextScope.GetVariable(iterator.hashKey) - - if err != nil { - return nil, err - } - - h := v.Hash() - - _, exists := iterator.hashes[h] - - if exists { - continue - } - - iterator.hashes[h] = true - - return nextScope, nil - } -} diff --git a/pkg/runtime/collections/unique_test.go b/pkg/runtime/collections/unique_test.go deleted file mode 100644 index c91833f7..00000000 --- a/pkg/runtime/collections/unique_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func TestUniqueIterator(t *testing.T) { - Convey("Should return only unique items", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(2), - values.NewInt(2), - values.NewInt(3), - values.NewInt(4), - values.NewInt(3), - values.NewInt(5), - values.NewInt(6), - values.NewInt(5), - values.NewInt(6), - } - - iter, err := collections.NewUniqueIterator( - sliceIterator(arr), - collections.DefaultValueVar, - ) - - So(err, ShouldBeNil) - ctx := context.Background() - scope, _ := core.NewRootScope() - - sets, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - res := toArrayOfValues(sets) - - So(res.String(), ShouldEqual, `[1,2,3,4,5,6]`) - }) - - Convey("Should return only unique items 2", t, func() { - arr := []core.Value{ - values.NewInt(1), - values.NewInt(1), - values.NewInt(1), - values.NewInt(1), - values.NewInt(1), - values.NewInt(1), - } - - iter, err := collections.NewUniqueIterator( - sliceIterator(arr), - collections.DefaultValueVar, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - sets, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - res := toArrayOfValues(sets) - - So(res.String(), ShouldEqual, `[1]`) - }) - - Convey("Should return only unique items 3", t, func() { - arr := []core.Value{ - values.NewString("a"), - values.NewString("b"), - values.NewString("c"), - values.NewString("d"), - values.NewString("e"), - values.NewString("a"), - values.NewString("b"), - values.NewString("f"), - values.NewString("d"), - values.NewString("e"), - values.NewString("f"), - } - - iter, err := collections.NewUniqueIterator( - sliceIterator(arr), - collections.DefaultValueVar, - ) - - So(err, ShouldBeNil) - - ctx := context.Background() - scope, _ := core.NewRootScope() - - sets, err := collections.ToSlice(ctx, scope, iter) - - So(err, ShouldBeNil) - - res := toArrayOfValues(sets) - - So(res.String(), ShouldEqual, `["a","b","c","d","e","f"]`) - }) -} diff --git a/pkg/runtime/collections/while.go b/pkg/runtime/collections/while.go deleted file mode 100644 index 405fe312..00000000 --- a/pkg/runtime/collections/while.go +++ /dev/null @@ -1,73 +0,0 @@ -package collections - -import ( - "context" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -type ( - WhileMode int - - WhilePredicate func(ctx context.Context, scope *core.Scope) (bool, error) - - WhileIterator struct { - mode WhileMode - predicate WhilePredicate - valVar string - pos int - } -) - -var ( - WhileModePost WhileMode - WhileModePre WhileMode = 1 -) - -func NewWhileIterator( - mode WhileMode, - valVar string, - predicate WhilePredicate, -) (Iterator, error) { - if valVar == "" { - return nil, core.Error(core.ErrMissedArgument, "value variable") - } - - if predicate == nil { - return nil, core.Error(core.ErrMissedArgument, "predicate") - } - - return &WhileIterator{mode, predicate, valVar, 0}, nil -} - -func NewDefaultWhileIterator(mode WhileMode, predicate WhilePredicate) (Iterator, error) { - return NewWhileIterator(mode, DefaultValueVar, predicate) -} - -func (iterator *WhileIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { - // if it's Post conditional execution, step in always - // Otherwise, it's not the first iteration - if iterator.mode == WhileModePost || iterator.pos > 0 { - doNext, err := iterator.predicate(ctx, scope) - - if err != nil { - return nil, err - } - - if !doNext { - return nil, core.ErrNoMoreData - } - } - - counter := values.NewInt(iterator.pos) - iterator.pos++ - - nextScope := scope.Fork() - - if err := nextScope.SetVariable(iterator.valVar, counter); err != nil { - return nil, err - } - - return nextScope, nil -} diff --git a/pkg/runtime/collections/while_pre_test.go b/pkg/runtime/collections/while_pre_test.go deleted file mode 100644 index 4c936004..00000000 --- a/pkg/runtime/collections/while_pre_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestDoWhileIterator(t *testing.T) { - Convey("Should iterate while a predicate returns true", t, func() { - predicateCounter := 0 - iterationCounter := 0 - expectedCount := 10 - - iterator, err := collections.NewDefaultWhileIterator(collections.WhileModePre, func(ctx context.Context, scope *core.Scope) (bool, error) { - if predicateCounter == (expectedCount - 1) { - return false, nil - } - - predicateCounter++ - - return true, nil - }) - - So(err, ShouldBeNil) - - scope, fn := core.NewRootScope() - defer fn() - err = collections.ForEach(context.Background(), scope, iterator, func(ctx context.Context, scope *core.Scope) bool { - iterationCounter++ - - return true - }) - - So(err, ShouldBeNil) - So(iterationCounter, ShouldEqual, expectedCount) - }) - - Convey("Should iterate once if a predicate returns false", t, func() { - iterationCounter := 0 - expectedCount := 1 - - iterator, err := collections.NewDefaultWhileIterator(collections.WhileModePre, func(ctx context.Context, scope *core.Scope) (bool, error) { - return false, nil - }) - - So(err, ShouldBeNil) - - scope, fn := core.NewRootScope() - defer fn() - err = collections.ForEach(context.Background(), scope, iterator, func(ctx context.Context, scope *core.Scope) bool { - iterationCounter++ - - return true - }) - - So(err, ShouldBeNil) - So(iterationCounter, ShouldEqual, expectedCount) - }) -} diff --git a/pkg/runtime/collections/while_test.go b/pkg/runtime/collections/while_test.go deleted file mode 100644 index 97295b60..00000000 --- a/pkg/runtime/collections/while_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package collections_test - -import ( - "context" - "testing" - - "github.com/MontFerret/ferret/pkg/runtime/collections" - "github.com/MontFerret/ferret/pkg/runtime/core" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestWhileIterator(t *testing.T) { - Convey("Should iterate while a predicate returns true", t, func() { - predicateCounter := 0 - iterationCounter := 0 - expectedCount := 10 - - iterator, err := collections.NewDefaultWhileIterator(collections.WhileModePost, func(ctx context.Context, scope *core.Scope) (bool, error) { - if predicateCounter == expectedCount { - return false, nil - } - - predicateCounter++ - - return true, nil - }) - - So(err, ShouldBeNil) - - scope, fn := core.NewRootScope() - defer fn() - err = collections.ForEach(context.Background(), scope, iterator, func(ctx context.Context, scope *core.Scope) bool { - iterationCounter++ - - return true - }) - - So(err, ShouldBeNil) - So(iterationCounter, ShouldEqual, expectedCount) - }) - - Convey("Should not iterate if a predicate returns false", t, func() { - iterationCounter := 0 - expectedCount := 0 - - iterator, err := collections.NewDefaultWhileIterator(collections.WhileModePost, func(ctx context.Context, scope *core.Scope) (bool, error) { - return false, nil - }) - - So(err, ShouldBeNil) - - scope, fn := core.NewRootScope() - defer fn() - err = collections.ForEach(context.Background(), scope, iterator, func(ctx context.Context, scope *core.Scope) bool { - iterationCounter++ - - return true - }) - - So(err, ShouldBeNil) - So(iterationCounter, ShouldEqual, expectedCount) - }) -} diff --git a/pkg/runtime/core/cloneable.go b/pkg/runtime/core/cloneable.go index a382e9d7..0d8cf393 100644 --- a/pkg/runtime/core/cloneable.go +++ b/pkg/runtime/core/cloneable.go @@ -1,5 +1,8 @@ package core +// Cloneable represents an interface of a value that can be cloned. +// The difference between Copy and Clone is that Copy returns a shallow copy of the value +// and Clone returns a deep copy of the value. type Cloneable interface { Value Clone() Cloneable diff --git a/pkg/runtime/core/collections.go b/pkg/runtime/core/collections.go new file mode 100644 index 00000000..c2609e82 --- /dev/null +++ b/pkg/runtime/core/collections.go @@ -0,0 +1,13 @@ +package core + +import "context" + +type ( + Indexed interface { + GetByIndex(ctx context.Context, idx int) (Value, error) + } + + Keyed interface { + GetByKey(ctx context.Context, key string) (Value, error) + } +) diff --git a/pkg/runtime/core/comparable.go b/pkg/runtime/core/comparable.go new file mode 100644 index 00000000..dfc576ce --- /dev/null +++ b/pkg/runtime/core/comparable.go @@ -0,0 +1,5 @@ +package core + +type Comparable interface { + Compare(other Value) int64 +} diff --git a/pkg/runtime/core/errors.go b/pkg/runtime/core/errors.go index a011deaf..1a57343f 100644 --- a/pkg/runtime/core/errors.go +++ b/pkg/runtime/core/errors.go @@ -13,61 +13,8 @@ type ( BaseError error ComputeError error } - - // PathError represents an interface of - // error type which returned when an error occurs during an execution of Getter.GetIn or Setter.SetIn functions - // and contains segment of a given path that caused the error. - PathError interface { - error - Cause() error - Segment() int - Format(path []Value) string - } - - // NativePathError represents a default implementation of GetterError interface. - NativePathError struct { - cause error - segment int - } ) -// NewPathError is a constructor function of NativePathError struct. -func NewPathError(err error, segment int) PathError { - return &NativePathError{ - cause: err, - segment: segment, - } -} - -// NewPathErrorFrom is a constructor function of NativePathError struct -// that accepts nested PathError and original segment index. -// It sums indexes to get the correct one that points to original path. -func NewPathErrorFrom(err PathError, segment int) PathError { - return NewPathError(err.Cause(), err.Segment()+segment) -} - -func (e *NativePathError) Cause() error { - return e.cause -} - -func (e *NativePathError) Error() string { - return e.cause.Error() -} - -func (e *NativePathError) Segment() int { - return e.segment -} - -func (e *NativePathError) Format(path []Value) string { - err := e.cause - - if err == ErrInvalidPath && len(path) > e.segment { - return err.Error() + " '" + path[e.segment].String() + "'" - } - - return err.Error() -} - func (e *SourceErrorDetail) Error() string { return e.ComputeError.Error() } @@ -99,7 +46,9 @@ func SourceError(src SourceMap, err error) error { } } -func TypeError(actual Type, expected ...Type) error { +func TypeError(value Value, expected ...Type) error { + actual := Reflect(value) + if len(expected) == 0 { return Error(ErrInvalidType, actual.String()) } @@ -139,10 +88,6 @@ func Errors(err ...error) error { return errors.New(message) } -func IsNoMoreData(err error) bool { - return err == ErrNoMoreData -} - func IsDone(err error) bool { return err == ErrDone } diff --git a/pkg/runtime/core/expression.go b/pkg/runtime/core/expression.go deleted file mode 100644 index f38e022a..00000000 --- a/pkg/runtime/core/expression.go +++ /dev/null @@ -1,21 +0,0 @@ -package core - -import "context" - -type ( - Expression interface { - Exec(ctx context.Context, scope *Scope) (Value, error) - } - - ExpressionFn struct { - fn func(ctx context.Context, scope *Scope) (Value, error) - } -) - -func AsExpression(fn func(ctx context.Context, scope *Scope) (Value, error)) Expression { - return &ExpressionFn{fn} -} - -func (f *ExpressionFn) Exec(ctx context.Context, scope *Scope) (Value, error) { - return f.fn(ctx, scope) -} diff --git a/pkg/runtime/core/getter.go b/pkg/runtime/core/getter.go deleted file mode 100644 index 3d09b8e7..00000000 --- a/pkg/runtime/core/getter.go +++ /dev/null @@ -1,25 +0,0 @@ -package core - -import "context" - -type ( - GetterPathIterator interface { - Path() []Value - Current() Value - CurrentIndex() int - } - - // Getter represents an interface of - // complex types that needs to be used to read values by path. - // The interface is created to let user-defined types be used in dot notation data access. - Getter interface { - GetIn(ctx context.Context, path []Value) (Value, PathError) - } - - GetterV2 interface { - GetIn(ctx context.Context, path Value) (Value, error) - } - - // GetterFn represents a type of helper functions that implement complex path resolutions. - GetterFn func(ctx context.Context, path []Value, src Getter) (Value, PathError) -) diff --git a/pkg/runtime/core/helpers.go b/pkg/runtime/core/helpers.go index ddb20b82..0e8ba668 100644 --- a/pkg/runtime/core/helpers.go +++ b/pkg/runtime/core/helpers.go @@ -47,9 +47,8 @@ func NumberLowerBoundary(input float64) float64 { } func RandomDefault() float64 { - rand.Seed(time.Now().UnixNano()) - - return rand.Float64() + rnd := rand.New(rand.NewSource(time.Now().UnixNano())) + return rnd.Float64() } func Random(max float64, min float64) float64 { @@ -68,13 +67,19 @@ func Random2(mid float64) float64 { func ForEach(ctx context.Context, iter Iterator, predicate func(value Value, key Value) bool) error { for { - value, key, err := iter.Next(ctx) + hasNext, err := iter.HasNext(ctx) if err != nil { - if IsNoMoreData(err) { - return nil - } + return err + } + + if !hasNext { + return nil + } + value, key, err := iter.Next(ctx) + + if err != nil { return err } diff --git a/pkg/runtime/core/iterator.go b/pkg/runtime/core/iterator.go new file mode 100644 index 00000000..e1de53a9 --- /dev/null +++ b/pkg/runtime/core/iterator.go @@ -0,0 +1,16 @@ +package core + +import "context" + +type ( + // Iterable represents an interface of a value that can be iterated by using an iterator. + Iterable interface { + Iterate(ctx context.Context) (Iterator, error) + } + + // Iterator represents an interface of an iterator. + Iterator interface { + HasNext(ctx context.Context) (bool, error) + Next(ctx context.Context) (value Value, key Value, err error) + } +) diff --git a/pkg/runtime/core/measurable.go b/pkg/runtime/core/measurable.go new file mode 100644 index 00000000..a3ff5c8a --- /dev/null +++ b/pkg/runtime/core/measurable.go @@ -0,0 +1,5 @@ +package core + +type Measurable interface { + Length() int +} diff --git a/pkg/runtime/core/predicate.go b/pkg/runtime/core/predicate.go deleted file mode 100644 index 3073d350..00000000 --- a/pkg/runtime/core/predicate.go +++ /dev/null @@ -1,8 +0,0 @@ -package core - -import "context" - -type Predicate interface { - Expression - Eval(ctx context.Context, left, right Value) (Value, error) -} diff --git a/pkg/runtime/core/reflectable.go b/pkg/runtime/core/reflectable.go new file mode 100644 index 00000000..49ef04a8 --- /dev/null +++ b/pkg/runtime/core/reflectable.go @@ -0,0 +1,20 @@ +package core + +import "reflect" + +// Reflectable Represents a value can reflect its own type. +type Reflectable interface { + Type() Type +} + +func Reflect(input Value) Type { + reflectable, ok := input.(Reflectable) + + if ok { + return reflectable.Type() + } + + typeDesc := reflect.TypeOf(input) + + return NewType(typeDesc.PkgPath(), typeDesc.Name()) +} diff --git a/pkg/runtime/core/scope.go b/pkg/runtime/core/scope.go deleted file mode 100644 index f4634e7a..00000000 --- a/pkg/runtime/core/scope.go +++ /dev/null @@ -1,154 +0,0 @@ -package core - -import ( - "io" -) - -type ( - CloseFunc func() error - - RootScope struct { - closed bool - disposables []io.Closer - } - - Scope struct { - root *RootScope - parent *Scope - vars map[string]Value - } -) - -func NewRootScope() (*Scope, CloseFunc) { - root := &RootScope{ - closed: false, - disposables: make([]io.Closer, 0, 10), - } - - return newScope(root, nil), root.Close -} - -func (s *RootScope) AddDisposable(disposable io.Closer) { - if s.closed { - return - } - - if disposable != nil { - s.disposables = append(s.disposables, disposable) - } -} - -func (s *RootScope) Close() error { - if s.closed { - return Error(ErrInvalidOperation, "scope is already closed") - } - - s.closed = true - - var errors []error - - // close all values implemented io.Close - for _, c := range s.disposables { - if err := c.Close(); err != nil { - if errors == nil { - errors = make([]error, 0, len(s.disposables)) - } - - errors = append(errors, err) - } - } - - if errors == nil { - return nil - } - - return Errors(errors...) -} - -func newScope(root *RootScope, parent *Scope) *Scope { - return &Scope{ - root: root, - parent: parent, - vars: make(map[string]Value), - } -} - -func (s *Scope) SetVariable(name string, val Value) error { - if name != IgnorableVariable { - _, exists := s.vars[name] - - // it already has been declared in the current scope - if exists { - return Errorf(ErrNotUnique, "variable is already declared: '%s'", name) - } - - s.vars[name] = val - } - - // we still want to make sure that nothing than needs to be closed leaks out - disposable, ok := val.(io.Closer) - - if ok { - s.root.AddDisposable(disposable) - } - - return nil -} - -func (s *Scope) HasVariable(name string) bool { - _, exists := s.vars[name] - - // does not exist in the current scope - // try to find in a parent scope - if !exists { - if s.parent != nil { - return s.parent.HasVariable(name) - } - } - - return exists -} - -func (s *Scope) GetVariable(name string) (Value, error) { - out, exists := s.vars[name] - - // does not exist in the current scope - // try to find in the parent scope - if !exists { - if s.parent != nil { - return s.parent.GetVariable(name) - } - - return nil, Errorf(ErrNotFound, "variable: '%s'", name) - } - - return out, nil -} - -func (s *Scope) MustGetVariable(name string) Value { - out, err := s.GetVariable(name) - - if err != nil { - panic(err) - } - - return out -} - -func (s *Scope) UpdateVariable(name string, val Value) error { - _, exists := s.vars[name] - - if !exists { - return Errorf(ErrNotFound, "variable: '%s'", name) - } - - delete(s.vars, name) - - return s.SetVariable(name, val) -} - -func (s *Scope) Fork() *Scope { - child := newScope(s.root, s) - - return child -} diff --git a/pkg/runtime/core/scope_test.go b/pkg/runtime/core/scope_test.go deleted file mode 100644 index 86fc1112..00000000 --- a/pkg/runtime/core/scope_test.go +++ /dev/null @@ -1,253 +0,0 @@ -package core_test - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" -) - -func TestScope(t *testing.T) { - Convey(".SetVariable", t, func() { - Convey("Should set a new variable", func() { - rs, cf := core.NewRootScope() - - So(cf, ShouldNotBeNil) - - err := rs.SetVariable("foo", values.NewString("bar")) - - So(err, ShouldBeNil) - }) - - Convey("Should return an error when a variable is already defined", func() { - rs, cf := core.NewRootScope() - - So(cf, ShouldNotBeNil) - - err := rs.SetVariable("foo", values.NewString("bar")) - So(err, ShouldBeNil) - - err = rs.SetVariable("foo", values.NewString("bar")) - So(err, ShouldHaveSameTypeAs, core.ErrNotUnique) - }) - }) - - Convey(".GetVariable", t, func() { - Convey("Should set and get a variable", func() { - rs, cf := core.NewRootScope() - - So(cf, ShouldNotBeNil) - - err := rs.SetVariable("foo", values.NewString("bar")) - So(err, ShouldBeNil) - - v, err := rs.GetVariable("foo") - - So(err, ShouldBeNil) - So(v, ShouldEqual, "bar") - }) - - Convey("Should return an error when variable is not defined", func() { - rs, cf := core.NewRootScope() - - So(cf, ShouldNotBeNil) - - _, err := rs.GetVariable("foo") - - So(err, ShouldNotBeNil) - }) - }) - - Convey(".HasVariable", t, func() { - Convey("Should return TRUE when a variable exists", func() { - rs, cf := core.NewRootScope() - - So(cf, ShouldNotBeNil) - - err := rs.SetVariable("foo", values.NewString("bar")) - So(err, ShouldBeNil) - - exists := rs.HasVariable("foo") - - So(exists, ShouldBeTrue) - }) - - Convey("Should return FALSE when a variable exists", func() { - rs, cf := core.NewRootScope() - - So(cf, ShouldNotBeNil) - - exists := rs.HasVariable("foo") - - So(exists, ShouldBeFalse) - }) - }) - - Convey(".Fork", t, func() { - Convey("Should create a nested scope", func() { - Convey("Should set a variable only in a child scope", func() { - rs, cf := core.NewRootScope() - So(cf, ShouldNotBeNil) - - cs := rs.Fork() - cs.SetVariable("foo", values.NewString("bar")) - - exists := rs.HasVariable("foo") - - So(exists, ShouldBeFalse) - }) - - Convey("Should return a variable defined only in a child scope", func() { - rs, cf := core.NewRootScope() - So(cf, ShouldNotBeNil) - - cs := rs.Fork() - err := cs.SetVariable("foo", values.NewString("bar")) - So(err, ShouldBeNil) - - v, err := cs.GetVariable("foo") - - So(err, ShouldBeNil) - So(v, ShouldEqual, "bar") - }) - - Convey("Should return a variable defined only in a parent scope", func() { - rs, cf := core.NewRootScope() - So(cf, ShouldNotBeNil) - - cs := rs.Fork() - err := cs.SetVariable("foo", values.NewString("bar")) - So(err, ShouldBeNil) - - err = rs.SetVariable("faz", values.NewString("qaz")) - So(err, ShouldBeNil) - - v, err := cs.GetVariable("faz") - - So(err, ShouldBeNil) - So(v, ShouldEqual, "qaz") - }) - - Convey("Should set a new variable with a same name defined in a parent scope", func() { - rs, cf := core.NewRootScope() - So(cf, ShouldNotBeNil) - - err := rs.SetVariable("foo", values.NewString("bar")) - So(err, ShouldBeNil) - - cs := rs.Fork() - err = cs.SetVariable("foo", values.NewString("faz")) - So(err, ShouldBeNil) - - rsV, err := rs.GetVariable("foo") - So(err, ShouldBeNil) - - csV, err := cs.GetVariable("foo") - So(err, ShouldBeNil) - - So(csV, ShouldNotEqual, rsV) - }) - }) - }) -} - -func BenchmarkScope(b *testing.B) { - root, _ := core.NewRootScope() - - for n := 0; n < b.N; n++ { - root.Fork() - } -} - -type ( - TestCloserType struct{} - - TestCloserValue struct { - closed bool - } -) - -func (tct TestCloserType) ID() int64 { - return 99 -} - -func (tct TestCloserType) String() string { - return "TestCloser" -} - -func (tct TestCloserType) Equals(other core.Type) bool { - return other.ID() == tct.ID() -} - -func (tc *TestCloserValue) MarshalJSON() ([]byte, error) { - return nil, core.ErrNotImplemented -} - -func (tc *TestCloserValue) Type() core.Type { - return TestCloserType{} -} - -func (tc *TestCloserValue) String() string { - return "" -} - -func (tc *TestCloserValue) Compare(other core.Value) int64 { - return 0 -} - -func (tc *TestCloserValue) Unwrap() interface{} { - return tc -} - -func (tc *TestCloserValue) Hash() uint64 { - return 0 -} - -func (tc *TestCloserValue) Copy() core.Value { - return &TestCloserValue{} -} - -func (tc *TestCloserValue) Close() error { - if tc.closed { - return core.Error(core.ErrInvalidOperation, "already closed") - } - - tc.closed = true - - return nil -} - -func TestCloseFunc(t *testing.T) { - Convey("Should close root scope and close all io.Closer values", t, func() { - rs, cf := core.NewRootScope() - - tc := &TestCloserValue{} - - rs.SetVariable("disposable", tc) - So(tc.closed, ShouldBeFalse) - - err := cf() - So(err, ShouldBeNil) - - So(tc.closed, ShouldBeTrue) - }) - - Convey("Should return error if it's already closed", t, func() { - rs, cf := core.NewRootScope() - - tc := &TestCloserValue{} - - rs.SetVariable("disposable", tc) - So(tc.closed, ShouldBeFalse) - - err := cf() - So(err, ShouldBeNil) - - So(tc.closed, ShouldBeTrue) - - err = cf() - So(err, ShouldHaveSameTypeAs, core.ErrInvalidOperation) - }) -} diff --git a/pkg/runtime/core/setter.go b/pkg/runtime/core/setter.go deleted file mode 100644 index d262c8dd..00000000 --- a/pkg/runtime/core/setter.go +++ /dev/null @@ -1,12 +0,0 @@ -package core - -import "context" - -type ( - // Setter represents an interface of - // complex types that needs to be used to write values by path. - // The interface is created to let user-defined types be used in dot notation assignment. - Setter interface { - SetIn(ctx context.Context, path []Value, value Value) PathError - } -) diff --git a/pkg/runtime/core/type.go b/pkg/runtime/core/type.go index c33395fa..9c585b27 100644 --- a/pkg/runtime/core/type.go +++ b/pkg/runtime/core/type.go @@ -1,56 +1,54 @@ package core -import ( - "math/rand" +import "math/rand" - "github.com/pkg/errors" -) - -// Type represents runtime type with id for quick type check -// and GetName for error messages - -//revive:disable-next-line:redefines-builtin-id type ( Type interface { ID() int64 + Namespace() string + Name() string String() string - Equals(other Type) bool } - BaseType struct { - id int64 - name string + GenericType struct { + id int64 + namespace string + name string } ) -func NewType(name string) Type { - return BaseType{rand.Int63(), name} +func NewType(namespace, name string) Type { + return &GenericType{rand.Int63(), namespace, name} +} + +func (b *GenericType) ID() int64 { + return b.id } -func (t BaseType) ID() int64 { - return t.id +func (b *GenericType) Namespace() string { + return b.namespace } -func (t BaseType) String() string { - return t.name +func (b *GenericType) Name() string { + return b.name } -func (t BaseType) Equals(other Type) bool { - return t.id == other.ID() +func (b *GenericType) String() string { + return b.namespace + "." + b.name } // IsTypeOf return true when value's type // is equal to check type. // Returns false, otherwise. func IsTypeOf(value Value, check Type) bool { - return value.Type().ID() == check.ID() + return Reflect(value).ID() == check.ID() } // ValidateType checks the match of // value's type and required types. func ValidateType(value Value, required ...Type) error { var valid bool - tid := value.Type().ID() + tid := Reflect(value).ID() for _, t := range required { if tid == t.ID() { @@ -60,62 +58,8 @@ func ValidateType(value Value, required ...Type) error { } if !valid { - return TypeError(value.Type(), required...) - } - - return nil -} - -// ValidateValueTypePairs validate pairs of -// Values and Types. -// Returns error when type didn't match -func ValidateValueTypePairs(pairs ...PairValueType) error { - var err error - - for idx, pair := range pairs { - err = ValidateType(pair.Value, pair.Types...) - - if err != nil { - return errors.Errorf("pair %d: %v", idx, err) - } + return TypeError(value, required...) } return nil } - -// PairValueType is a supporting -// structure that used in validateValueTypePairs. -type PairValueType struct { - Value Value - Types []Type -} - -// NewPairValueType it's a shortcut for creating a new PairValueType. -// -// The common pattern of using PairValueType is: -// ``` -// -// pairs := []core.PairValueType{ -// core.PairValueType{args[0], []core.Type{types.String}}, // go vet warning -// core.PairValueType{Value: args[1], Types: []core.Type{types.Binary}}, // too long -// } -// -// ``` -// With NewPairValueType there is no need to type `[]core.Type{...}` and code becomes -// more readable and maintainable. -// -// That is how the code above looks like with NewPairValueType: -// ``` -// -// pairs := []core.PairValueType{ -// core.NewPairValueType(args[0], types.String), -// core.NewPairValueType(args[1], types.Binary), -// } -// -// ``` -func NewPairValueType(value Value, types ...Type) PairValueType { - return PairValueType{ - Value: value, - Types: types, - } -} diff --git a/pkg/runtime/core/type_test.go b/pkg/runtime/core/type_test.go deleted file mode 100644 index 07e6a0a4..00000000 --- a/pkg/runtime/core/type_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package core_test - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/core" -) - -type ( - Value struct { - type_ core.Type - } - - TypeA struct{} - - TypeB struct{} - - TypeC struct{} -) - -func (t Value) MarshalJSON() ([]byte, error) { - return nil, nil -} - -func (t Value) Type() core.Type { - return t.type_ -} - -func (t Value) String() string { - return "" -} - -func (t Value) Compare(other core.Value) int64 { - return 0 -} - -func (t Value) Unwrap() interface{} { - return nil -} - -func (t Value) Hash() uint64 { - return 0 -} - -func (t Value) Copy() core.Value { - return t -} - -func (t TypeA) ID() int64 { - return 1 -} - -func (t TypeA) String() string { - return "type_a" -} - -func (t TypeA) Equals(other core.Type) bool { - return t.ID() == other.ID() -} - -func (t TypeB) ID() int64 { - return 2 -} - -func (t TypeB) String() string { - return "type_b" -} - -func (t TypeB) Equals(other core.Type) bool { - return t.ID() == other.ID() -} - -func (t TypeC) ID() int64 { - return 3 -} - -func (t TypeC) String() string { - return "type_c" -} - -func (t TypeC) Equals(other core.Type) bool { - return t.ID() == other.ID() -} - -func TestType(t *testing.T) { - typeA := TypeA{} - typeB := TypeB{} - - Convey("IsTypeOf", t, func() { - Convey("Should return 'false' when types are different", func() { - vA := Value{typeA} - - So(core.IsTypeOf(vA, typeB), ShouldBeFalse) - }) - }) -} - -func TestValidateType(t *testing.T) { - typeA := TypeA{} - typeB := TypeB{} - - Convey("Should validate types", t, func() { - vA := Value{typeA} - vB := Value{typeB} - - So(core.ValidateType(vA, typeA), ShouldBeNil) - So(core.ValidateType(vB, typeA), ShouldNotBeNil) - }) -} diff --git a/pkg/runtime/core/value.go b/pkg/runtime/core/value.go index 7fda37a4..f46ebb57 100644 --- a/pkg/runtime/core/value.go +++ b/pkg/runtime/core/value.go @@ -1,31 +1,15 @@ package core import ( - "context" "encoding/json" ) -type ( - // Value represents an interface of - // any type that needs to be used during runtime - Value interface { - json.Marshaler - Type() Type - String() string - Compare(other Value) int64 - Unwrap() interface{} - Hash() uint64 - Copy() Value - } - - // Iterable represents an interface of a value that can be iterated by using an iterator. - Iterable interface { - Iterate(ctx context.Context) (Iterator, error) - } - - // Iterator represents an interface of a value iterator. - // When iterator is exhausted it must return None as a value. - Iterator interface { - Next(ctx context.Context) (value Value, key Value, err error) - } -) +// Value represents an interface of +// any type that needs to be used during runtime +type Value interface { + json.Marshaler + String() string + Unwrap() interface{} + Hash() uint64 + Copy() Value +} diff --git a/pkg/runtime/events/iterator.go b/pkg/runtime/events/iterator.go index f2e52991..7a3e82d6 100644 --- a/pkg/runtime/events/iterator.go +++ b/pkg/runtime/events/iterator.go @@ -9,25 +9,36 @@ import ( type Iterator struct { messages <-chan Message + message Message } func NewIterator(ch <-chan Message) core.Iterator { - return &Iterator{ch} + return &Iterator{ch, nil} } -func (e *Iterator) Next(ctx context.Context) (value core.Value, key core.Value, err error) { +func (e *Iterator) HasNext(ctx context.Context) (bool, error) { select { case evt, ok := <-e.messages: if !ok { - return values.None, values.None, core.ErrNoMoreData + return false, nil } - if err := evt.Err(); err != nil { + e.message = evt + + return true, nil + case <-ctx.Done(): + return false, ctx.Err() + } +} + +func (e *Iterator) Next(_ context.Context) (value core.Value, key core.Value, err error) { + if e.message != nil { + if err := e.message.Err(); err != nil { return values.None, values.None, err } - return evt.Value(), values.None, nil - case <-ctx.Done(): - return values.None, values.None, ctx.Err() + return e.message.Value(), values.None, nil } + + return values.None, values.None, core.ErrNoMoreData } diff --git a/pkg/runtime/globals.go b/pkg/runtime/globals.go new file mode 100644 index 00000000..7ccdf5f6 --- /dev/null +++ b/pkg/runtime/globals.go @@ -0,0 +1 @@ +package runtime diff --git a/pkg/runtime/opcodes.go b/pkg/runtime/opcodes.go index d69fa1d9..55a31346 100644 --- a/pkg/runtime/opcodes.go +++ b/pkg/runtime/opcodes.go @@ -10,12 +10,12 @@ const ( OpFalse OpArray OpObject - OpSetGlobal - OpGetGlobal - OpGetLocal - OpSetLocal - OpGetProperty - OpGetPropertyOptional + OpLoadGlobal + OpStoreGlobal + OpLoadLocal + OpStoreLocal + OpLoadProperty + OpLoadPropertyOptional OpNegate OpFlipPositive OpFlipNegative @@ -52,6 +52,10 @@ const ( OpJumpIfTrue OpJump OpLoopInit + OpLoopHasNext + OpLoopNext + OpLoopNextValue + OpLoopNextCounter OpLoop OpLoopPush OpReturn diff --git a/pkg/runtime/operators/like.go b/pkg/runtime/operators/like.go index 614eb32b..e36fe1e3 100644 --- a/pkg/runtime/operators/like.go +++ b/pkg/runtime/operators/like.go @@ -1,25 +1,19 @@ package operators import ( - "github.com/gobwas/glob" - "github.com/pkg/errors" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" + "github.com/gobwas/glob" + "github.com/pkg/errors" ) func Like(left, right core.Value) (values.Boolean, error) { - err := core.ValidateType(right, types.String) - - if err != nil { + if err := values.AssertString(left); err != nil { // TODO: Return the error? AQL just returns false return values.False, nil } - err = core.ValidateType(left, types.String) - - if err != nil { + if err := values.AssertString(right); err != nil { // TODO: Return the error? AQL just returns false return values.False, nil } diff --git a/pkg/runtime/operators/math.go b/pkg/runtime/operators/math.go index 2f4944a2..11f6c30c 100644 --- a/pkg/runtime/operators/math.go +++ b/pkg/runtime/operators/math.go @@ -3,252 +3,199 @@ package operators import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func Add(inputL, inputR core.Value) core.Value { left := values.ToNumberOrString(inputL) - right := values.ToNumberOrString(inputR) - if left.Type() == types.Int { - if right.Type() == types.Int { - l := left.(values.Int) - r := right.(values.Int) - - return l + r - } - - if right.Type() == types.Float { - l := left.(values.Int) - r := right.(values.Float) - - return values.Float(l) + r - } + switch leftVal := left.(type) { + case values.Int: + return addLeftInt(leftVal, inputR) + case values.Float: + return addLeftFloat(leftVal, inputR) + case values.String: + return addLeftString(leftVal, inputR) + default: + return values.String(leftVal.String() + inputR.String()) } +} - if left.Type() == types.Float { - if right.Type() == types.Float { - l := left.(values.Float) - r := right.(values.Float) +func addLeftInt(integer values.Int, input core.Value) core.Value { + right := values.ToNumberOrString(input) - return l + r - } + switch rightVal := right.(type) { + case values.Int: + return integer + rightVal + case values.Float: + return values.Float(integer) + rightVal + default: + return values.String(integer.String() + rightVal.String()) + } +} - if right.Type() == types.Int { - l := left.(values.Float) - r := right.(values.Int) +func addLeftFloat(float values.Float, input core.Value) core.Value { + right := values.ToNumberOrString(input) - return l + values.Float(r) - } + switch rightVal := right.(type) { + case values.Int: + return float + values.Float(rightVal) + case values.Float: + return float + rightVal + default: + return values.String(float.String() + rightVal.String()) } +} - return values.String(left.String() + right.String()) +func addLeftString(str values.String, input core.Value) core.Value { + return values.String(str.String() + input.String()) } func Subtract(inputL, inputR core.Value) core.Value { left := values.ToNumberOnly(inputL) - right := values.ToNumberOnly(inputR) - if left.Type() == types.Int { - if right.Type() == types.Int { - l := left.(values.Int) - r := right.(values.Int) - - return l - r - } - - if right.Type() == types.Float { - l := left.(values.Int) - r := right.(values.Float) - - return values.Float(l) - r - } + switch leftVal := left.(type) { + case values.Int: + return subtractLeftInt(leftVal, inputR) + case values.Float: + return subtractLeftFloat(leftVal, inputR) + default: + return values.ZeroInt } +} - if left.Type() == types.Float { - if right.Type() == types.Float { - l := left.(values.Float) - r := right.(values.Float) +func subtractLeftInt(integer values.Int, input core.Value) core.Value { + right := values.ToNumberOnly(input) - return l - r - } + switch rightVal := right.(type) { + case values.Int: + return integer - rightVal + case values.Float: + return values.Float(integer) - rightVal + default: + return values.ZeroInt + } +} - if right.Type() == types.Int { - l := left.(values.Float) - r := right.(values.Int) +func subtractLeftFloat(float values.Float, input core.Value) core.Value { + right := values.ToNumberOnly(input) - return l - values.Float(r) - } + switch rightVal := right.(type) { + case values.Int: + return float - values.Float(rightVal) + case values.Float: + return float - rightVal + default: + return values.ZeroInt } - - return values.ZeroInt } func Multiply(inputL, inputR core.Value) core.Value { left := values.ToNumberOnly(inputL) - right := values.ToNumberOnly(inputR) - if left.Type() == types.Int { - if right.Type() == types.Int { - l := left.(values.Int) - r := right.(values.Int) - - return l * r - } - - if right.Type() == types.Float { - l := left.(values.Int) - r := right.(values.Float) - - return values.Float(l) * r - } + switch leftVal := left.(type) { + case values.Int: + return multiplyLeftInt(leftVal, inputR) + case values.Float: + return multiplyLeftFloat(leftVal, inputR) + default: + return values.ZeroInt } +} - if left.Type() == types.Float { - if right.Type() == types.Float { - l := left.(values.Float) - r := right.(values.Float) +func multiplyLeftInt(integer values.Int, input core.Value) core.Value { + right := values.ToNumberOnly(input) - return l * r - } + switch rightVal := right.(type) { + case values.Int: + return integer * rightVal + case values.Float: + return values.Float(integer) * rightVal + default: + return values.ZeroInt + } +} - if right.Type() == types.Int { - l := left.(values.Float) - r := right.(values.Int) +func multiplyLeftFloat(float values.Float, input core.Value) core.Value { + right := values.ToNumberOnly(input) - return l * values.Float(r) - } + switch rightVal := right.(type) { + case values.Int: + return float * values.Float(rightVal) + case values.Float: + return float * rightVal + default: + return values.ZeroInt } - - return values.ZeroInt } func Divide(inputL, inputR core.Value) core.Value { left := values.ToNumberOnly(inputL) - right := values.ToNumberOnly(inputR) - if left.Type() == types.Int { - if right.Type() == types.Int { - l := values.Float(left.(values.Int)) - r := values.Float(right.(values.Int)) - - if r == 0.0 { - panic("divide by zero") - } - - return l / r - } - - if right.Type() == types.Float { - l := values.Float(left.(values.Int)) - r := right.(values.Float) - - if r == 0.0 { - panic("divide by zero") - } - - return l / r - } + switch leftVal := left.(type) { + case values.Int: + return divideLeftInt(leftVal, inputR) + case values.Float: + return divideLeftFloat(leftVal, inputR) + default: + return values.ZeroInt } +} - if left.Type() == types.Float { - if right.Type() == types.Float { - l := left.(values.Float) - r := right.(values.Float) - - if r == 0.0 { - panic("divide by zero") - } - - return l / r - } - - if right.Type() == types.Int { - l := left.(values.Float) - r := values.Float(right.(values.Int)) - - if r == 0.0 { - panic("divide by zero") - } +func divideLeftInt(integer values.Int, input core.Value) core.Value { + right := values.ToNumberOnly(input) - return l / r - } + switch rightVal := right.(type) { + case values.Int: + return integer / rightVal + case values.Float: + return values.Float(integer) / rightVal + default: + return values.ZeroInt } - - return values.ZeroInt } -func Modulus(inputL, inputR core.Value) core.Value { - left := values.ToNumberOnly(inputL) - right := values.ToNumberOnly(inputR) +func divideLeftFloat(float values.Float, input core.Value) core.Value { + right := values.ToNumberOnly(input) - if left.Type() == types.Int { - if right.Type() == types.Int { - l := left.(values.Int) - r := right.(values.Int) - - return l % r - } - - if right.Type() == types.Float { - l := left.(values.Int) - r := right.(values.Float) - - return l % values.Int(r) - } + switch rightVal := right.(type) { + case values.Int: + return float / values.Float(rightVal) + case values.Float: + return float / rightVal + default: + return values.ZeroInt } +} - if left.Type() == types.Float { - if right.Type() == types.Float { - l := left.(values.Float) - r := right.(values.Float) - - return values.Int(l) % values.Int(r) - } - - if right.Type() == types.Int { - l := left.(values.Float) - r := right.(values.Int) - - return values.Int(l) % r - } - } +func Modulus(inputL, inputR core.Value) core.Value { + left := values.ToInt(inputL) + right := values.ToInt(inputR) - return values.ZeroInt + return left % right } func Increment(input core.Value) core.Value { left := values.ToNumberOnly(input) - if left.Type() == types.Int { - l := left.(values.Int) - - return l + 1 - } - - if left.Type() == types.Float { - l := left.(values.Float) - - return l + 1 + switch value := left.(type) { + case values.Int: + return value + 1 + case values.Float: + return value + 1 + default: + return values.None } - - return values.None } func Decrement(input core.Value) core.Value { left := values.ToNumberOnly(input) - if left.Type() == types.Int { - l := left.(values.Int) - - return l - 1 - } - - if left.Type() == types.Float { - l := left.(values.Float) - - return l - 1 + switch value := left.(type) { + case values.Int: + return value - 1 + case values.Float: + return value - 1 + default: + return values.None } - - return values.None } diff --git a/pkg/runtime/operators/range.go b/pkg/runtime/operators/range.go index 5f76a439..8ab6c6ba 100644 --- a/pkg/runtime/operators/range.go +++ b/pkg/runtime/operators/range.go @@ -3,42 +3,15 @@ package operators import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func Range(left, right core.Value) (core.Value, error) { - err := core.ValidateType(left, types.Int, types.Float) + start := values.ToInt(left) + end := values.ToInt(right) - if err != nil { - return values.None, err + if start > end { + return values.None, nil } - err = core.ValidateType(right, types.Int, types.Float) - - if err != nil { - return values.None, err - } - - var start int - var end int - - if left.Type() == types.Float { - start = int(left.(values.Float)) - } else { - start = int(left.(values.Int)) - } - - if right.Type() == types.Float { - end = int(right.(values.Float)) - } else { - end = int(right.(values.Int)) - } - - arr := values.NewArray(10) - - for i := start; i <= end; i++ { - arr.Push(values.NewInt(i)) - } - - return arr, nil + return values.NewRange(uint64(start), uint64(end)), nil } diff --git a/pkg/runtime/program_test.go b/pkg/runtime/program_test.go deleted file mode 100644 index f7ab2685..00000000 --- a/pkg/runtime/program_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package runtime_test - -import ( - "testing" - - "github.com/MontFerret/ferret/pkg/runtime" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime_v2" -) - -func TestProgram(t *testing.T) { - Convey("Disassemble", t, func() { - Convey("Constants", t, func() { - Convey("Should return a string", func() { - p := runtime_v2.NewProgram([]runtime.Opcode{ - runtime.OpConstant, - }, []core.Value{ - values.String("test"), - }) - - out := p.Disassemble() - - So(out, ShouldEqual, "const 0\n") - }) - }) - }) -} diff --git a/pkg/runtime/values/array.go b/pkg/runtime/values/array.go index bc7cf524..5a0349be 100644 --- a/pkg/runtime/values/array.go +++ b/pkg/runtime/values/array.go @@ -3,13 +3,13 @@ package values import ( "context" "encoding/binary" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "sort" "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -18,28 +18,32 @@ type ( ArraySorter = func(first, second core.Value) bool Array struct { - items []core.Value + data []core.Value } ) func EmptyArray() *Array { - return &Array{items: make([]core.Value, 0, 0)} + return &Array{data: make([]core.Value, 0, 0)} } func NewArray(size int) *Array { - return &Array{items: make([]core.Value, 0, size)} + return &Array{data: make([]core.Value, 0, size)} } func NewSizedArray(size int) *Array { - return &Array{items: make([]core.Value, size)} + return &Array{data: make([]core.Value, size)} } func NewArrayWith(values ...core.Value) *Array { - return &Array{items: values} + return &Array{data: values} +} + +func (t *Array) Iterate(ctx context.Context) (core.Iterator, error) { + return NewArrayIterator(t), nil } func (t *Array) MarshalJSON() ([]byte, error) { - return jettison.MarshalOpts(t.items, jettison.NoHTMLEscaping()) + return jettison.MarshalOpts(t.data, jettison.NoHTMLEscaping()) } func (t *Array) Type() core.Type { @@ -57,41 +61,41 @@ func (t *Array) String() string { } func (t *Array) Compare(other core.Value) int64 { - if other.Type() == types.Array { - other := other.(*Array) + otherArr, ok := other.(*Array) - if t.Length() == 0 && other.Length() == 0 { - return 0 - } + if !ok { + return types.Compare(types.Array, core.Reflect(other)) + } - if t.Length() < other.Length() { - return -1 - } + if t.Length() == 0 && otherArr.Length() == 0 { + return 0 + } - if t.Length() > other.Length() { - return 1 - } + if t.Length() < otherArr.Length() { + return -1 + } - var res int64 - var val core.Value + if t.Length() > otherArr.Length() { + return 1 + } - other.ForEach(func(otherVal core.Value, idx int) bool { - val = t.Get(NewInt(idx)) - res = val.Compare(otherVal) + var res int64 + var val core.Value - return res == 0 - }) + otherArr.ForEach(func(otherVal core.Value, idx int) bool { + val = t.Get(NewInt(idx)) + res = Compare(val, otherVal) - return res - } + return res == 0 + }) - return types.Compare(types.Array, other.Type()) + return res } func (t *Array) Unwrap() interface{} { arr := make([]interface{}, t.Length()) - for idx, val := range t.items { + for idx, val := range t.data { arr[idx] = val.Unwrap() } @@ -101,13 +105,13 @@ func (t *Array) Unwrap() interface{} { func (t *Array) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(t.Type().String())) + h.Write([]byte(types.Array.String())) h.Write([]byte(":")) h.Write([]byte("[")) - endIndex := len(t.items) - 1 + endIndex := len(t.data) - 1 - for i, el := range t.items { + for i, el := range t.data { bytes := make([]byte, 8) binary.LittleEndian.PutUint64(bytes, el.Hash()) @@ -124,9 +128,9 @@ func (t *Array) Hash() uint64 { } func (t *Array) Copy() core.Value { - c := NewArray(len(t.items)) + c := NewArray(len(t.data)) - for _, el := range t.items { + for _, el := range t.data { c.Push(el) } @@ -134,11 +138,11 @@ func (t *Array) Copy() core.Value { } func (t *Array) Length() Int { - return Int(len(t.items)) + return Int(len(t.data)) } func (t *Array) ForEach(predicate ArrayPredicate) { - for idx, val := range t.items { + for idx, val := range t.data { if !predicate(val, idx) { break } @@ -146,29 +150,29 @@ func (t *Array) ForEach(predicate ArrayPredicate) { } func (t *Array) First() core.Value { - if len(t.items) > 0 { - return t.items[0] + if len(t.data) > 0 { + return t.data[0] } return None } func (t *Array) Last() core.Value { - size := len(t.items) + size := len(t.data) if size > 1 { - return t.items[size-1] + return t.data[size-1] } else if size == 1 { - return t.items[0] + return t.data[0] } return None } func (t *Array) Find(predicate ArrayPredicate) (*Array, Boolean) { - result := NewArray(len(t.items)) + result := NewArray(len(t.data)) - for idx, val := range t.items { + for idx, val := range t.data { if predicate(val, idx) { result.Push(val) } @@ -178,7 +182,7 @@ func (t *Array) Find(predicate ArrayPredicate) (*Array, Boolean) { } func (t *Array) FindOne(predicate ArrayPredicate) (core.Value, Boolean) { - for idx, val := range t.items { + for idx, val := range t.data { if predicate(val, idx) { return val, True } @@ -188,7 +192,7 @@ func (t *Array) FindOne(predicate ArrayPredicate) (core.Value, Boolean) { } func (t *Array) Get(idx Int) core.Value { - l := len(t.items) - 1 + l := len(t.data) - 1 if l < 0 { return None @@ -198,14 +202,14 @@ func (t *Array) Get(idx Int) core.Value { return None } - return t.items[idx] + return t.data[idx] } func (t *Array) Set(idx Int, value core.Value) error { - last := len(t.items) - 1 + last := len(t.data) - 1 if last >= int(idx) { - t.items[idx] = value + t.data[idx] = value return nil } @@ -214,11 +218,11 @@ func (t *Array) Set(idx Int, value core.Value) error { } func (t *Array) MustSet(idx Int, value core.Value) { - t.items[idx] = value + t.data[idx] = value } func (t *Array) Push(item core.Value) { - t.items = append(t.items, item) + t.data = append(t.data, item) } func (t *Array) Slice(from, to Int) *Array { @@ -233,7 +237,7 @@ func (t *Array) Slice(from, to Int) *Array { } result := new(Array) - result.items = t.items[from:to] + result.data = t.data[from:to] return result } @@ -245,8 +249,8 @@ func (t *Array) Contains(item core.Value) Boolean { func (t *Array) IndexOf(item core.Value) Int { res := Int(-1) - for idx, el := range t.items { - if el.Compare(item) == 0 { + for idx, el := range t.data { + if Compare(item, el) == 0 { res = Int(idx) break } @@ -256,18 +260,18 @@ func (t *Array) IndexOf(item core.Value) Int { } func (t *Array) Insert(idx Int, value core.Value) { - t.items = append(t.items[:idx], append([]core.Value{value}, t.items[idx:]...)...) + t.data = append(t.data[:idx], append([]core.Value{value}, t.data[idx:]...)...) } func (t *Array) RemoveAt(idx Int) { i := int(idx) - max := len(t.items) - 1 + max := len(t.data) - 1 if i > max { return } - t.items = append(t.items[:i], t.items[i+1:]...) + t.data = append(t.data[:i], t.data[i+1:]...) } func (t *Array) Clone() core.Cloneable { @@ -291,52 +295,20 @@ func (t *Array) Clone() core.Cloneable { func (t *Array) Sort() *Array { return t.SortWith(func(first, second core.Value) bool { - return first.Compare(second) == -1 + return Compare(first, second) == -1 }) } func (t *Array) SortWith(sorter ArraySorter) *Array { - c := make([]core.Value, len(t.items)) - copy(c, t.items) + c := make([]core.Value, len(t.data)) + copy(c, t.data) sort.SliceStable(c, func(i, j int) bool { return sorter(c[i], c[j]) }) res := new(Array) - res.items = c + res.data = c return res } - -func (t *Array) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { - return None, nil - } - - segmentIdx := 0 - - if typ := path[segmentIdx].Type(); typ != types.Int { - return None, core.NewPathError(core.TypeError(typ, types.Int), segmentIdx) - } - - first := t.Get(path[segmentIdx].(Int)) - - if len(path) == 1 { - return first, nil - } - - segmentIdx++ - - if first == None || first == nil { - return None, core.NewPathError(core.ErrInvalidPath, segmentIdx) - } - - getter, ok := first.(core.Getter) - - if !ok { - return GetIn(ctx, first, path[segmentIdx:]) - } - - return getter.GetIn(ctx, path[segmentIdx:]) -} diff --git a/pkg/runtime/values/array_iter.go b/pkg/runtime/values/array_iter.go new file mode 100644 index 00000000..88d083a3 --- /dev/null +++ b/pkg/runtime/values/array_iter.go @@ -0,0 +1,28 @@ +package values + +import ( + "context" + "github.com/MontFerret/ferret/pkg/runtime/core" +) + +type ArrayIterator struct { + pos int + values *Array +} + +func NewArrayIterator(values *Array) core.Iterator { + return &ArrayIterator{values: values, pos: 0} +} + +func (iterator *ArrayIterator) HasNext(_ context.Context) (bool, error) { + return int(iterator.values.Length()) > iterator.pos, nil +} + +func (iterator *ArrayIterator) Next(_ context.Context) (value core.Value, key core.Value, err error) { + idx := NewInt(iterator.pos) + val := iterator.values.Get(idx) + + iterator.pos++ + + return val, idx, nil +} diff --git a/pkg/runtime/values/array_test.go b/pkg/runtime/values/array_test.go index 8d9dfd50..94469f63 100644 --- a/pkg/runtime/values/array_test.go +++ b/pkg/runtime/values/array_test.go @@ -1,14 +1,11 @@ package values_test import ( - "context" "encoding/json" "testing" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" - . "github.com/smartystreets/goconvey/convey" ) @@ -55,14 +52,6 @@ func TestArray(t *testing.T) { }) }) - Convey(".Type", t, func() { - Convey("Should return type", func() { - arr := values.NewArray(1) - - So(arr.Type().Equals(types.Array), ShouldBeTrue) - }) - }) - Convey(".Unwrap", t, func() { Convey("Should return a an array of unwrapped values", func() { arr := values.NewArrayWith( @@ -563,90 +552,4 @@ func TestArray(t *testing.T) { So(nestedInArr.Compare(nestedInClone), ShouldNotEqual, 0) }) }) - - Convey(".GetIn", t, func() { - - ctx := context.Background() - - Convey("Should return the same as .Get when input is correct", func() { - - Convey("Should return item by key", func() { - key := values.NewInt(0) - arr := values.NewArrayWith( - values.NewInt(0), - ) - - el, err := arr.GetIn(ctx, []core.Value{key}) - elGet := arr.Get(key) - - So(err, ShouldBeNil) - So(el.Compare(elGet), ShouldEqual, 0) - }) - - Convey("Should return None when no items", func() { - key := values.NewInt(0) - arr := values.NewArray(0) - - el, err := arr.GetIn(ctx, []core.Value{key}) - elGet := arr.Get(key) - - So(err, ShouldBeNil) - So(el.Compare(elGet), ShouldEqual, 0) - }) - }) - - Convey("Should error when input is not correct", func() { - - Convey("Should error when path[0] is not an int", func() { - arr := values.NewArray(0) - path := []core.Value{values.NewString("")} - - el, err := arr.GetIn(ctx, path) - - So(err, ShouldBeError) - So(el.Compare(values.None), ShouldEqual, 0) - }) - - Convey("Should error when first received item is not a Getter and len(path) > 1", func() { - key := values.NewInt(0) - arr := values.NewArrayWith( - values.NewInt(1), - ) - path := []core.Value{key, key} - - el, err := arr.GetIn(ctx, path) - - So(err, ShouldBeError) - So(el.Compare(values.None), ShouldEqual, 0) - }) - }) - - Convey("Should return None when len(path) == 0", func() { - arr := values.NewArrayWith( - values.NewInt(1), - ) - - el, err := arr.GetIn(ctx, nil) - - So(err, ShouldBeNil) - So(el.Compare(values.None), ShouldEqual, 0) - }) - - Convey("Should call the nested Getter", func() { - key := values.NewInt(0) - arr := values.NewArrayWith( - values.NewObjectWith( - values.NewObjectProperty("foo", key), - ), - ) - - el, err := arr.GetIn(ctx, []core.Value{ - key, // obj[0] - values.NewString("foo"), // obj[0].foo - }) - - So(err, ShouldBeNil) - So(el.Compare(key), ShouldEqual, 0) - }) - }) } diff --git a/pkg/runtime/values/assertions.go b/pkg/runtime/values/assertions.go new file mode 100644 index 00000000..3edb9b15 --- /dev/null +++ b/pkg/runtime/values/assertions.go @@ -0,0 +1,119 @@ +package values + +import ( + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" +) + +func AssertString(input core.Value) error { + _, ok := input.(String) + + if !ok { + return core.TypeError( + input, + types.String, + ) + } + + return nil +} + +func AssertInt(input core.Value) error { + _, ok := input.(Int) + + if !ok { + return core.TypeError( + input, + types.Int, + ) + } + + return nil +} + +func AssertFloat(input core.Value) error { + _, ok := input.(Float) + + if !ok { + return core.TypeError( + input, + types.Float, + ) + } + + return nil +} + +func AssertNumber(input core.Value) error { + switch input.(type) { + case Int, Float: + return nil + default: + return core.TypeError(input, types.Int, types.Float) + } +} + +func AssertBoolean(input core.Value) error { + _, ok := input.(Boolean) + + if !ok { + return core.TypeError( + input, + types.Boolean, + ) + } + + return nil +} + +func AssertArray(input core.Value) error { + _, ok := input.(*Array) + + if !ok { + return core.TypeError( + input, + types.Array, + ) + } + + return nil +} + +func AssertObject(input core.Value) error { + _, ok := input.(*Object) + + if !ok { + return core.TypeError( + input, + types.Object, + ) + } + + return nil +} + +func AssertBinary(input core.Value) error { + _, ok := input.(*Binary) + + if !ok { + return core.TypeError( + input, + types.Binary, + ) + } + + return nil +} + +func AssertDateTime(input core.Value) error { + _, ok := input.(DateTime) + + if !ok { + return core.TypeError( + input, + types.DateTime, + ) + } + + return nil +} diff --git a/pkg/runtime/values/binary.go b/pkg/runtime/values/binary.go index 9b61f8c5..f17bbfa2 100644 --- a/pkg/runtime/values/binary.go +++ b/pkg/runtime/values/binary.go @@ -1,13 +1,13 @@ package values import ( + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "io" "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Binary []byte @@ -42,22 +42,23 @@ func (b Binary) String() string { } func (b Binary) Compare(other core.Value) int64 { - if other.Type() == types.Binary { - // TODO: Lame comparison, need to think more about it - b2 := other.(*Binary) + otherBin, ok := other.(Binary) - if b2.Length() == b.Length() { - return 0 - } + if !ok { + return types.Compare(types.Binary, core.Reflect(other)) + } - if b.Length() > b2.Length() { - return 1 - } + // TODO: Lame comparison, need to think more about it + // Maybe we should do a byte by byte comparison? + if otherBin.Length() == b.Length() { + return 0 + } - return -1 + if b.Length() > otherBin.Length() { + return 1 } - return types.Compare(types.Binary, other.Type()) + return -1 } func (b Binary) Unwrap() interface{} { @@ -67,7 +68,7 @@ func (b Binary) Unwrap() interface{} { func (b Binary) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(b.Type().String())) + h.Write([]byte(types.Binary.String())) h.Write([]byte(":")) h.Write(b) diff --git a/pkg/runtime/values/boolean.go b/pkg/runtime/values/boolean.go index 962e95c4..42028f45 100644 --- a/pkg/runtime/values/boolean.go +++ b/pkg/runtime/values/boolean.go @@ -1,13 +1,13 @@ package values import ( + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "strings" "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Boolean bool @@ -68,23 +68,21 @@ func (t Boolean) String() string { } func (t Boolean) Compare(other core.Value) int64 { - raw := bool(t) + otherBool, ok := other.(Boolean) - if types.Boolean.Equals(other.Type()) { - i := other.Unwrap().(bool) - - if raw == i { - return 0 - } + if !ok { + return types.Compare(types.Boolean, core.Reflect(other)) + } - if !raw && i { - return -1 - } + if t == otherBool { + return 0 + } - return +1 + if !t && otherBool { + return -1 } - return types.Compare(types.Boolean, other.Type()) + return +1 } func (t Boolean) Unwrap() interface{} { @@ -94,7 +92,7 @@ func (t Boolean) Unwrap() interface{} { func (t Boolean) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(t.Type().String())) + h.Write([]byte(types.Boolean.String())) h.Write([]byte(":")) h.Write([]byte(t.String())) diff --git a/pkg/runtime/values/boolean_test.go b/pkg/runtime/values/boolean_test.go index 80912945..cd26cafe 100644 --- a/pkg/runtime/values/boolean_test.go +++ b/pkg/runtime/values/boolean_test.go @@ -7,7 +7,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func TestBoolean(t *testing.T) { @@ -22,12 +21,6 @@ func TestBoolean(t *testing.T) { }) }) - Convey(".Type", t, func() { - Convey("Should return a type", func() { - So(values.True.Type().Equals(types.Boolean), ShouldBeTrue) - }) - }) - Convey(".Unwrap", t, func() { Convey("Should return an unwrapped items", func() { So(values.True.Unwrap(), ShouldHaveSameTypeAs, true) diff --git a/pkg/runtime/values/boxed.go b/pkg/runtime/values/boxed.go new file mode 100644 index 00000000..2eebecc6 --- /dev/null +++ b/pkg/runtime/values/boxed.go @@ -0,0 +1,44 @@ +package values + +import ( + "fmt" + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" + "github.com/wI2L/jettison" + "hash/fnv" +) + +// Boxed represents an arbitrary value that can be boxed as a runtime Value. +type Boxed struct { + value any +} + +func NewBoxedValue(value any) *Boxed { + return &Boxed{value} +} + +func (b *Boxed) MarshalJSON() ([]byte, error) { + return jettison.MarshalOpts(b.value, jettison.NoHTMLEscaping()) +} + +func (b *Boxed) String() string { + return fmt.Sprintf("%v", b.value) +} + +func (b *Boxed) Unwrap() interface{} { + return b.value +} + +func (b *Boxed) Hash() uint64 { + h := fnv.New64a() + + h.Write([]byte(types.Boxed.String())) + h.Write([]byte(":")) + h.Write([]byte(fmt.Sprintf("%v", b.value))) + + return h.Sum64() +} + +func (b *Boxed) Copy() core.Value { + return NewBoxedValue(b.value) +} diff --git a/pkg/runtime/values/casting.go b/pkg/runtime/values/casting.go new file mode 100644 index 00000000..1de3d1da --- /dev/null +++ b/pkg/runtime/values/casting.go @@ -0,0 +1,166 @@ +package values + +import ( + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" +) + +func CastBoolean(input core.Value) (Boolean, error) { + boolean, ok := input.(Boolean) + + if ok { + return boolean, nil + } + + return False, core.TypeError(input, types.Boolean) +} + +func SafeCastBoolean(input core.Value, fallback Boolean) Boolean { + boolean, ok := input.(Boolean) + + if ok { + return boolean + } + + return fallback +} + +func CastInt(input core.Value) (Int, error) { + integer, ok := input.(Int) + + if ok { + return integer, nil + } + + return ZeroInt, core.TypeError(input, types.Int) +} + +func SafeCastInt(input core.Value, fallback Int) Int { + integer, ok := input.(Int) + + if ok { + return integer + } + + return fallback +} + +func CastFloat(input core.Value) (Float, error) { + float, ok := input.(Float) + + if ok { + return float, nil + } + + return ZeroFloat, core.TypeError(input, types.Float) +} + +func SafeCastFloat(input core.Value, fallback Float) Float { + float, ok := input.(Float) + + if ok { + return float + } + + return fallback +} + +func CastString(input core.Value) (String, error) { + str, ok := input.(String) + + if ok { + return str, nil + } + + return EmptyString, core.TypeError(input, types.String) +} + +func SafeCastString(input core.Value, fallback String) String { + str, ok := input.(String) + + if ok { + return str + } + + return fallback +} + +func CastDateTime(input core.Value) (DateTime, error) { + dt, ok := input.(DateTime) + + if ok { + return dt, nil + } + + return ZeroDateTime, core.TypeError(input, types.DateTime) +} + +func SafeCastDateTime(input core.Value, fallback DateTime) DateTime { + dt, ok := input.(DateTime) + + if ok { + return dt + } + + return fallback +} + +func CastArray(input core.Value) (*Array, error) { + arr, ok := input.(*Array) + + if ok { + return arr, nil + } + + return nil, core.TypeError(input, types.Array) +} + +func SafeCastArray(input core.Value, fallback *Array) *Array { + arr, ok := input.(*Array) + + if ok { + return arr + } + + return fallback +} + +func CastObject(input core.Value) (*Object, error) { + obj, ok := input.(*Object) + + if ok { + return obj, nil + } + + return nil, core.TypeError(input, types.Object) +} + +func SafeCastObject(input core.Value, fallback *Object) *Object { + obj, ok := input.(*Object) + + if ok { + return obj + } + return fallback + +} + +func CastBinary(input core.Value) (Binary, error) { + bin, ok := input.(Binary) + + if ok { + return bin, nil + } + + return nil, core.TypeError(input, types.Binary) +} + +func SafeCastBinary(input core.Value, fallback Binary) Binary { + bin, ok := input.(Binary) + + if ok { + return bin + } + + return fallback +} diff --git a/pkg/runtime/values/comparator.go b/pkg/runtime/values/comparator.go new file mode 100644 index 00000000..6eea3cd0 --- /dev/null +++ b/pkg/runtime/values/comparator.go @@ -0,0 +1,23 @@ +package values + +import ( + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" +) + +func Compare(a, b core.Value) int64 { + aComparable, ok := a.(core.Comparable) + + if ok { + return aComparable.Compare(b) + } + + bComparable, ok := b.(core.Comparable) + + if ok { + return -bComparable.Compare(a) + } + + return types.Compare(core.Reflect(a), core.Reflect(b)) +} + diff --git a/pkg/runtime/values/date_time.go b/pkg/runtime/values/date_time.go index 3c137c35..cab7be5d 100644 --- a/pkg/runtime/values/date_time.go +++ b/pkg/runtime/values/date_time.go @@ -1,13 +1,13 @@ package values import ( + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "time" "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) const DefaultTimeLayout = time.RFC3339 @@ -70,21 +70,21 @@ func (t DateTime) String() string { } func (t DateTime) Compare(other core.Value) int64 { - if other.Type() == types.DateTime { - other := other.(DateTime) + otherDt, ok := other.(DateTime) - if t.After(other.Time) { - return 1 - } + if !ok { + return types.Compare(types.DateTime, core.Reflect(other)) + } - if t.Before(other.Time) { - return -1 - } + if t.After(otherDt.Time) { + return 1 + } - return 0 + if t.Before(otherDt.Time) { + return -1 } - return types.Compare(types.DateTime, other.Type()) + return 0 } func (t DateTime) Unwrap() interface{} { @@ -94,7 +94,7 @@ func (t DateTime) Unwrap() interface{} { func (t DateTime) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(t.Type().String())) + h.Write([]byte(types.DateTime.String())) h.Write([]byte(":")) bytes, err := t.Time.GobEncode() diff --git a/pkg/runtime/values/float.go b/pkg/runtime/values/float.go index cf91edd8..58311b84 100644 --- a/pkg/runtime/values/float.go +++ b/pkg/runtime/values/float.go @@ -3,6 +3,7 @@ package values import ( "encoding/binary" "fmt" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "math" "strconv" @@ -10,12 +11,13 @@ import ( "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Float float64 -var NaN = Float(math.NaN()) +var ( + NaN = Float(math.NaN()) +) const ZeroFloat = Float(0.0) @@ -87,39 +89,32 @@ func (t Float) String() string { } func (t Float) Compare(other core.Value) int64 { - otherType := other.Type() - raw := float64(t) - - if otherType == types.Float { - f := other.Unwrap().(float64) - - if raw == f { + switch otherVal := other.(type) { + case Float: + if t == otherVal { return 0 } - if raw < f { + if t < otherVal { return -1 } return +1 - } + case Int: + f := Float(otherVal) - if otherType == types.Int { - i := other.Unwrap().(int) - f := float64(i) - - if raw == f { + if t == f { return 0 } - if raw < f { + if t < f { return -1 } return +1 + default: + return types.Compare(types.Float, core.Reflect(other)) } - - return types.Compare(types.Float, otherType) } func (t Float) Unwrap() interface{} { @@ -129,7 +124,7 @@ func (t Float) Unwrap() interface{} { func (t Float) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(t.Type().String())) + h.Write([]byte(types.Float.String())) h.Write([]byte(":")) bytes := make([]byte, 8) diff --git a/pkg/runtime/values/helpers.go b/pkg/runtime/values/helpers.go index f5ab9148..87329365 100644 --- a/pkg/runtime/values/helpers.go +++ b/pkg/runtime/values/helpers.go @@ -14,174 +14,8 @@ import ( "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) -// GetIn checks that from implements core.Getter interface. If it implements, -// GetIn call from.GetIn method, otherwise iterates over values and tries to resolve a given path. -func GetIn(ctx context.Context, from core.Value, byPath []core.Value) (core.Value, core.PathError) { - if len(byPath) == 0 { - return None, nil - } - - var result = from - - for i, segment := range byPath { - if result == None || result == nil { - break - } - - segType := segment.Type() - - switch curVal := result.(type) { - case *Object: - result, _ = curVal.Get(ToString(segment)) - case *Array: - if segType != types.Int { - return nil, core.NewPathError( - core.TypeError(segType, types.Int), - i, - ) - } - - result = curVal.Get(segment.(Int)) - case String: - if segType != types.Int { - return nil, core.NewPathError( - core.TypeError(segType, types.Int), - i, - ) - } - - result = curVal.At(ToInt(segment)) - case core.Getter: - return curVal.GetIn(ctx, byPath[i:]) - default: - return None, core.NewPathError(core.ErrInvalidPath, i) - } - } - - return result, nil -} - -func SetIn(ctx context.Context, to core.Value, byPath []core.Value, value core.Value) core.PathError { - if len(byPath) == 0 { - return nil - } - - var parent core.Value - var current = to - target := len(byPath) - 1 - - for idx, segment := range byPath { - parent = current - isTarget := target == idx - segmentType := segment.Type() - - switch parVal := parent.(type) { - case *Object: - if segmentType != types.String { - return core.NewPathError( - core.TypeError(segmentType, types.String), - idx, - ) - } - - if !isTarget { - current, _ = parVal.Get(segment.(String)) - } else { - parVal.Set(segment.(String), value) - } - case *Array: - if segmentType != types.Int { - return core.NewPathError( - core.TypeError(segmentType, types.Int), - idx, - ) - } - - if !isTarget { - current = parVal.Get(segment.(Int)) - } else { - if err := parVal.Set(segment.(Int), value); err != nil { - return core.NewPathError(err, idx) - } - } - case core.Setter: - return parVal.SetIn(ctx, byPath[idx:], value) - default: - // redefine parent - isArray := segmentType.Equals(types.Int) - - // it's not an index - if !isArray { - obj := NewObject() - parent = obj - - if segmentType != types.String { - return core.NewPathError(core.TypeError(segmentType, types.String), idx) - } - - if isTarget { - obj.Set(segment.(String), value) - } - } else { - arr := NewArray(10) - parent = arr - - if isTarget { - if err := arr.Set(segment.(Int), value); err != nil { - return core.NewPathError(err, idx) - } - } - } - - // set new parent - nextPath := byPath - - if idx > 0 { - nextPath = byPath[0 : idx-1] - } else { - nextPath = byPath[0:] - } - - if err := SetIn(ctx, to, nextPath, parent); err != nil { - return err - } - - if !isTarget { - current = None - } - } - } - - return nil -} - -func ReturnOrNext(ctx context.Context, path []core.Value, idx int, out core.Value, err error) (core.Value, core.PathError) { - if err != nil { - pathErr, ok := err.(core.PathError) - - if ok { - return None, core.NewPathErrorFrom(pathErr, idx) - } - - return None, core.NewPathError(err, idx) - } - - if len(path) > (idx + 1) { - out, pathErr := GetIn(ctx, out, path[idx+1:]) - - if pathErr != nil { - return None, core.NewPathErrorFrom(pathErr, idx) - } - - return out, nil - } - - return out, nil -} - func Parse(input interface{}) core.Value { switch value := input.(type) { case bool: @@ -315,19 +149,37 @@ func MustMarshalAny(input interface{}) json.RawMessage { return out } +func IsScalar(input core.Value) Boolean { + switch input.(type) { + case Int, Float, String, Boolean: + return true + default: + return false + } +} + +func IsNumber(input core.Value) Boolean { + switch input.(type) { + case Int, Float: + return true + default: + return false + } +} + func ToBoolean(input core.Value) Boolean { - switch input.Type() { - case types.Boolean: - return input.(Boolean) - case types.String: - return NewBoolean(input.(String) != "") - case types.Int: - return NewBoolean(input.(Int) != 0) - case types.Float: - return NewBoolean(input.(Float) != 0) - case types.DateTime: - return NewBoolean(!input.(DateTime).IsZero()) - case types.None: + switch val := input.(type) { + case Boolean: + return val + case String: + return val != "" + case Int: + return val != 0 + case Float: + return val != 0 + case DateTime: + return val.IsZero() == false + case *none: return False default: return True @@ -550,10 +402,20 @@ func ToStrings(input *Array) []String { return res } -func Hash(rtType core.Type, content []byte) uint64 { +func ToBinary(input core.Value) Binary { + bin, ok := input.(Binary) + + if ok { + return bin + } + + return NewBinary([]byte(input.String())) +} + +func Hash(typename string, content []byte) uint64 { h := fnv.New64a() - h.Write([]byte(rtType.String())) + h.Write([]byte(typename)) h.Write([]byte(":")) h.Write(content) @@ -597,12 +459,6 @@ func MapHash(input map[string]core.Value) uint64 { return h.Sum64() } -func IsNumber(input core.Value) Boolean { - t := input.Type() - - return t == types.Int || t == types.Float -} - func UnwrapStrings(values []String) []string { out := make([]string, len(values)) @@ -626,28 +482,28 @@ func Negate(input core.Value) core.Value { } } -func Negative(value core.Value) core.Value { - if value.Type() == types.Int { - return -value.(Int) - } - - if value.Type() == types.Float { - return -value.(Float) +func Negative(input core.Value) core.Value { + switch value := input.(type) { + case Int: + return -value + case Float: + return -value + default: + // TODO: Maybe we should return None? + return input } - - return value } -func Positive(value core.Value) core.Value { - if value.Type() == types.Int { - return +value.(Int) - } - - if value.Type() == types.Float { - return +value.(Float) +func Positive(input core.Value) core.Value { + switch value := input.(type) { + case Int: + return +value + case Float: + return +value + default: + // TODO: Maybe we should return None? + return input } - - return value } func Contains(input core.Value, value core.Value) Boolean { @@ -662,27 +518,26 @@ func Contains(input core.Value, value core.Value) Boolean { } func ToNumberOrString(input core.Value) core.Value { - switch input.Type() { - case types.Int, types.Float, types.String: - return input + switch value := input.(type) { + case Int, Float, String: + return value default: - return ToInt(input) + return ToString(value) } } func ToNumberOnly(input core.Value) core.Value { - switch input.Type() { - case types.Int, types.Float: - return input - case types.String: - if strings.Contains(input.String(), ".") { + switch value := input.(type) { + case Int, Float: + return value + case String: + if strings.Contains(value.String(), ".") { return ToFloat(input) } return ToInt(input) - case types.Array: - arr := input.(*Array) - length := arr.Length() + case *Array: + length := value.Length() if length == 0 { return ZeroInt @@ -692,12 +547,13 @@ func ToNumberOnly(input core.Value) core.Value { f := ZeroFloat for y := Int(0); y < length; y++ { - out := ToNumberOnly(arr.Get(y)) + out := ToNumberOnly(value.Get(y)) - if out.Type() == types.Int { - i += out.(Int) - } else { - f += out.(Float) + switch item := out.(type) { + case Int: + i += item + case Float: + f += item } } diff --git a/pkg/runtime/values/helpers_test.go b/pkg/runtime/values/helpers_test.go index d1b0b241..a4693ba4 100644 --- a/pkg/runtime/values/helpers_test.go +++ b/pkg/runtime/values/helpers_test.go @@ -3,18 +3,15 @@ package values_test import ( "context" "encoding/json" + "reflect" "testing" - "github.com/MontFerret/ferret/pkg/runtime/values/types" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" . "github.com/smartystreets/goconvey/convey" ) -var CustomType = core.NewType("custom") - type CustomValue struct { properties map[core.Value]core.Value } @@ -23,10 +20,6 @@ func (t *CustomValue) MarshalJSON() ([]byte, error) { return nil, core.ErrNotImplemented } -func (t *CustomValue) Type() core.Type { - return CustomType -} - func (t *CustomValue) String() string { return "" } @@ -47,119 +40,8 @@ func (t *CustomValue) Copy() core.Value { return values.None } -func (t *CustomValue) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { - return values.None, nil - } - - propKey := path[0] - propValue, ok := t.properties[propKey] - - if !ok { - return values.None, nil - } - - if len(path) == 1 { - return propValue, nil - } - - return values.GetIn(ctx, propValue, path[1:]) -} - -func (t *CustomValue) SetIn(ctx context.Context, path []core.Value, value core.Value) core.PathError { - if len(path) == 0 { - return nil - } - - propKey := path[0] - propValue, ok := t.properties[propKey] - - if !ok { - return nil - } - - if len(path) == 1 { - t.properties[propKey] = value - - return nil - } - - return values.SetIn(ctx, propValue, path[1:], value) -} - func TestHelpers(t *testing.T) { Convey("Helpers", t, func() { - Convey("Getter", func() { - Convey("It should get a value by a given path", func() { - ct := &CustomValue{ - properties: map[core.Value]core.Value{ - values.NewString("foo"): values.NewInt(1), - values.NewString("bar"): &CustomValue{ - properties: map[core.Value]core.Value{ - values.NewString("qaz"): values.NewInt(2), - }, - }, - }, - } - - ctx := context.Background() - - foo, err := values.GetIn(ctx, ct, []core.Value{ - values.NewString("foo"), - }) - - So(err, ShouldBeNil) - So(foo, ShouldEqual, values.NewInt(1)) - - qaz, err := values.GetIn(ctx, ct, []core.Value{ - values.NewString("bar"), - values.NewString("qaz"), - }) - - So(err, ShouldBeNil) - So(qaz, ShouldEqual, values.NewInt(2)) - }) - }) - - Convey("Setter", func() { - Convey("It should get a value by a given path", func() { - ct := &CustomValue{ - properties: map[core.Value]core.Value{ - values.NewString("foo"): values.NewInt(1), - values.NewString("bar"): &CustomValue{ - properties: map[core.Value]core.Value{ - values.NewString("qaz"): values.NewInt(2), - }, - }, - }, - } - - ctx := context.Background() - - err := values.SetIn(ctx, ct, []core.Value{ - values.NewString("foo"), - }, values.NewInt(2)) - - So(err, ShouldBeNil) - So(ct.properties[values.NewString("foo")], ShouldEqual, values.NewInt(2)) - - err = values.SetIn(ctx, ct, []core.Value{ - values.NewString("bar"), - values.NewString("qaz"), - }, values.NewString("foobar")) - - So(err, ShouldBeNil) - - qaz, err := values.GetIn(ctx, ct, []core.Value{ - values.NewString("bar"), - values.NewString("qaz"), - }) - - So(err, ShouldBeNil) - So(qaz, ShouldEqual, values.NewString("foobar")) - }) - }) - Convey("Parse", func() { Convey("It should parse values", func() { inputs := []struct { @@ -176,7 +58,10 @@ func TestHelpers(t *testing.T) { for _, input := range inputs { out := values.Parse(input.Raw) - So(out.Type().ID(), ShouldEqual, input.Parsed.Type().ID()) + expectedType := reflect.TypeOf(input.Parsed) + actualType := reflect.TypeOf(out) + + So(actualType, ShouldEqual, expectedType) So(out.Unwrap(), ShouldEqual, input.Parsed.Unwrap()) } }) @@ -460,7 +345,6 @@ func TestHelpers(t *testing.T) { val, err := values.Unmarshal(json1) So(err, ShouldBeNil) - So(val.Type(), ShouldResemble, types.Object) json2, err := val.MarshalJSON() diff --git a/pkg/runtime/values/int.go b/pkg/runtime/values/int.go index ad4a008d..a0b01e03 100644 --- a/pkg/runtime/values/int.go +++ b/pkg/runtime/values/int.go @@ -2,13 +2,13 @@ package values import ( "encoding/binary" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "strconv" "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Int int64 @@ -19,6 +19,10 @@ func NewInt(input int) Int { return Int(int64(input)) } +func NewInt64(input int64) Int { + return Int(input) +} + func ParseInt(input interface{}) (Int, error) { if core.IsNil(input) { return ZeroInt, nil @@ -75,38 +79,34 @@ func (t Int) String() string { } func (t Int) Compare(other core.Value) int64 { - otherType := other.Type() - - if otherType == types.Int { - i := other.(Int) - - if t == i { + switch otherVal := other.(type) { + case Int: + if t == otherVal { return 0 } - if t < i { + if t < otherVal { return -1 } return +1 - } - if otherType == types.Float { - f := other.(Float) - f2 := Float(t) + case Float: + f := Float(t) - if f2 == f { + if f == otherVal { return 0 } - if f2 < f { + if f < otherVal { return -1 } return +1 - } - return types.Compare(types.Int, otherType) + default: + return types.Compare(types.Int, core.Reflect(other)) + } } func (t Int) Unwrap() interface{} { @@ -116,7 +116,7 @@ func (t Int) Unwrap() interface{} { func (t Int) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(t.Type().String())) + h.Write([]byte(types.Int.String())) h.Write([]byte(":")) bytes := make([]byte, 8) diff --git a/pkg/runtime/values/none.go b/pkg/runtime/values/none.go index 9acb6a9a..468f67f3 100644 --- a/pkg/runtime/values/none.go +++ b/pkg/runtime/values/none.go @@ -7,7 +7,9 @@ import ( type none struct{} -var None = &none{} +var ( + None = &none{} +) func (t *none) MarshalJSON() ([]byte, error) { return []byte("null"), nil @@ -22,7 +24,7 @@ func (t *none) String() string { } func (t *none) Compare(other core.Value) int64 { - if other.Type() == types.None { + if t == other { return 0 } diff --git a/pkg/runtime/values/object.go b/pkg/runtime/values/object.go index 59adbc6e..492befb5 100644 --- a/pkg/runtime/values/object.go +++ b/pkg/runtime/values/object.go @@ -3,13 +3,13 @@ package values import ( "context" "encoding/binary" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "sort" "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -21,7 +21,7 @@ type ( } Object struct { - value map[string]core.Value + data map[string]core.Value } ) @@ -37,20 +37,20 @@ func NewObjectWith(props ...*ObjectProperty) *Object { obj := NewObject() for _, prop := range props { - obj.value[prop.key] = prop.value + obj.data[prop.key] = prop.value } return obj } -func (t *Object) MarshalJSON() ([]byte, error) { - return jettison.MarshalOpts(t.value, jettison.NoHTMLEscaping()) -} - func (t *Object) Type() core.Type { return types.Object } +func (t *Object) MarshalJSON() ([]byte, error) { + return jettison.MarshalOpts(t.data, jettison.NoHTMLEscaping()) +} + func (t *Object) String() string { marshaled, err := t.MarshalJSON() @@ -65,75 +65,75 @@ func (t *Object) String() string { // The behavior of the Compare is similar // to the comparison of objects in ArangoDB func (t *Object) Compare(other core.Value) int64 { - if other.Type() == t.Type() { - other := other.(*Object) + otherObject, ok := other.(*Object) - if t.Length() == 0 && other.Length() == 0 { - return 0 - } + if !ok { + return types.Compare(types.Object, core.Reflect(other)) + } - if t.Length() < other.Length() { - return -1 - } + if t.Length() == 0 && otherObject.Length() == 0 { + return 0 + } - if t.Length() > other.Length() { - return 1 - } + if t.Length() < otherObject.Length() { + return -1 + } - var res int64 + if t.Length() > otherObject.Length() { + return 1 + } - tKeys := make([]string, 0, len(t.value)) + var res int64 - for k := range t.value { - tKeys = append(tKeys, k) - } + tKeys := make([]string, 0, len(t.data)) - sortedT := sort.StringSlice(tKeys) - sortedT.Sort() + for k := range t.data { + tKeys = append(tKeys, k) + } - otherKeys := make([]string, 0, other.Length()) + sortedT := sort.StringSlice(tKeys) + sortedT.Sort() - other.ForEach(func(value core.Value, k string) bool { - otherKeys = append(otherKeys, k) - return true - }) + otherKeys := make([]string, 0, otherObject.Length()) - sortedOther := sort.StringSlice(otherKeys) - sortedOther.Sort() + otherObject.ForEach(func(value core.Value, k string) bool { + otherKeys = append(otherKeys, k) + return true + }) - var tVal, otherVal core.Value - var tKey, otherKey string + sortedOther := sort.StringSlice(otherKeys) + sortedOther.Sort() - for i := 0; i < len(t.value) && res == 0; i++ { - tKey, otherKey = sortedT[i], sortedOther[i] + var tVal, otherVal core.Value + var tKey, otherKey string - if tKey == otherKey { - tVal, _ = t.Get(NewString(tKey)) - otherVal, _ = other.Get(NewString(tKey)) - res = tVal.Compare(otherVal) + for i := 0; i < len(t.data) && res == 0; i++ { + tKey, otherKey = sortedT[i], sortedOther[i] - continue - } + if tKey == otherKey { + tVal, _ = t.Get(NewString(tKey)) + otherVal, _ = otherObject.Get(NewString(tKey)) + res = Compare(tVal, otherVal) - if tKey < otherKey { - res = 1 - } else { - res = -1 - } + continue + } - break + if tKey < otherKey { + res = 1 + } else { + res = -1 } - return res + break } - return types.Compare(types.Object, other.Type()) + return res } func (t *Object) Unwrap() interface{} { obj := make(map[string]interface{}) - for key, val := range t.value { + for key, val := range t.data { obj[key] = val.Unwrap() } @@ -143,13 +143,13 @@ func (t *Object) Unwrap() interface{} { func (t *Object) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(t.Type().String())) + h.Write([]byte(types.Object.String())) h.Write([]byte(":")) h.Write([]byte("{")) - keys := make([]string, 0, len(t.value)) + keys := make([]string, 0, len(t.data)) - for key := range t.value { + for key := range t.data { keys = append(keys, key) } @@ -162,7 +162,7 @@ func (t *Object) Hash() uint64 { h.Write([]byte(key)) h.Write([]byte(":")) - el := t.value[key] + el := t.data[key] bytes := make([]byte, 8) binary.LittleEndian.PutUint64(bytes, el.Hash()) @@ -182,7 +182,7 @@ func (t *Object) Hash() uint64 { func (t *Object) Copy() core.Value { c := NewObject() - for k, v := range t.value { + for k, v := range t.data { c.Set(NewString(k), v) } @@ -190,13 +190,13 @@ func (t *Object) Copy() core.Value { } func (t *Object) Length() Int { - return Int(len(t.value)) + return Int(len(t.data)) } func (t *Object) Keys() []String { - keys := make([]String, 0, len(t.value)) + keys := make([]String, 0, len(t.data)) - for k := range t.value { + for k := range t.data { keys = append(keys, NewString(k)) } @@ -204,9 +204,9 @@ func (t *Object) Keys() []String { } func (t *Object) Values() []core.Value { - keys := make([]core.Value, 0, len(t.value)) + keys := make([]core.Value, 0, len(t.data)) - for _, v := range t.value { + for _, v := range t.data { keys = append(keys, v) } @@ -214,7 +214,7 @@ func (t *Object) Values() []core.Value { } func (t *Object) ForEach(predicate ObjectPredicate) { - for key, val := range t.value { + for key, val := range t.data { if !predicate(val, key) { break } @@ -222,7 +222,7 @@ func (t *Object) ForEach(predicate ObjectPredicate) { } func (t *Object) Find(predicate ObjectPredicate) (core.Value, Boolean) { - for idx, val := range t.value { + for idx, val := range t.data { if predicate(val, idx) { return val, True } @@ -232,7 +232,7 @@ func (t *Object) Find(predicate ObjectPredicate) (core.Value, Boolean) { } func (t *Object) Has(key String) Boolean { - _, exists := t.value[string(key)] + _, exists := t.data[string(key)] return NewBoolean(exists) } @@ -244,7 +244,7 @@ func (t *Object) MustGet(key String) core.Value { } func (t *Object) MustGetOr(key String, defaultValue core.Value) core.Value { - val, found := t.value[string(key)] + val, found := t.data[string(key)] if found { return val @@ -254,7 +254,7 @@ func (t *Object) MustGetOr(key String, defaultValue core.Value) core.Value { } func (t *Object) Get(key String) (core.Value, Boolean) { - val, found := t.value[string(key)] + val, found := t.data[string(key)] if found { return val, NewBoolean(found) @@ -265,14 +265,14 @@ func (t *Object) Get(key String) (core.Value, Boolean) { func (t *Object) Set(key String, value core.Value) { if value != nil { - t.value[string(key)] = value + t.data[string(key)] = value } else { - t.value[string(key)] = None + t.data[string(key)] = None } } func (t *Object) Remove(key String) { - delete(t.value, string(key)) + delete(t.data, string(key)) } func (t *Object) Clone() core.Cloneable { @@ -281,7 +281,7 @@ func (t *Object) Clone() core.Cloneable { var value core.Value var keyString String - for key := range t.value { + for key := range t.data { keyString = NewString(key) value, _ = t.Get(keyString) @@ -296,29 +296,7 @@ func (t *Object) Clone() core.Cloneable { return cloned } -func (t *Object) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { - if len(path) == 0 { - return None, nil - } - - segmentIdx := 0 - first, _ := t.Get(ToString(path[segmentIdx])) - - if len(path) == 1 { - return first, nil - } - - segmentIdx++ - - if first == None || first == nil { - return None, core.NewPathError(core.ErrInvalidPath, segmentIdx) - } - - getter, ok := first.(core.Getter) - - if !ok { - return GetIn(ctx, first, path[segmentIdx:]) - } - - return getter.GetIn(ctx, path[segmentIdx:]) +func (t *Object) Iterate(_ context.Context) (core.Iterator, error) { + // TODO: implement channel based iterator + return NewObjectIterator(t), nil } diff --git a/pkg/runtime/values/object_iter.go b/pkg/runtime/values/object_iter.go new file mode 100644 index 00000000..880fe371 --- /dev/null +++ b/pkg/runtime/values/object_iter.go @@ -0,0 +1,44 @@ +package values + +import ( + "context" + "github.com/MontFerret/ferret/pkg/runtime/core" +) + +type ObjectIterator struct { + keys []string + data map[string]core.Value + pos int +} + +func NewObjectIterator(obj *Object) core.Iterator { + return &ObjectIterator{data: obj.data, keys: nil} +} + +func (iterator *ObjectIterator) init() { + iterator.keys = make([]string, len(iterator.data)) + + i := 0 + + for key := range iterator.data { + iterator.keys[i] = key + i++ + } +} + +func (iterator *ObjectIterator) HasNext(_ context.Context) (bool, error) { + return len(iterator.keys) > iterator.pos, nil +} + +func (iterator *ObjectIterator) Next(ctx context.Context) (core.Value, core.Value, error) { + if iterator.keys == nil { + iterator.init() + } + + key := iterator.keys[iterator.pos] + val := iterator.data[key] + + iterator.pos++ + + return val, String(key), nil +} diff --git a/pkg/runtime/values/object_test.go b/pkg/runtime/values/object_test.go index a9fac337..b7e92c2f 100644 --- a/pkg/runtime/values/object_test.go +++ b/pkg/runtime/values/object_test.go @@ -1,13 +1,10 @@ package values_test import ( - "context" "testing" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" - . "github.com/smartystreets/goconvey/convey" ) @@ -62,14 +59,6 @@ func TestObject(t *testing.T) { }) }) - Convey(".Type", t, func() { - Convey("Should return type", func() { - obj := values.NewObject() - - So(obj.Type().Equals(types.Object), ShouldBeTrue) - }) - }) - Convey(".Unwrap", t, func() { Convey("Should return an unwrapped items", func() { obj := values.NewObjectWith( @@ -410,87 +399,4 @@ func TestObject(t *testing.T) { So(nestedInObjArr.Compare(nestedInCloneArr), ShouldNotEqual, 0) }) }) - - Convey(".GetIn", t, func() { - - ctx := context.Background() - - Convey("Should return the same as .Get when input is correct", func() { - - Convey("Should return item by key", func() { - key := values.NewString("foo") - obj := values.NewObjectWith( - values.NewObjectProperty(key.String(), values.NewInt(1)), - ) - - el, err := obj.GetIn(ctx, []core.Value{key}) - elGet, _ := obj.Get(key) - - So(err, ShouldBeNil) - So(el.Compare(elGet), ShouldEqual, 0) - }) - - Convey("Should return None when no items", func() { - key := values.NewString("foo") - obj := values.NewObject() - - el, err := obj.GetIn(ctx, []core.Value{key}) - elGet, _ := obj.Get(key) - - So(err, ShouldBeNil) - So(el.Compare(elGet), ShouldEqual, 0) - }) - }) - - Convey("Should error when input is not correct", func() { - - Convey("Should return None when path[0] is not a string", func() { - obj := values.NewObject() - path := []core.Value{values.NewInt(0)} - - el, err := obj.GetIn(ctx, path) - - So(err, ShouldBeNil) - So(el, ShouldNotBeNil) - So(el.Type().String(), ShouldEqual, types.None.String()) - }) - - Convey("Should error when first received item is not a Getter and len(path) > 1", func() { - key := values.NewString("foo") - obj := values.NewObjectWith( - values.NewObjectProperty(key.String(), values.NewInt(1)), - ) - path := []core.Value{key, key} - - el, err := obj.GetIn(ctx, path) - - So(err, ShouldBeError) - So(el.Compare(values.None), ShouldEqual, 0) - }) - }) - - Convey("Should return None when len(path) == 0", func() { - obj := values.NewObject() - - el, err := obj.GetIn(ctx, nil) - - So(err, ShouldBeNil) - So(el.Compare(values.None), ShouldEqual, 0) - }) - - Convey("Should call the nested Getter", func() { - key := values.NewString("foo") - obj := values.NewObjectWith( - values.NewObjectProperty(key.String(), values.NewArrayWith(key)), - ) - - el, err := obj.GetIn(ctx, []core.Value{ - key, // obj.foo - values.NewInt(0), // obj.foo[0] - }) - - So(err, ShouldBeNil) - So(el.Compare(key), ShouldEqual, 0) - }) - }) } diff --git a/pkg/runtime/values/range.go b/pkg/runtime/values/range.go new file mode 100644 index 00000000..c2a3d118 --- /dev/null +++ b/pkg/runtime/values/range.go @@ -0,0 +1,84 @@ +package values + +import ( + "context" + "encoding/binary" + "fmt" + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" + "github.com/wI2L/jettison" + "hash/fnv" +) + +type Range struct { + start uint64 + end uint64 +} + +func NewRange(start, end uint64) *Range { + return &Range{start, end} +} +func (r *Range) Start() uint64 { + return r.start +} + +func (r *Range) End() uint64 { + return r.end +} + +func (r *Range) MarshalJSON() ([]byte, error) { + arr := make([]uint64, r.end-r.start+1) + + for i := r.start; i <= r.end; i++ { + arr[i-r.start] = i + } + + return jettison.MarshalOpts(arr, jettison.NoHTMLEscaping()) +} + +func (r *Range) String() string { + return fmt.Sprintf("%d..%d", r.start, r.end) +} + +func (r *Range) Compare(other core.Value) int64 { + otherRange, ok := other.(*Range) + + if !ok { + return types.Compare(types.Range, core.Reflect(other)) + } + + if r.start == otherRange.start && r.end == otherRange.end { + return 0 + } else if r.start < otherRange.start || r.end < otherRange.end { + return -1 + } else { + return 1 + } +} + +func (r *Range) Unwrap() interface{} { + return []uint64{r.start, r.end} +} + +func (r *Range) Hash() uint64 { + h := fnv.New64a() + + h.Write([]byte(types.Range.String())) + h.Write([]byte(":")) + bytes := make([]byte, 8) + binary.LittleEndian.PutUint64(bytes, r.start) + h.Write(bytes) + h.Write([]byte("..")) + binary.LittleEndian.PutUint64(bytes, r.end) + h.Write(bytes) + + return h.Sum64() +} + +func (r *Range) Copy() core.Value { + return NewRange(r.start, r.end) +} + +func (r *Range) Iterate(_ context.Context) (core.Iterator, error) { + return NewRangeIterator(r), nil +} diff --git a/pkg/runtime/values/range_iter.go b/pkg/runtime/values/range_iter.go new file mode 100644 index 00000000..d5d1875c --- /dev/null +++ b/pkg/runtime/values/range_iter.go @@ -0,0 +1,27 @@ +package values + +import ( + "context" + "github.com/MontFerret/ferret/pkg/runtime/core" +) + +type RangeIterator struct { + values *Range + pos uint64 +} + +func NewRangeIterator(values *Range) core.Iterator { + return &RangeIterator{values: values, pos: values.start} +} + +func (iterator *RangeIterator) HasNext(ctx context.Context) (bool, error) { + return iterator.values.end > iterator.pos, nil +} + +func (iterator *RangeIterator) Next(_ context.Context) (value core.Value, key core.Value, err error) { + val := NewInt64(int64(iterator.pos)) + + iterator.pos++ + + return val, val, nil +} diff --git a/pkg/runtime/values/regexp.go b/pkg/runtime/values/regexp.go index 6b4e0f59..c64d367f 100644 --- a/pkg/runtime/values/regexp.go +++ b/pkg/runtime/values/regexp.go @@ -1,6 +1,7 @@ package values import ( + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "regexp" "strings" @@ -8,7 +9,6 @@ import ( "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Regexp regexp.Regexp @@ -23,24 +23,26 @@ func NewRegexp(pattern string) (*Regexp, error) { return (*Regexp)(r), nil } -func (r *Regexp) MarshalJSON() ([]byte, error) { - return jettison.MarshalOpts(r.String(), jettison.NoHTMLEscaping()) -} - func (r *Regexp) Type() core.Type { return types.Regexp } +func (r *Regexp) MarshalJSON() ([]byte, error) { + return jettison.MarshalOpts(r.String(), jettison.NoHTMLEscaping()) +} + func (r *Regexp) String() string { return (*regexp.Regexp)(r).String() } func (r *Regexp) Compare(other core.Value) int64 { - if other.Type() != types.Regexp { - return types.Compare(types.String, other.Type()) + otherRegexp, ok := other.(*Regexp) + + if !ok { + return types.Compare(types.Regexp, core.Reflect(other)) } - return int64(strings.Compare(r.String(), other.(*Regexp).String())) + return int64(strings.Compare(r.String(), otherRegexp.String())) } func (r *Regexp) Unwrap() interface{} { @@ -50,7 +52,7 @@ func (r *Regexp) Unwrap() interface{} { func (r *Regexp) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(r.Type().String())) + h.Write([]byte(types.Regexp.String())) h.Write([]byte(":")) h.Write([]byte(r.String())) diff --git a/pkg/runtime/values/string.go b/pkg/runtime/values/string.go index 82bd6518..a6af4e9c 100644 --- a/pkg/runtime/values/string.go +++ b/pkg/runtime/values/string.go @@ -2,13 +2,13 @@ package values import ( "fmt" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "hash/fnv" "strings" "github.com/wI2L/jettison" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type String string @@ -68,24 +68,26 @@ func MustParseString(input interface{}) String { return res } -func (t String) MarshalJSON() ([]byte, error) { - return jettison.MarshalOpts(string(t), jettison.NoHTMLEscaping()) -} - func (t String) Type() core.Type { return types.String } +func (t String) MarshalJSON() ([]byte, error) { + return jettison.MarshalOpts(string(t), jettison.NoHTMLEscaping()) +} + func (t String) String() string { return string(t) } func (t String) Compare(other core.Value) int64 { - if other.Type() == types.String { - return int64(strings.Compare(string(t), other.Unwrap().(string))) + otherString, ok := other.(String) + + if !ok { + return types.Compare(types.String, core.Reflect(other)) } - return types.Compare(types.String, other.Type()) + return int64(strings.Compare(string(t), otherString.Unwrap().(string))) } func (t String) Unwrap() interface{} { @@ -95,7 +97,7 @@ func (t String) Unwrap() interface{} { func (t String) Hash() uint64 { h := fnv.New64a() - h.Write([]byte(t.Type().String())) + h.Write([]byte(types.String.String())) h.Write([]byte(":")) h.Write([]byte(t)) diff --git a/pkg/runtime/values/types/comparator.go b/pkg/runtime/values/types/comparator.go new file mode 100644 index 00000000..22620f59 --- /dev/null +++ b/pkg/runtime/values/types/comparator.go @@ -0,0 +1,50 @@ +package types + +import "github.com/MontFerret/ferret/pkg/runtime/core" + +var ( + // Comparison table of builtin types + typeComparisonTable = map[int64]uint64{ + None.ID(): 0, + Boolean.ID(): 1, + Int.ID(): 2, + Float.ID(): 3, + String.ID(): 4, + DateTime.ID(): 5, + Regexp.ID(): 6, + Range.ID(): 7, + Array.ID(): 8, + Object.ID(): 9, + Binary.ID(): 10, + } +) + +func Compare(first, second core.Type) int64 { + f, ok := typeComparisonTable[first.ID()] + + // custom type + if !ok { + return -1 + } + + s, ok := typeComparisonTable[second.ID()] + + // custom type + if !ok { + return 1 + } + + if f == s { + return 0 + } + + if f > s { + return 1 + } + + return -1 +} + +func Equal(first, second core.Type) bool { + return Compare(first, second) == 0 +} diff --git a/pkg/runtime/values/types/helpers.go b/pkg/runtime/values/types/helpers.go deleted file mode 100644 index 86ae5e6e..00000000 --- a/pkg/runtime/values/types/helpers.go +++ /dev/null @@ -1,55 +0,0 @@ -package types - -import "github.com/MontFerret/ferret/pkg/runtime/core" - -// Comparison table of builtin types -var typeComparisonTable = map[core.Type]uint64{ - None: 0, - Boolean: 1, - Int: 2, - Float: 3, - String: 4, - DateTime: 5, - Array: 6, - Regexp: 7, - Object: 8, - Binary: 9, -} - -func Compare(first, second core.Type) int64 { - f, ok := typeComparisonTable[first] - - // custom type - if !ok { - return -1 - } - - s, ok := typeComparisonTable[second] - - // custom type - if !ok { - return 1 - } - - if f == s { - return 0 - } - - if f > s { - return 1 - } - - return -1 -} - -func IsNumeric(t core.Type) bool { - return t == Int || t == Float -} - -func IsScalar(t core.Type) bool { - return t == Boolean || t == Int || t == Float || t == String || t == DateTime || t == Regexp -} - -func IsCollection(t core.Type) bool { - return t == Array || t == Object -} diff --git a/pkg/runtime/values/types/helpers_test.go b/pkg/runtime/values/types/helpers_test.go deleted file mode 100644 index c070eea0..00000000 --- a/pkg/runtime/values/types/helpers_test.go +++ /dev/null @@ -1,196 +0,0 @@ -package types_test - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" -) - -func TestHelpers(t *testing.T) { - Convey("Compare", t, func() { - typesList := []core.Type{ - types.None, - types.Boolean, - types.Int, - types.Float, - types.String, - types.DateTime, - types.Array, - types.Regexp, - types.Object, - types.Binary, - } - - Convey("None", func() { - So(types.Compare(types.None, types.None), ShouldEqual, 0) - - for _, t := range typesList[1:] { - So(types.Compare(types.None, t), ShouldEqual, -1) - } - }) - - Convey("Boolean", func() { - for _, t := range typesList { - switch t.ID() { - case types.None.ID(): - So(types.Compare(types.Boolean, t), ShouldEqual, 1) - case types.Boolean.ID(): - So(types.Compare(types.Boolean, t), ShouldEqual, 0) - default: - So(types.Compare(types.Boolean, t), ShouldEqual, -1) - } - } - }) - - Convey("Int", func() { - for _, t := range typesList { - switch t.ID() { - case types.None.ID(): - So(types.Compare(types.Int, t), ShouldEqual, 1) - case types.Boolean.ID(): - So(types.Compare(types.Int, t), ShouldEqual, 1) - case types.Int.ID(): - So(types.Compare(types.Int, t), ShouldEqual, 0) - default: - So(types.Compare(types.Int, t), ShouldEqual, -1) - } - } - }) - - Convey("Float", func() { - for _, t := range typesList { - switch t.ID() { - case types.None.ID(): - So(types.Compare(types.Float, t), ShouldEqual, 1) - case types.Boolean.ID(): - So(types.Compare(types.Float, t), ShouldEqual, 1) - case types.Int.ID(): - So(types.Compare(types.Float, t), ShouldEqual, 1) - case types.Float.ID(): - So(types.Compare(types.Float, t), ShouldEqual, 0) - default: - So(types.Compare(types.Float, t), ShouldEqual, -1) - } - } - }) - - Convey("String", func() { - for _, t := range typesList { - switch t.ID() { - case types.None.ID(): - So(types.Compare(types.String, t), ShouldEqual, 1) - case types.Boolean.ID(): - So(types.Compare(types.String, t), ShouldEqual, 1) - case types.Int.ID(): - So(types.Compare(types.String, t), ShouldEqual, 1) - case types.Float.ID(): - So(types.Compare(types.String, t), ShouldEqual, 1) - case types.String.ID(): - So(types.Compare(types.String, t), ShouldEqual, 0) - default: - So(types.Compare(types.String, t), ShouldEqual, -1) - } - } - }) - - Convey("DateTime", func() { - for _, t := range typesList { - switch t.ID() { - case types.None.ID(): - So(types.Compare(types.DateTime, t), ShouldEqual, 1) - case types.Boolean.ID(): - So(types.Compare(types.DateTime, t), ShouldEqual, 1) - case types.Int.ID(): - So(types.Compare(types.DateTime, t), ShouldEqual, 1) - case types.Float.ID(): - So(types.Compare(types.DateTime, t), ShouldEqual, 1) - case types.String.ID(): - So(types.Compare(types.DateTime, t), ShouldEqual, 1) - case types.DateTime.ID(): - So(types.Compare(types.DateTime, t), ShouldEqual, 0) - default: - So(types.Compare(types.DateTime, t), ShouldEqual, -1) - } - } - }) - - Convey("Array", func() { - for _, t := range typesList { - switch t.ID() { - case types.None.ID(): - So(types.Compare(types.Array, t), ShouldEqual, 1) - case types.Boolean.ID(): - So(types.Compare(types.Array, t), ShouldEqual, 1) - case types.Int.ID(): - So(types.Compare(types.Array, t), ShouldEqual, 1) - case types.Float.ID(): - So(types.Compare(types.Array, t), ShouldEqual, 1) - case types.String.ID(): - So(types.Compare(types.Array, t), ShouldEqual, 1) - case types.DateTime.ID(): - So(types.Compare(types.Array, t), ShouldEqual, 1) - case types.Array.ID(): - So(types.Compare(types.Array, t), ShouldEqual, 0) - default: - So(types.Compare(types.Array, t), ShouldEqual, -1) - } - } - }) - - Convey("Object", func() { - for _, t := range typesList { - switch t.ID() { - case types.None.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.Boolean.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.Int.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.Float.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.String.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.DateTime.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.Array.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.Regexp.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 1) - case types.Object.ID(): - So(types.Compare(types.Object, t), ShouldEqual, 0) - default: - So(types.Compare(types.Object, t), ShouldEqual, -1) - } - } - }) - - Convey("Binary", func() { - for _, t := range typesList { - switch t.ID() { - case types.Binary.ID(): - So(types.Compare(types.Binary, t), ShouldEqual, 0) - default: - So(types.Compare(types.Binary, t), ShouldEqual, 1) - } - } - }) - - Convey("Regexp", func() { - for _, t := range typesList { - switch t.ID() { - case types.Regexp.ID(): - So(types.Compare(types.Regexp, t), ShouldEqual, 0) - case types.Object.ID(): - So(types.Compare(types.Regexp, t), ShouldEqual, -1) - case types.Binary.ID(): - So(types.Compare(types.Regexp, t), ShouldEqual, -1) - default: - So(types.Compare(types.Regexp, t), ShouldEqual, 1) - } - } - }) - }) -} diff --git a/pkg/runtime/values/types/types.go b/pkg/runtime/values/types/types.go index 0c21afb5..c8f55cf1 100644 --- a/pkg/runtime/values/types/types.go +++ b/pkg/runtime/values/types/types.go @@ -2,15 +2,27 @@ package types import "github.com/MontFerret/ferret/pkg/runtime/core" +const coreNamespace = "ferret.runtime" + +func newCoreType(name string) core.Type { + return core.NewType(coreNamespace, name) +} + var ( - None = core.NewType("none") - Boolean = core.NewType("boolean") - Int = core.NewType("int") - Float = core.NewType("float") - String = core.NewType("string") - DateTime = core.NewType("date_time") - Array = core.NewType("array") - Object = core.NewType("object") - Binary = core.NewType("binary") - Regexp = core.NewType("regexp") + None = newCoreType("none") + Boolean = newCoreType("boolean") + Int = newCoreType("int") + Float = newCoreType("float") + String = newCoreType("string") + Regexp = newCoreType("regexp") + Range = newCoreType("range") + DateTime = newCoreType("datetime") + Array = newCoreType("array") + Object = newCoreType("object") + Binary = newCoreType("binary") + Boxed = newCoreType("boxed") + Measurable = newCoreType("measurable") + Iterable = newCoreType("iterable") + Keyed = newCoreType("keyed") + Indexed = newCoreType("indexed") ) diff --git a/pkg/runtime/values/types/types_test.go b/pkg/runtime/values/types/types_test.go deleted file mode 100644 index 6afaeb5d..00000000 --- a/pkg/runtime/values/types/types_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package types_test - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" - - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" -) - -type TestValue struct { - t core.Type -} - -func (v TestValue) MarshalJSON() ([]byte, error) { - return nil, nil -} - -func (v TestValue) Type() core.Type { - return v.t -} - -func (v TestValue) String() string { - return "" -} - -func (v TestValue) Compare(other core.Value) int64 { - return 0 -} - -func (v TestValue) Unwrap() interface{} { - return nil -} - -func (v TestValue) Hash() uint64 { - return 0 -} - -func (v TestValue) Copy() core.Value { - return v -} - -func TestType(t *testing.T) { - Convey(".GetName", t, func() { - So(types.None.String(), ShouldEqual, "none") - So(types.Boolean.String(), ShouldEqual, "boolean") - So(types.Int.String(), ShouldEqual, "int") - So(types.Float.String(), ShouldEqual, "float") - So(types.String.String(), ShouldEqual, "string") - So(types.DateTime.String(), ShouldEqual, "date_time") - So(types.Array.String(), ShouldEqual, "array") - So(types.Object.String(), ShouldEqual, "object") - So(types.Binary.String(), ShouldEqual, "binary") - So(types.Regexp.String(), ShouldEqual, "regexp") - }) - - Convey("==", t, func() { - typesList := []core.Type{ - types.None, - types.Boolean, - types.Int, - types.Float, - types.String, - types.DateTime, - types.Array, - types.Object, - types.Binary, - types.Regexp, - } - - valuesList := []core.Value{ - TestValue{types.None}, - TestValue{types.Boolean}, - TestValue{types.Int}, - TestValue{types.Float}, - TestValue{types.String}, - TestValue{types.DateTime}, - TestValue{types.Array}, - TestValue{types.Object}, - TestValue{types.Binary}, - TestValue{types.Regexp}, - } - - for i, t := range typesList { - So(t == valuesList[i].Type(), ShouldBeTrue) - } - }) -} diff --git a/pkg/runtime/vm.go b/pkg/runtime/vm.go index 0b989bfa..64159d7f 100644 --- a/pkg/runtime/vm.go +++ b/pkg/runtime/vm.go @@ -3,10 +3,10 @@ package runtime import ( "context" "errors" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/operators" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) const DefaultStackSize = 128 @@ -98,49 +98,68 @@ loop: case OpPop: stack.Pop() - case OpSetGlobal: + case OpStoreGlobal: vm.globals[program.Constants[arg].String()] = stack.Pop() - case OpGetGlobal: + case OpLoadGlobal: stack.Push(vm.globals[program.Constants[arg].String()]) - case OpSetLocal: + case OpStoreLocal: stack.Set(arg, stack.Peek()) - case OpGetLocal: + case OpLoadLocal: stack.Push(stack.Get(arg)) - case OpGetProperty, OpGetPropertyOptional: - fieldName := stack.Pop() + case OpLoadProperty, OpLoadPropertyOptional: + prop := stack.Pop() val := stack.Pop() - switch src := val.(type) { - case *values.Array: - idx := values.ToInt(fieldName) - - stack.Push(src.Get(idx)) - case *values.Object: - fieldName := values.ToString(fieldName) + switch getter := prop.(type) { + case values.String: + switch src := val.(type) { + case *values.Object: + stack.Push(src.MustGetOr(getter, values.None)) + case core.Keyed: + out, err := src.GetByKey(ctx, getter.String()) + + if err == nil { + stack.Push(out) + } else if op == OpLoadPropertyOptional { + stack.Push(values.None) + } else { + return nil, err + } + default: + if op != OpLoadPropertyOptional { + return nil, core.TypeError(src, types.Object, types.Keyed) + } - stack.Push(src.MustGetOr(fieldName, values.None)) - case core.GetterV2: - out, err := src.GetIn(ctx, fieldName) - - if err == nil { - stack.Push(out) - } else if op == OpGetPropertyOptional { stack.Push(values.None) - } else { - return nil, err - } - default: - if op != OpGetPropertyOptional { - return nil, ErrValueUndefined } + case values.Float, values.Int: + switch src := val.(type) { + case *values.Array: + idx := values.ToInt(getter) + + stack.Push(src.Get(idx)) + case core.Indexed: + out, err := src.GetByIndex(ctx, int(values.ToInt(getter))) + + if err == nil { + stack.Push(out) + } else if op == OpLoadPropertyOptional { + stack.Push(values.None) + } else { + return nil, err + } + default: + if op != OpLoadPropertyOptional { + return nil, core.TypeError(src, types.Array, types.Indexed) + } - stack.Push(values.None) + stack.Push(values.None) + } } - case OpNegate: stack.Push(values.Negate(stack.Pop())) @@ -156,32 +175,32 @@ loop: case OpEq: left := stack.Pop() right := stack.Pop() - stack.Push(values.NewBoolean(left.Compare(right) == 0)) + stack.Push(values.NewBoolean(values.Compare(left, right) == 0)) case OpNeq: left := stack.Pop() right := stack.Pop() - stack.Push(values.NewBoolean(left.Compare(right) != 0)) + stack.Push(values.NewBoolean(values.Compare(left, right) != 0)) case OpGt: right := stack.Pop() left := stack.Pop() - stack.Push(values.NewBoolean(left.Compare(right) > 0)) + stack.Push(values.NewBoolean(values.Compare(left, right) > 0)) case OpLt: right := stack.Pop() left := stack.Pop() - stack.Push(values.NewBoolean(left.Compare(right) < 0)) + stack.Push(values.NewBoolean(values.Compare(left, right) < 0)) case OpGte: right := stack.Pop() left := stack.Pop() - stack.Push(values.NewBoolean(left.Compare(right) >= 0)) + stack.Push(values.NewBoolean(values.Compare(left, right) >= 0)) case OpLte: right := stack.Pop() left := stack.Pop() - stack.Push(values.NewBoolean(left.Compare(right) <= 0)) + stack.Push(values.NewBoolean(values.Compare(left, right) <= 0)) case OpIn: right := stack.Pop() @@ -348,8 +367,53 @@ loop: } case OpLoopInit: - // push a new array to the stack - stack.Push(values.NewArray(0)) + // start a new iteration + src := stack.Pop() + + switch src := src.(type) { + case core.Iterable: + iterator, err := src.Iterate(ctx) + + if err != nil { + return nil, err + } + + stack.Push(values.NewBoxedValue(iterator)) + default: + return nil, core.TypeError(src, types.Iterable) + } + + case OpLoopHasNext: + boxed := stack.Peek() + iterator := boxed.Unwrap().(core.Iterator) + hasNext, err := iterator.HasNext(ctx) + + if err != nil { + return nil, err + } + + stack.Push(values.NewBoolean(hasNext)) + + case OpLoopNext, OpLoopNextValue, OpLoopNextCounter: + boxed := stack.Peek() + iterator := boxed.Unwrap().(core.Iterator) + + // get the next value from the iterator + val, key, err := iterator.Next(ctx) + + if err != nil { + return nil, err + } + + switch op { + case OpLoopNextValue: + stack.Push(val) + case OpLoopNextCounter: + stack.Push(key) + default: + stack.Push(val) + stack.Push(key) + } case OpLoop: // jump back to the start of the loop diff --git a/pkg/runtime/vm_test.go b/pkg/runtime/vm_test.go deleted file mode 100644 index d6cdd528..00000000 --- a/pkg/runtime/vm_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package runtime_test - -import "testing" - -func TestVM(t *testing.T) { - t.Run("Constants", func(t *testing.T) { - - }) -} diff --git a/pkg/stdlib/arrays/append.go b/pkg/stdlib/arrays/append.go index afef30c8..a514a11a 100644 --- a/pkg/stdlib/arrays/append.go +++ b/pkg/stdlib/arrays/append.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // APPEND appends a new item to an array and returns a new array with a given element. @@ -20,7 +18,7 @@ func Append(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err @@ -31,7 +29,7 @@ func Append(_ context.Context, args ...core.Value) (core.Value, error) { unique := values.False if len(args) > 2 { - err = core.ValidateType(args[2], types.Boolean) + err = values.AssertBoolean(args[2]) if err != nil { return values.None, err @@ -60,7 +58,7 @@ func Append(_ context.Context, args ...core.Value) (core.Value, error) { next.Push(item) if !hasDuplicate { - hasDuplicate = item.Compare(arg) == 0 + hasDuplicate = values.Compare(item, arg) == 0 } return true diff --git a/pkg/stdlib/arrays/first.go b/pkg/stdlib/arrays/first.go index 7cb0e4c2..0ee19c82 100644 --- a/pkg/stdlib/arrays/first.go +++ b/pkg/stdlib/arrays/first.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // FIRST returns a first element from a given array. @@ -18,7 +16,7 @@ func First(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, nil diff --git a/pkg/stdlib/arrays/flatten.go b/pkg/stdlib/arrays/flatten.go index 45172154..ac1422b5 100644 --- a/pkg/stdlib/arrays/flatten.go +++ b/pkg/stdlib/arrays/flatten.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // FLATTEN turns an array of arrays into a flat array. @@ -23,7 +21,7 @@ func Flatten(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err @@ -33,7 +31,7 @@ func Flatten(_ context.Context, args ...core.Value) (core.Value, error) { level := 1 if len(args) > 1 { - err = core.ValidateType(args[1], types.Int) + err = values.AssertInt(args[1]) if err != nil { return values.None, err @@ -50,10 +48,12 @@ func Flatten(_ context.Context, args ...core.Value) (core.Value, error) { currentLevel++ input.ForEach(func(value core.Value, idx int) bool { - if value.Type() != types.Array || currentLevel > level { + valueArr, ok := value.(*values.Array) + + if !ok || currentLevel > level { result.Push(value) } else { - unwrap(value.(*values.Array)) + unwrap(valueArr) currentLevel-- } diff --git a/pkg/stdlib/arrays/intersection.go b/pkg/stdlib/arrays/intersection.go index 4e8fe4fe..e849625e 100644 --- a/pkg/stdlib/arrays/intersection.go +++ b/pkg/stdlib/arrays/intersection.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // INTERSECTION return the intersection of all arrays specified. @@ -28,7 +26,7 @@ func sections(args []core.Value, count int) (core.Value, error) { capacity := len(args) for _, i := range args { - err := core.ValidateType(i, types.Array) + err := values.AssertArray(i) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/last.go b/pkg/stdlib/arrays/last.go index fe2b01dc..9e16f2cb 100644 --- a/pkg/stdlib/arrays/last.go +++ b/pkg/stdlib/arrays/last.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // LAST returns the last element of an array. @@ -18,7 +16,7 @@ func Last(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, nil diff --git a/pkg/stdlib/arrays/minus.go b/pkg/stdlib/arrays/minus.go index 39506203..9678e00d 100644 --- a/pkg/stdlib/arrays/minus.go +++ b/pkg/stdlib/arrays/minus.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // MINUS return the difference of all arrays specified. @@ -24,7 +22,7 @@ func Minus(_ context.Context, args ...core.Value) (core.Value, error) { for idx, i := range args { idx := idx - err := core.ValidateType(i, types.Array) + err := values.AssertArray(i) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/nth.go b/pkg/stdlib/arrays/nth.go index dabace1f..f52348d9 100644 --- a/pkg/stdlib/arrays/nth.go +++ b/pkg/stdlib/arrays/nth.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // NTH returns the element of an array at a given position. @@ -21,13 +19,13 @@ func Nth(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err } - err = core.ValidateType(args[1], types.Int) + err = values.AssertInt(args[1]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/pop.go b/pkg/stdlib/arrays/pop.go index db0061b4..15b2c808 100644 --- a/pkg/stdlib/arrays/pop.go +++ b/pkg/stdlib/arrays/pop.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // POP returns a new array without last element. @@ -18,7 +16,7 @@ func Pop(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/position.go b/pkg/stdlib/arrays/position.go index 302aaf4e..d5799a0a 100644 --- a/pkg/stdlib/arrays/position.go +++ b/pkg/stdlib/arrays/position.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // POSITION returns a value indicating whether an element is contained in array. Optionally returns its position. @@ -20,7 +18,7 @@ func Position(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err @@ -31,13 +29,13 @@ func Position(_ context.Context, args ...core.Value) (core.Value, error) { retIdx := false if len(args) > 2 { - err = core.ValidateType(args[2], types.Boolean) + err = values.AssertBoolean(args[2]) if err != nil { return values.None, err } - retIdx = args[2].Compare(values.True) == 0 + retIdx = values.Compare(args[2], values.True) == 0 } position := arr.IndexOf(el) diff --git a/pkg/stdlib/arrays/push.go b/pkg/stdlib/arrays/push.go index b60c8e45..ea45fe68 100644 --- a/pkg/stdlib/arrays/push.go +++ b/pkg/stdlib/arrays/push.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // PUSH create a new array with appended value. @@ -14,30 +12,27 @@ import ( // @param {Boolean} [unique=False] - Read indicating whether to do uniqueness check. // @return {Any[]} - A new array with appended value. func Push(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 2, 3) - - if err != nil { + if err := core.ValidateArgs(args, 2, 3); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.Array) + arr, err := values.CastArray(args[0]) if err != nil { return values.None, err } - - arr := args[0].(*values.Array) + value := args[1] uniq := false if len(args) > 2 { - err = core.ValidateType(args[2], types.Boolean) + err = values.AssertBoolean(args[2]) if err != nil { return values.None, err } - uniq = args[2].Compare(values.True) == 0 + uniq = values.Compare(args[2], values.True) == 0 } result := values.NewArray(int(arr.Length() + 1)) @@ -45,7 +40,7 @@ func Push(_ context.Context, args ...core.Value) (core.Value, error) { arr.ForEach(func(item core.Value, idx int) bool { if uniq && push { - push = item.Compare(value) != 0 + push = values.Compare(item, value) != 0 } result.Push(item) diff --git a/pkg/stdlib/arrays/remove_nth.go b/pkg/stdlib/arrays/remove_nth.go index 498d1d48..f02b209e 100644 --- a/pkg/stdlib/arrays/remove_nth.go +++ b/pkg/stdlib/arrays/remove_nth.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // REMOVE_NTH returns a new array without an element by a given position. @@ -19,13 +17,13 @@ func RemoveNth(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err } - err = core.ValidateType(args[1], types.Int) + err = values.AssertInt(args[1]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/remove_value.go b/pkg/stdlib/arrays/remove_value.go index 8a0babdf..f6a73fc9 100644 --- a/pkg/stdlib/arrays/remove_value.go +++ b/pkg/stdlib/arrays/remove_value.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // REMOVE_VALUE returns a new array with removed all occurrences of value in a given array. @@ -21,7 +19,7 @@ func RemoveValue(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err @@ -32,7 +30,7 @@ func RemoveValue(_ context.Context, args ...core.Value) (core.Value, error) { limit := -1 if len(args) > 2 { - err = core.ValidateType(args[2], types.Int) + err = values.AssertInt(args[2]) if err != nil { return values.None, err @@ -45,7 +43,7 @@ func RemoveValue(_ context.Context, args ...core.Value) (core.Value, error) { counter := 0 arr.ForEach(func(item core.Value, idx int) bool { - remove := item.Compare(value) == 0 + remove := values.Compare(item, value) == 0 if remove { if counter == limit { diff --git a/pkg/stdlib/arrays/remove_values.go b/pkg/stdlib/arrays/remove_values.go index df71ab13..80b8b06c 100644 --- a/pkg/stdlib/arrays/remove_values.go +++ b/pkg/stdlib/arrays/remove_values.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // REMOVE_VALUES returns a new array with removed all occurrences of values in a given array. @@ -19,13 +17,13 @@ func RemoveValues(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err } - err = core.ValidateType(args[1], types.Array) + err = values.AssertArray(args[1]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/shift.go b/pkg/stdlib/arrays/shift.go index f2aa9e7f..ac9df75a 100644 --- a/pkg/stdlib/arrays/shift.go +++ b/pkg/stdlib/arrays/shift.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SHIFT returns a new array without the first element. @@ -18,7 +16,7 @@ func Shift(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/slice.go b/pkg/stdlib/arrays/slice.go index e6cb709d..ab87a2a7 100644 --- a/pkg/stdlib/arrays/slice.go +++ b/pkg/stdlib/arrays/slice.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SLICE returns a new sliced array. @@ -20,13 +18,13 @@ func Slice(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err } - err = core.ValidateType(args[1], types.Int) + err = values.AssertInt(args[1]) if err != nil { return values.None, err @@ -37,12 +35,10 @@ func Slice(_ context.Context, args ...core.Value) (core.Value, error) { length := values.NewInt(int(arr.Length())) if len(args) > 2 { - if args[2].Type() == types.Int { - arg2 := args[2].(values.Int) + lengthArg, ok := args[2].(values.Int) - if arg2 > 0 { - length = start + args[2].(values.Int) - } + if ok && lengthArg > 0 { + length = start + lengthArg } } diff --git a/pkg/stdlib/arrays/sorted.go b/pkg/stdlib/arrays/sorted.go index 8159ee42..66cbd769 100644 --- a/pkg/stdlib/arrays/sorted.go +++ b/pkg/stdlib/arrays/sorted.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SORTED sorts all elements in anyArray. @@ -19,7 +17,7 @@ func Sorted(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/sorted_unique.go b/pkg/stdlib/arrays/sorted_unique.go index e188877f..ac2a1927 100644 --- a/pkg/stdlib/arrays/sorted_unique.go +++ b/pkg/stdlib/arrays/sorted_unique.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SORTED_UNIQUE sorts all elements in anyArray. @@ -20,7 +18,7 @@ func SortedUnique(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/union.go b/pkg/stdlib/arrays/union.go index 0a570c2d..8ce2a248 100644 --- a/pkg/stdlib/arrays/union.go +++ b/pkg/stdlib/arrays/union.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // UNION returns the union of all passed arrays. @@ -18,7 +16,7 @@ func Union(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err @@ -28,7 +26,7 @@ func Union(_ context.Context, args ...core.Value) (core.Value, error) { result := values.NewArray(len(args) * int(firstArrLen)) for _, arg := range args { - err := core.ValidateType(arg, types.Array) + err := values.AssertArray(arg) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/union_distinct.go b/pkg/stdlib/arrays/union_distinct.go index 3a73981a..02fd2c54 100644 --- a/pkg/stdlib/arrays/union_distinct.go +++ b/pkg/stdlib/arrays/union_distinct.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // UNION_DISTINCT returns the union of all passed arrays with unique values. @@ -18,7 +16,7 @@ func UnionDistinct(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err @@ -29,7 +27,7 @@ func UnionDistinct(_ context.Context, args ...core.Value) (core.Value, error) { hashes := make(map[uint64]bool) for _, arg := range args { - err := core.ValidateType(arg, types.Array) + err := values.AssertArray(arg) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/unique.go b/pkg/stdlib/arrays/unique.go index 40f0c59f..8485f374 100644 --- a/pkg/stdlib/arrays/unique.go +++ b/pkg/stdlib/arrays/unique.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // UNIQUE returns all unique elements from a given array. @@ -18,7 +16,7 @@ func Unique(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], types.Array) + err = values.AssertArray(args[0]) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/unshift.go b/pkg/stdlib/arrays/unshift.go index c461878f..87514184 100644 --- a/pkg/stdlib/arrays/unshift.go +++ b/pkg/stdlib/arrays/unshift.go @@ -2,10 +2,8 @@ package arrays import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // UNSHIFT prepends value to a given array. @@ -14,30 +12,20 @@ import ( // @param {Boolean} [unique=False] - Optional value indicating whether a value must be unique to be prepended. Default is false. // @return {Any[]} - New array with prepended value. func Unshift(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 2, 3) - - if err != nil { + if err := core.ValidateArgs(args, 2, 3); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.Array) - - if err != nil { - return values.None, err - } - - arr := args[0].(*values.Array) + arr, err := values.CastArray(args[0]) value := args[1] uniq := values.False if len(args) > 2 { - err = core.ValidateType(args[2], types.Boolean) + uniq, err = values.CastBoolean(args[2]) if err != nil { return values.None, err } - - uniq = args[2].(values.Boolean) } result := values.NewArray(int(arr.Length() + 1)) @@ -58,7 +46,7 @@ func Unshift(_ context.Context, args ...core.Value) (core.Value, error) { result.Push(value) arr.ForEach(func(el core.Value, idx int) bool { - if el.Compare(value) != 0 { + if values.Compare(el, value) != 0 { result.Push(el) return true diff --git a/pkg/stdlib/collections/include.go b/pkg/stdlib/collections/include.go index d0fb44df..98fff3ee 100644 --- a/pkg/stdlib/collections/include.go +++ b/pkg/stdlib/collections/include.go @@ -30,13 +30,13 @@ func Includes(ctx context.Context, args ...core.Value) (core.Value, error) { break case *values.Array: _, result = v.FindOne(func(value core.Value, _ int) bool { - return needle.Compare(value) == 0 + return values.Compare(needle, value) == 0 }) break case *values.Object: _, result = v.Find(func(value core.Value, _ string) bool { - return needle.Compare(value) == 0 + return values.Compare(needle, value) == 0 }) break @@ -48,7 +48,7 @@ func Includes(ctx context.Context, args ...core.Value) (core.Value, error) { } err = core.ForEach(ctx, iter, func(value core.Value, key core.Value) bool { - if needle.Compare(value) == 0 { + if values.Compare(needle, value) == 0 { result = values.True return false @@ -61,11 +61,11 @@ func Includes(ctx context.Context, args ...core.Value) (core.Value, error) { return values.False, err } default: - return values.None, core.TypeError(haystack.Type(), + return values.None, core.TypeError(haystack, types.String, types.Array, types.Object, - core.NewType("Iterable"), + types.Iterable, ) } diff --git a/pkg/stdlib/collections/length.go b/pkg/stdlib/collections/length.go index 5bc75cc7..e72f5852 100644 --- a/pkg/stdlib/collections/length.go +++ b/pkg/stdlib/collections/length.go @@ -2,8 +2,6 @@ package collections import ( "context" - - "github.com/MontFerret/ferret/pkg/runtime/collections" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/values/types" @@ -21,17 +19,17 @@ func Length(_ context.Context, inputs ...core.Value) (core.Value, error) { value := inputs[0] - c, ok := value.(collections.Measurable) + c, ok := value.(core.Measurable) if !ok { - return values.None, core.TypeError(value.Type(), + return values.None, core.TypeError(value, types.String, types.Array, types.Object, types.Binary, - core.NewType("Measurable"), + types.Measurable, ) } - return c.Length(), nil + return values.Int(c.Length()), nil } diff --git a/pkg/stdlib/collections/reverse.go b/pkg/stdlib/collections/reverse.go index 01b77197..0e18e8f8 100644 --- a/pkg/stdlib/collections/reverse.go +++ b/pkg/stdlib/collections/reverse.go @@ -2,7 +2,6 @@ package collections import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/runtime/core" @@ -19,12 +18,6 @@ func Reverse(_ context.Context, args ...core.Value) (core.Value, error) { return values.EmptyString, err } - err = core.ValidateType(args[0], types.Array, types.String) - - if err != nil { - return values.None, err - } - switch col := args[0].(type) { case values.String: runes := []rune(string(col)) @@ -47,6 +40,6 @@ func Reverse(_ context.Context, args ...core.Value) (core.Value, error) { return result, nil default: - return values.None, nil + return values.None, core.TypeError(args[0], types.Array, types.String) } } diff --git a/pkg/stdlib/datetime/add_subtract.go b/pkg/stdlib/datetime/add_subtract.go index f9ec280a..87232651 100644 --- a/pkg/stdlib/datetime/add_subtract.go +++ b/pkg/stdlib/datetime/add_subtract.go @@ -2,10 +2,8 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) var ( @@ -75,17 +73,19 @@ func DateSubtract(_ context.Context, args ...core.Value) (core.Value, error) { } func getArgs(args []core.Value) (values.DateTime, values.Int, values.String, error) { - err := core.ValidateArgs(args, 3, 3) - if err != nil { + if err := core.ValidateArgs(args, 3, 3); err != nil { return emptyDateTime, emptyInt, emptyString, err } - err = core.ValidateValueTypePairs( - core.NewPairValueType(args[0], types.DateTime), - core.NewPairValueType(args[1], types.Int), - core.NewPairValueType(args[2], types.String), - ) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { + return emptyDateTime, emptyInt, emptyString, err + } + + if err := values.AssertInt(args[1]); err != nil { + return emptyDateTime, emptyInt, emptyString, err + } + + if err := values.AssertString(args[2]); err != nil { return emptyDateTime, emptyInt, emptyString, err } diff --git a/pkg/stdlib/datetime/compare.go b/pkg/stdlib/datetime/compare.go index 64e412ee..980a23bb 100644 --- a/pkg/stdlib/datetime/compare.go +++ b/pkg/stdlib/datetime/compare.go @@ -2,12 +2,10 @@ package datetime import ( "context" - "github.com/pkg/errors" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_COMPARE checks if two partial dates match. @@ -17,17 +15,19 @@ import ( // @param {String} [unitRangeEnd="millisecond"] - Unit to end with. Error will be returned if unitRangeStart unit less that unitRangeEnd. // @return {Boolean} - True if the dates match, else false. func DateCompare(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 3, 4) - if err != nil { + if err := core.ValidateArgs(args, 3, 4); err != nil { return values.None, err } - err = core.ValidateValueTypePairs( - core.NewPairValueType(args[0], types.DateTime), - core.NewPairValueType(args[1], types.DateTime), - core.NewPairValueType(args[2], types.String), - ) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { + return values.None, err + } + + if err := values.AssertDateTime(args[1]); err != nil { + return values.None, err + } + + if err := values.AssertString(args[2]); err != nil { return values.None, err } @@ -37,9 +37,7 @@ func DateCompare(_ context.Context, args ...core.Value) (core.Value, error) { rangeEnd := values.NewString("millisecond") if len(args) == 4 { - err = core.ValidateType(args[3], types.String) - - if err != nil { + if err := values.AssertString(args[3]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/date.go b/pkg/stdlib/datetime/date.go index 368b38e5..87f61652 100644 --- a/pkg/stdlib/datetime/date.go +++ b/pkg/stdlib/datetime/date.go @@ -6,7 +6,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE parses a formatted string and returns DateTime object it represents. @@ -18,7 +17,7 @@ func Date(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - if err := core.ValidateType(args[0], types.String); err != nil { + if err := values.AssertString(args[0]); err != nil { return values.None, err } @@ -26,11 +25,11 @@ func Date(_ context.Context, args ...core.Value) (core.Value, error) { layout := values.DefaultTimeLayout if len(args) > 1 { - if err := core.ValidateType(args[1], types.String); err != nil { + if err := values.AssertString(args[1]); err != nil { return values.None, err } - layout = values.ToString(args[1]).String() + layout = args[1].String() } t, err := time.Parse(layout, str.String()) diff --git a/pkg/stdlib/datetime/day.go b/pkg/stdlib/datetime/day.go index d1855dc5..3b6bb5b7 100644 --- a/pkg/stdlib/datetime/day.go +++ b/pkg/stdlib/datetime/day.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_DAY returns the day of date as a number. // @param {DateTime} date - Source DateTime. // @return {Int} - A day number. func DateDay(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/dayofweek.go b/pkg/stdlib/datetime/dayofweek.go index ef1eee4d..ab49d3b3 100644 --- a/pkg/stdlib/datetime/dayofweek.go +++ b/pkg/stdlib/datetime/dayofweek.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_DAYOFWEEK returns number of the weekday from the date. Sunday is the 0th day of week. // @param {DateTime} date - Source DateTime. // @return {Int} - Number of the weekday. func DateDayOfWeek(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/dayofyear.go b/pkg/stdlib/datetime/dayofyear.go index 9be9c3bd..4a776829 100644 --- a/pkg/stdlib/datetime/dayofyear.go +++ b/pkg/stdlib/datetime/dayofyear.go @@ -2,10 +2,8 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_DAYOFYEAR returns the day of year number of date. @@ -13,13 +11,11 @@ import ( // @param {DateTime} date - Source DateTime. // @return {Int} - A day of year number. func DateDayOfYear(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/daysinmonth.go b/pkg/stdlib/datetime/daysinmonth.go index 2df51c9c..b202f9b4 100644 --- a/pkg/stdlib/datetime/daysinmonth.go +++ b/pkg/stdlib/datetime/daysinmonth.go @@ -6,7 +6,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) var daysCount = map[time.Month]int{ @@ -28,13 +27,11 @@ var daysCount = map[time.Month]int{ // @param {DateTime} date - Source DateTime. // @return {Int} - Number of the days. func DateDaysInMonth(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/diff.go b/pkg/stdlib/datetime/diff.go index 817f7a59..bc97f60d 100644 --- a/pkg/stdlib/datetime/diff.go +++ b/pkg/stdlib/datetime/diff.go @@ -2,10 +2,8 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_DIFF returns the difference between two dates in given time unit. @@ -15,17 +13,19 @@ import ( // @param {Boolean} [asFloat=False] - If true amount of unit will be as float. // @return {Int | Float} - Difference between date1 and date2. func DateDiff(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 3, 4) - if err != nil { + if err := core.ValidateArgs(args, 3, 4); err != nil { return values.None, err } - err = core.ValidateValueTypePairs( - core.NewPairValueType(args[0], types.DateTime), - core.NewPairValueType(args[1], types.DateTime), - core.NewPairValueType(args[2], types.String), - ) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { + return values.None, err + } + + if err := values.AssertDateTime(args[1]); err != nil { + return values.None, err + } + + if err := values.AssertString(args[2]); err != nil { return values.None, err } @@ -35,10 +35,10 @@ func DateDiff(_ context.Context, args ...core.Value) (core.Value, error) { isFloat := values.NewBoolean(false) if len(args) == 4 { - err = core.ValidateType(args[3], types.Boolean) - if err != nil { + if err := values.AssertBoolean(args[3]); err != nil { return values.None, err } + isFloat = args[3].(values.Boolean) } diff --git a/pkg/stdlib/datetime/format.go b/pkg/stdlib/datetime/format.go index 9ed21bc5..c51402c6 100644 --- a/pkg/stdlib/datetime/format.go +++ b/pkg/stdlib/datetime/format.go @@ -2,10 +2,8 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_FORMAT format date according to the given format string. @@ -13,18 +11,15 @@ import ( // @param {String} format - String format. // @return {String} - Formatted date. func DateFormat(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 2, 2) - if err != nil { + if err := core.ValidateArgs(args, 2, 2); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } - err = core.ValidateType(args[1], types.String) - if err != nil { + if err := values.AssertString(args[1]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/hour.go b/pkg/stdlib/datetime/hour.go index 7dac0798..56a1dd10 100644 --- a/pkg/stdlib/datetime/hour.go +++ b/pkg/stdlib/datetime/hour.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_HOUR returns the hour of date as a number. // @param {DateTime} date - Source DateTime. // @return {Int} - An hour number. func DateHour(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/leapyear.go b/pkg/stdlib/datetime/leapyear.go index c3efaa58..8c344a92 100644 --- a/pkg/stdlib/datetime/leapyear.go +++ b/pkg/stdlib/datetime/leapyear.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_LEAPYEAR returns true if date is in a leap year else false. // @param {DateTime} date - Source DateTime. // @return {Boolean} - Date is in a leap year. func DateLeapYear(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/millisecond.go b/pkg/stdlib/datetime/millisecond.go index 02c45ccd..c2b2066a 100644 --- a/pkg/stdlib/datetime/millisecond.go +++ b/pkg/stdlib/datetime/millisecond.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_MILLISECOND returns the millisecond of date as a number. // @param {DateTime} date - Source DateTime. // @return {Int} - A millisecond number. func DateMillisecond(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/minute.go b/pkg/stdlib/datetime/minute.go index 4a96d93a..f9b4b7cf 100644 --- a/pkg/stdlib/datetime/minute.go +++ b/pkg/stdlib/datetime/minute.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_MINUTE returns the minute of date as a number. // @param {DateTime} date -Source DateTime. // @return {Int} - A minute number. func DateMinute(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/month.go b/pkg/stdlib/datetime/month.go index cd6c533a..d16437f1 100644 --- a/pkg/stdlib/datetime/month.go +++ b/pkg/stdlib/datetime/month.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_MONTH returns the month of date as a number. // @param {DateTime} date - Source DateTime. // @return {Int} - A month number. func DateMonth(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/quarter.go b/pkg/stdlib/datetime/quarter.go index b08725b3..cdb52442 100644 --- a/pkg/stdlib/datetime/quarter.go +++ b/pkg/stdlib/datetime/quarter.go @@ -6,20 +6,17 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_QUARTER returns which quarter date belongs to. // @param {DateTime} date - Source DateTime. // @return {Int} - A quarter number. func DateQuarter(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/second.go b/pkg/stdlib/datetime/second.go index 84fb559c..cd219df7 100644 --- a/pkg/stdlib/datetime/second.go +++ b/pkg/stdlib/datetime/second.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_SECOND returns the second of date as a number. // @param {DateTime} date - Source DateTime. // @return {Int} - A second number. func DateSecond(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/year.go b/pkg/stdlib/datetime/year.go index 6251d58a..c29afee6 100644 --- a/pkg/stdlib/datetime/year.go +++ b/pkg/stdlib/datetime/year.go @@ -2,23 +2,19 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DATE_YEAR returns the year extracted from the given date. // @param {DateTime} date - Source DateTime. // @return {Int} - A year number. func DateYear(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.DateTime) - if err != nil { + if err := values.AssertDateTime(args[0]); err != nil { return values.None, err } diff --git a/pkg/stdlib/html/attr_remove.go b/pkg/stdlib/html/attr_remove.go index 5d96e9f8..22ec0bc6 100644 --- a/pkg/stdlib/html/attr_remove.go +++ b/pkg/stdlib/html/attr_remove.go @@ -2,20 +2,16 @@ package html import ( "context" - "github.com/MontFerret/ferret/pkg/drivers" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ATTR_REMOVE removes single or more attribute(s) of a given element. // @param {HTMLPage | HTMLDocument | HTMLElement} node - Target node. // @param {String, repeated} attrNames - Attribute name(s). func AttributeRemove(ctx context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 2, core.MaxArgs) - - if err != nil { + if err := core.ValidateArgs(args, 2, core.MaxArgs); err != nil { return values.None, err } @@ -29,10 +25,10 @@ func AttributeRemove(ctx context.Context, args ...core.Value) (core.Value, error attrsStr := make([]values.String, 0, len(attrs)) for _, attr := range attrs { - str, ok := attr.(values.String) + str, err := values.CastString(attr) - if !ok { - return values.None, core.TypeError(attr.Type(), types.String) + if err != nil { + return values.None, err } attrsStr = append(attrsStr, str) diff --git a/pkg/stdlib/io/fs/write.go b/pkg/stdlib/io/fs/write.go index 54d93997..7a087867 100644 --- a/pkg/stdlib/io/fs/write.go +++ b/pkg/stdlib/io/fs/write.go @@ -25,17 +25,8 @@ func Write(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - fpath := args[0].String() - arg1 := args[1] - - var data []byte - - if arg1.Type() == types.Binary { - data = arg1.(values.Binary) - } else { - data = []byte(arg1.String()) - } - + fpath := values.ToString(args[0]) + data := values.ToBinary(args[1]) params := defaultParams if len(args) == 3 { @@ -50,7 +41,7 @@ func Write(_ context.Context, args ...core.Value) (core.Value, error) { } // 0666 - read & write - file, err := os.OpenFile(fpath, params.ModeFlag, 0666) + file, err := os.OpenFile(string(fpath), params.ModeFlag, 0666) if err != nil { return values.None, core.Error(err, "open file") diff --git a/pkg/stdlib/io/net/http/get.go b/pkg/stdlib/io/net/http/get.go index f2e051cc..ce37ebb3 100644 --- a/pkg/stdlib/io/net/http/get.go +++ b/pkg/stdlib/io/net/http/get.go @@ -21,18 +21,17 @@ func GET(ctx context.Context, args ...core.Value) (core.Value, error) { arg := args[0] - if err := core.ValidateType(arg, types.String, types.Object); err != nil { - return values.None, err - } - - if arg.Type() == types.String { + switch v := arg.(type) { + case values.String: return makeRequest(ctx, Params{ Method: "GET", - URL: values.ToString(arg), + URL: v, Headers: nil, Body: nil, }) + case *values.Object: + return execMethod(ctx, h.MethodGet, args) + default: + return values.None, core.TypeError(arg, types.String, types.Object) } - - return execMethod(ctx, h.MethodGet, args) } diff --git a/pkg/stdlib/io/net/http/request.go b/pkg/stdlib/io/net/http/request.go index a404416b..42557800 100644 --- a/pkg/stdlib/io/net/http/request.go +++ b/pkg/stdlib/io/net/http/request.go @@ -34,13 +34,13 @@ func execMethod(ctx context.Context, method values.String, args []core.Value) (c return values.None, err } - arg := args[0] + params, err := values.CastObject(args[0]) - if err := core.ValidateType(arg, types.Object); err != nil { + if err != nil { return values.None, err } - p, err := newParamsFrom(arg.(*values.Object)) + p, err := newParamsFrom(params) if err != nil { return values.None, err @@ -118,8 +118,10 @@ func newParamsFrom(obj *values.Object) (Params, error) { body, exists := obj.Get("body") if exists { - if core.IsTypeOf(body, types.Binary) { - p.Body = body.(values.Binary) + bin, ok := body.(values.Binary) + + if ok { + p.Body = bin } else { j, err := body.MarshalJSON() diff --git a/pkg/stdlib/lib.go b/pkg/stdlib/lib.go index ab3efd02..3e41de09 100644 --- a/pkg/stdlib/lib.go +++ b/pkg/stdlib/lib.go @@ -5,7 +5,6 @@ import ( "github.com/MontFerret/ferret/pkg/stdlib/arrays" "github.com/MontFerret/ferret/pkg/stdlib/collections" "github.com/MontFerret/ferret/pkg/stdlib/datetime" - "github.com/MontFerret/ferret/pkg/stdlib/html" "github.com/MontFerret/ferret/pkg/stdlib/io" "github.com/MontFerret/ferret/pkg/stdlib/math" "github.com/MontFerret/ferret/pkg/stdlib/objects" @@ -45,9 +44,9 @@ func RegisterLib(ns core.Namespace) error { return err } - if err := html.RegisterLib(ns); err != nil { - return err - } + //if err := html.RegisterLib(ns); err != nil { + // return err + //} if err := io.RegisterLib(ns); err != nil { return err diff --git a/pkg/stdlib/math/cos.go b/pkg/stdlib/math/cos.go index 647b5dab..35c9627d 100644 --- a/pkg/stdlib/math/cos.go +++ b/pkg/stdlib/math/cos.go @@ -13,15 +13,11 @@ import ( // @param {Int | Float} number - Input number. // @return {Float} - The cosine of a given number. func Cos(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.Int, types.Float) - - if err != nil { + if err := core.ValidateType(args[0], types.Int, types.Float); err != nil { return values.None, err } diff --git a/pkg/stdlib/math/lib.go b/pkg/stdlib/math/lib.go index 41d76e0a..75b01cb8 100644 --- a/pkg/stdlib/math/lib.go +++ b/pkg/stdlib/math/lib.go @@ -5,7 +5,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) const ( @@ -55,9 +54,12 @@ func RegisterLib(ns core.Namespace) error { } func toFloat(arg core.Value) float64 { - if arg.Type() == types.Int { - return float64(arg.(values.Int)) + switch v := arg.(type) { + case values.Float: + return float64(v) + case values.Int: + return float64(v) + default: + return 0 } - - return float64(arg.(values.Float)) } diff --git a/pkg/stdlib/objects/keep_keys.go b/pkg/stdlib/objects/keep_keys.go index f32fa734..6b4121ec 100644 --- a/pkg/stdlib/objects/keep_keys.go +++ b/pkg/stdlib/objects/keep_keys.go @@ -13,27 +13,29 @@ import ( // @param {String, repeated} keys - Keys that need to be kept. // @return {Object} - New Object with only given keys. func KeepKeys(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 2, core.MaxArgs) - - if err != nil { + if err := core.ValidateArgs(args, 2, core.MaxArgs); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.Object) - - if err != nil { + if err := core.ValidateType(args[0], types.Object); err != nil { return values.None, err } - keys := values.NewArrayWith(args[1:]...) + var keys *values.Array - if len(args) == 2 && args[1].Type().Equals(types.Array) { - keys = args[1].(*values.Array) - } + if len(args) == 2 { + arr, ok := args[1].(*values.Array) - err = validateArrayOf(types.String, keys) + if ok { + keys = arr + } + } - if err != nil { + if keys == nil { + keys = values.NewArrayWith(args[1:]...) + } + + if err := validateArrayOf(types.String, keys); err != nil { return values.None, err } diff --git a/pkg/stdlib/objects/merge.go b/pkg/stdlib/objects/merge.go index 4712a908..b80d10b8 100644 --- a/pkg/stdlib/objects/merge.go +++ b/pkg/stdlib/objects/merge.go @@ -12,21 +12,25 @@ import ( // @param {Object, repeated} objects - Objects to merge. // @return {Object} - Object created by merging. func Merge(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, core.MaxArgs) - - if err != nil { + if err := core.ValidateArgs(args, 1, core.MaxArgs); err != nil { return values.None, err } - objs := values.NewArrayWith(args...) + var objs *values.Array + + if len(args) == 1 { + arr, ok := args[0].(*values.Array) - if len(args) == 1 && args[0].Type().Equals(types.Array) { - objs = args[0].(*values.Array) + if ok { + objs = arr + } } - err = validateArrayOf(types.Object, objs) + if objs == nil { + objs = values.NewArrayWith(args...) + } - if err != nil { + if err := validateArrayOf(types.Object, objs); err != nil { return values.None, err } diff --git a/pkg/stdlib/objects/merge_recursive.go b/pkg/stdlib/objects/merge_recursive.go index 10552b25..8c6e94d5 100644 --- a/pkg/stdlib/objects/merge_recursive.go +++ b/pkg/stdlib/objects/merge_recursive.go @@ -33,16 +33,21 @@ func MergeRecursive(_ context.Context, args ...core.Value) (core.Value, error) { } func merge(src, dst core.Value) core.Value { - if src.Type() != dst.Type() { - return dst + if !types.Equal(core.Reflect(src), core.Reflect(dst)) { + return src } - if src.Type() != types.Object { + srcObj, ok := src.(*values.Object) + + if !ok { return dst } - srcObj := src.(*values.Object) - dstObj := dst.(*values.Object) + dstObj, ok := dst.(*values.Object) + + if !ok { + return src + } if dstObj.Length() == 0 { return src diff --git a/pkg/stdlib/path/join.go b/pkg/stdlib/path/join.go index 51f852a3..4c3f9bdc 100644 --- a/pkg/stdlib/path/join.go +++ b/pkg/stdlib/path/join.go @@ -13,18 +13,19 @@ import ( // @param {String, repeated | String[]} elements - The path elements // @return {String} - Single path from the given elements. func Join(_ context.Context, args ...core.Value) (core.Value, error) { - argsCount := len(args) + if argsCount == 0 { return values.EmptyString, nil } - arr := &values.Array{} + var arr *values.Array - if argsCount != 1 && args[0].Type() != types.Array { + switch arg := args[0].(type) { + case *values.Array: + arr = arg + default: arr = values.NewArrayWith(args...) - } else { - arr = args[0].(*values.Array) } elems := make([]string, arr.Length()) diff --git a/pkg/stdlib/strings/concat.go b/pkg/stdlib/strings/concat.go index 59300605..e5d92c91 100644 --- a/pkg/stdlib/strings/concat.go +++ b/pkg/stdlib/strings/concat.go @@ -5,16 +5,13 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // CONCAT concatenates one or more instances of String, or an Array. // @param {String, repeated | String[]} src - The source string / array. // @return {String} - A string value. func Concat(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, core.MaxArgs) - - if err != nil { + if err := core.ValidateArgs(args, 1, core.MaxArgs); err != nil { return values.EmptyString, err } @@ -22,16 +19,18 @@ func Concat(_ context.Context, args ...core.Value) (core.Value, error) { res := values.EmptyString - if argsCount == 1 && args[0].Type() == types.Array { - arr := args[0].(*values.Array) + if argsCount == 1 { + argv, ok := args[0].(*values.Array) - arr.ForEach(func(value core.Value, _ int) bool { - res = res.Concat(value) + if ok { + argv.ForEach(func(value core.Value, _ int) bool { + res = res.Concat(value) - return true - }) + return true + }) - return res, nil + return res, nil + } } for _, str := range args { @@ -54,26 +53,19 @@ func ConcatWithSeparator(_ context.Context, args ...core.Value) (core.Value, err separator := args[0] - if separator.Type() != types.String { + separator, ok := args[0].(values.String) + + if !ok { separator = values.NewString(separator.String()) } res := values.EmptyString for idx, arg := range args[1:] { - if arg.Type() != types.Array { - if arg.Type() != types.None { - if idx > 0 { - res = res.Concat(separator) - } - - res = res.Concat(arg) - } - } else { - arr := arg.(*values.Array) - - arr.ForEach(func(value core.Value, idx int) bool { - if value.Type() != types.None { + switch argv := arg.(type) { + case *values.Array: + argv.ForEach(func(value core.Value, idx int) bool { + if value != values.None { if idx > 0 { res = res.Concat(separator) } @@ -83,6 +75,15 @@ func ConcatWithSeparator(_ context.Context, args ...core.Value) (core.Value, err return true }) + default: + if argv != values.None { + if idx > 0 { + res = res.Concat(separator) + } + + res = res.Concat(argv) + } + } } diff --git a/pkg/stdlib/strings/contains.go b/pkg/stdlib/strings/contains.go index b20440c5..699ff6b1 100644 --- a/pkg/stdlib/strings/contains.go +++ b/pkg/stdlib/strings/contains.go @@ -5,7 +5,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // CONTAINS returns a value indicating whether a specified substring occurs within a string. @@ -14,37 +13,16 @@ import ( // @param {Boolean} [returnIndex=False] - Values which indicates whether to return the character position of the match is returned instead of a boolean. // @return {Boolean | Int} - A value indicating whether a specified substring occurs within a string. func Contains(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 2, 3) - - if err != nil { + if err := core.ValidateArgs(args, 2, 3); err != nil { return values.False, err } - var text values.String - var search values.String + text := values.SafeCastString(args[0], values.EmptyString) + search := values.SafeCastString(args[1], values.EmptyString) returnIndex := values.False - arg1 := args[0] - arg2 := args[1] - - if arg1.Type() == types.String { - text = arg1.(values.String) - } else { - text = values.NewString(arg1.String()) - } - - if arg2.Type() == types.String { - search = arg2.(values.String) - } else { - search = values.NewString(arg2.String()) - } - if len(args) > 2 { - arg3 := args[2] - - if arg3.Type() == types.Boolean { - returnIndex = arg3.(values.Boolean) - } + returnIndex = values.SafeCastBoolean(args[2], values.False) } if returnIndex == values.True { diff --git a/pkg/stdlib/strings/find.go b/pkg/stdlib/strings/find.go index 1599fb99..470c195e 100644 --- a/pkg/stdlib/strings/find.go +++ b/pkg/stdlib/strings/find.go @@ -6,7 +6,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // FIND_FIRST returns the position of the first occurrence of the string search inside the string text. Positions start at 0. @@ -31,18 +30,18 @@ func FindFirst(_ context.Context, args ...core.Value) (core.Value, error) { end := values.NewInt(len(text)) if argsCount == 3 { - arg3 := args[2] + arg3, ok := args[2].(values.Int) - if arg3.Type() == types.Int { - start = arg3.(values.Int) + if ok { + start = arg3 } } if argsCount == 4 { - arg4 := args[3] + arg4, ok := args[3].(values.Int) - if arg4.Type() == types.Int { - end = arg4.(values.Int) + if ok { + end = arg4 } } @@ -77,18 +76,18 @@ func FindLast(_ context.Context, args ...core.Value) (core.Value, error) { end := values.NewInt(len(text)) if argsCount == 3 { - arg3 := args[2] + arg3, ok := args[2].(values.Int) - if arg3.Type() == types.Int { - start = arg3.(values.Int) + if ok { + start = arg3 } } if argsCount == 4 { - arg4 := args[3] + arg4, ok := args[3].(values.Int) - if arg4.Type() == types.Int { - end = arg4.(values.Int) + if ok { + end = arg4 } } diff --git a/pkg/stdlib/strings/regex.go b/pkg/stdlib/strings/regex.go index 0919272d..97e46c44 100644 --- a/pkg/stdlib/strings/regex.go +++ b/pkg/stdlib/strings/regex.go @@ -6,7 +6,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // REGEX_MATCH returns the matches in the given string text, using the regex. @@ -68,8 +67,10 @@ func RegexSplit(_ context.Context, args ...core.Value) (core.Value, error) { limit := -1 if len(args) > 2 { - if args[2].Type() == types.Int { - limit = int(args[2].(values.Int)) + arg2, ok := args[2].(values.Int) + + if ok { + limit = int(arg2) } } diff --git a/pkg/stdlib/strings/split.go b/pkg/stdlib/strings/split.go index b822b912..38795418 100644 --- a/pkg/stdlib/strings/split.go +++ b/pkg/stdlib/strings/split.go @@ -6,7 +6,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SPLIT splits the given string value into a list of strings, using the separator. @@ -26,8 +25,10 @@ func Split(_ context.Context, args ...core.Value) (core.Value, error) { limit := -1 if len(args) > 2 { - if args[2].Type() == types.Int { - limit = int(args[2].(values.Int)) + args2, ok := args[2].(values.Int) + + if ok { + limit = int(args2) } } diff --git a/pkg/stdlib/strings/substitute.go b/pkg/stdlib/strings/substitute.go index cdb5c310..1762bc0c 100644 --- a/pkg/stdlib/strings/substitute.go +++ b/pkg/stdlib/strings/substitute.go @@ -6,7 +6,6 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SUBSTITUTE replaces search values in the string value. @@ -32,8 +31,10 @@ func Substitute(_ context.Context, args ...core.Value) (core.Value, error) { } if len(args) > 3 { - if args[3].Type() == types.Int { - limit = int(args[3].(values.Int)) + arg3, ok := args[3].(values.Int) + + if ok { + limit = int(arg3) } } diff --git a/pkg/stdlib/strings/substr.go b/pkg/stdlib/strings/substr.go index 65d26827..08d451d6 100644 --- a/pkg/stdlib/strings/substr.go +++ b/pkg/stdlib/strings/substr.go @@ -33,8 +33,10 @@ func Substring(_ context.Context, args ...core.Value) (core.Value, error) { length := size if len(args) > 2 { - if args[2].Type() == types.Int { - length = int(args[2].(values.Int)) + arg2, ok := args[2].(values.Int) + + if ok { + length = int(arg2) } } @@ -70,9 +72,10 @@ func Left(_ context.Context, args ...core.Value) (core.Value, error) { runes := []rune(text) var pos int + arg1, ok := args[1].(values.Int) - if args[1].Type() == types.Int { - pos = int(args[1].(values.Int)) + if ok { + pos = int(arg1) } if len(text) < pos { @@ -98,8 +101,10 @@ func Right(_ context.Context, args ...core.Value) (core.Value, error) { size := len(runes) pos := size - if args[1].Type() == types.Int { - pos = int(args[1].(values.Int)) + arg1, ok := args[1].(values.Int) + + if ok { + pos = int(arg1) } if len(text) < pos { diff --git a/pkg/stdlib/testing/array.go b/pkg/stdlib/testing/array.go index 4a151926..38057357 100644 --- a/pkg/stdlib/testing/array.go +++ b/pkg/stdlib/testing/array.go @@ -2,9 +2,9 @@ package testing import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/testing/base" ) @@ -18,6 +18,10 @@ var Array = base.Assertion{ MinArgs: 1, MaxArgs: 2, Fn: func(ctx context.Context, args []core.Value) (bool, error) { - return args[0].Type() == types.Array, nil + if err := values.AssertArray(args[0]); err != nil { + return false, err + } + + return true, nil }, } diff --git a/pkg/stdlib/testing/base/compare.go b/pkg/stdlib/testing/base/compare.go index 43191e01..eada659e 100644 --- a/pkg/stdlib/testing/base/compare.go +++ b/pkg/stdlib/testing/base/compare.go @@ -1,6 +1,9 @@ package base -import "github.com/MontFerret/ferret/pkg/runtime/core" +import ( + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values" +) type CompareOperator int @@ -44,18 +47,18 @@ func (op CompareOperator) Compare(args []core.Value) (bool, error) { switch op { case NotEqualOp: - result = actual.Compare(expected) != 0 + result = values.Compare(actual, expected) != 0 case EqualOp: - result = actual.Compare(expected) == 0 + result = values.Compare(actual, expected) == 0 case LessOp: - result = actual.Compare(expected) == -1 + result = values.Compare(actual, expected) == -1 case LessOrEqualOp: - c := actual.Compare(expected) + c := values.Compare(actual, expected) result = c == -1 || c == 0 case GreaterOp: - result = actual.Compare(expected) == 1 + result = values.Compare(actual, expected) == 1 default: - c := actual.Compare(expected) + c := values.Compare(actual, expected) result = c == 1 || c == 0 } diff --git a/pkg/stdlib/testing/base/format.go b/pkg/stdlib/testing/base/format.go index 4f51b210..05548b57 100644 --- a/pkg/stdlib/testing/base/format.go +++ b/pkg/stdlib/testing/base/format.go @@ -14,5 +14,5 @@ func FormatValue(val core.Value) string { valStr = "none" } - return fmt.Sprintf("[%s] '%s'", val.Type(), valStr) + return fmt.Sprintf("[%s] '%s'", core.Reflect(val), valStr) } diff --git a/pkg/stdlib/testing/binary.go b/pkg/stdlib/testing/binary.go index e13e7a8f..a499561c 100644 --- a/pkg/stdlib/testing/binary.go +++ b/pkg/stdlib/testing/binary.go @@ -2,9 +2,9 @@ package testing import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/testing/base" ) @@ -18,6 +18,10 @@ var Binary = base.Assertion{ MinArgs: 1, MaxArgs: 2, Fn: func(ctx context.Context, args []core.Value) (bool, error) { - return args[0].Type() == types.Binary, nil + if err := values.AssertBinary(args[0]); err != nil { + return false, err + } + + return true, nil }, } diff --git a/pkg/stdlib/testing/datetime.go b/pkg/stdlib/testing/datetime.go index 016c6243..4702f407 100644 --- a/pkg/stdlib/testing/datetime.go +++ b/pkg/stdlib/testing/datetime.go @@ -2,9 +2,9 @@ package testing import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/testing/base" ) @@ -18,6 +18,10 @@ var DateTime = base.Assertion{ MinArgs: 1, MaxArgs: 2, Fn: func(ctx context.Context, args []core.Value) (bool, error) { - return args[0].Type() == types.DateTime, nil + if err := values.AssertDateTime(args[0]); err != nil { + return false, err + } + + return true, nil }, } diff --git a/pkg/stdlib/testing/float.go b/pkg/stdlib/testing/float.go index 027148b3..a1c83b89 100644 --- a/pkg/stdlib/testing/float.go +++ b/pkg/stdlib/testing/float.go @@ -2,9 +2,9 @@ package testing import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/testing/base" ) @@ -18,6 +18,10 @@ var Float = base.Assertion{ MinArgs: 1, MaxArgs: 2, Fn: func(ctx context.Context, args []core.Value) (bool, error) { - return args[0].Type() == types.Float, nil + if err := values.AssertFloat(args[0]); err != nil { + return false, err + } + + return true, nil }, } diff --git a/pkg/stdlib/testing/include.go b/pkg/stdlib/testing/include.go index 8cec4e85..bb9a0963 100644 --- a/pkg/stdlib/testing/include.go +++ b/pkg/stdlib/testing/include.go @@ -30,6 +30,6 @@ var Include = base.Assertion{ return false, err } - return out.Compare(values.True) == 0, nil + return values.Compare(out, values.True) == 0, nil }, } diff --git a/pkg/stdlib/testing/int.go b/pkg/stdlib/testing/int.go index cc9f59f5..365c22b4 100644 --- a/pkg/stdlib/testing/int.go +++ b/pkg/stdlib/testing/int.go @@ -2,9 +2,9 @@ package testing import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/testing/base" ) @@ -18,6 +18,10 @@ var Int = base.Assertion{ MinArgs: 1, MaxArgs: 2, Fn: func(ctx context.Context, args []core.Value) (bool, error) { - return args[0].Type() == types.Int, nil + if err := values.AssertInt(args[0]); err != nil { + return false, err + } + + return true, nil }, } diff --git a/pkg/stdlib/testing/len.go b/pkg/stdlib/testing/len.go index 0a1699d3..27eb05b1 100644 --- a/pkg/stdlib/testing/len.go +++ b/pkg/stdlib/testing/len.go @@ -3,6 +3,7 @@ package testing import ( "context" "fmt" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/stdlib/collections" @@ -29,6 +30,6 @@ var Len = base.Assertion{ return false, err } - return out.Compare(size) == 0, nil + return values.Compare(out, size) == 0, nil }, } diff --git a/pkg/stdlib/testing/match.go b/pkg/stdlib/testing/match.go index 1433f74b..62e84ff9 100644 --- a/pkg/stdlib/testing/match.go +++ b/pkg/stdlib/testing/match.go @@ -29,6 +29,6 @@ var Match = base.Assertion{ return false, err } - return out.Compare(values.True) == 0, nil + return values.Compare(out, values.True) == 0, nil }, } diff --git a/pkg/stdlib/testing/object.go b/pkg/stdlib/testing/object.go index 8620969e..799c1949 100644 --- a/pkg/stdlib/testing/object.go +++ b/pkg/stdlib/testing/object.go @@ -2,9 +2,9 @@ package testing import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/testing/base" ) @@ -18,6 +18,10 @@ var Object = base.Assertion{ MinArgs: 1, MaxArgs: 2, Fn: func(ctx context.Context, args []core.Value) (bool, error) { - return args[0].Type() == types.Object, nil + if err := values.AssertObject(args[0]); err != nil { + return false, err + } + + return true, nil }, } diff --git a/pkg/stdlib/testing/string.go b/pkg/stdlib/testing/string.go index 214e3a7b..ac629bce 100644 --- a/pkg/stdlib/testing/string.go +++ b/pkg/stdlib/testing/string.go @@ -2,9 +2,9 @@ package testing import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/testing/base" ) @@ -18,6 +18,10 @@ var String = base.Assertion{ MinArgs: 1, MaxArgs: 2, Fn: func(ctx context.Context, args []core.Value) (bool, error) { - return args[0].Type() == types.String, nil + if err := values.AssertString(args[0]); err != nil { + return false, err + } + + return true, nil }, } diff --git a/pkg/stdlib/types/is_nan.go b/pkg/stdlib/types/is_nan.go index 4e643c3b..3aa50e9c 100644 --- a/pkg/stdlib/types/is_nan.go +++ b/pkg/stdlib/types/is_nan.go @@ -5,22 +5,21 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IS_NAN checks whether value is NaN. // @param {Any} value - Input value of arbitrary type. // @return {Boolean} - Returns true if value is NaN, otherwise false. func IsNaN(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - if args[0].Type() != types.Float { + val, err := values.CastFloat(args[0]) + + if err != nil { return values.False, nil } - return values.IsNaN(args[0].(values.Float)), nil + return values.IsNaN(val), nil } diff --git a/pkg/stdlib/types/type_name.go b/pkg/stdlib/types/type_name.go index 64585e58..99bcba2a 100644 --- a/pkg/stdlib/types/type_name.go +++ b/pkg/stdlib/types/type_name.go @@ -11,11 +11,9 @@ import ( // @param {Any} value - Input value of arbitrary type. // @return {Boolean} - Returns string representation of a type. func TypeName(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - - if err != nil { + if err := core.ValidateArgs(args, 1, 1); err != nil { return values.None, err } - return values.NewString(args[0].Type().String()), nil + return values.NewString(core.Reflect(args[0]).Name()), nil }