From 70aa70d044e358d8f96ab85f7d6a0e282bca2dea Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Mon, 26 Jun 2017 21:32:08 -0400 Subject: [PATCH] Filters can have (single) parameters --- chunks/render_test.go | 6 +- expressions/expressions.y | 16 ++-- expressions/filters.go | 38 +++++++-- expressions/generics.go | 5 +- expressions/scanner.go | 168 ++++++++++++++++++++------------------ expressions/scanner.rl | 1 + expressions/y.go | 90 ++++++++++---------- 7 files changed, 188 insertions(+), 136 deletions(-) diff --git a/chunks/render_test.go b/chunks/render_test.go index c563d36..05c801b 100644 --- a/chunks/render_test.go +++ b/chunks/render_test.go @@ -49,9 +49,9 @@ var filterTests = []struct{ in, expected string }{ // list filters // {{ site.pages | map: 'category' | compact | join "," %} // {% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}{{ my_array.first }} - // {`{{"John, Paul, George, Ringo" | split: ", " | join: "and"}}`, "John and Paul and George and Ringo"}, - {`{{ animals | sort | join }}`, "Sally Snake, giraffe, octopus, zebra"}, - // {`{{ animals | sort | join: "," }}`, "Sally Snake, giraffe, octopus, zebra"}, + // {`{{"John, Paul, George, Ringo" | split: ", " }}`, "John and Paul and George and Ringo"}, + {`{{"John, Paul, George, Ringo" | split: ", " | join: " and "}}`, "John and Paul and George and Ringo"}, + {`{{ animals | sort | join: ", " }}`, "Sally Snake, giraffe, octopus, zebra"}, // join, last, map, slice, sort, sort_natural, reverse, size, uniq // string filters diff --git a/expressions/expressions.y b/expressions/expressions.y index 0e9260d..0486841 100644 --- a/expressions/expressions.y +++ b/expressions/expressions.y @@ -15,17 +15,17 @@ func init() { val interface{} f func(Context) interface{} } -%type expr rel +%type expr rel expr1 %token LITERAL -%token IDENTIFIER RELATION +%token IDENTIFIER KEYWORD RELATION %token ASSIGN %token EQ -%left '.' +%left '.' '|' %left '<' '>' %% start: rel ';' { yylex.(*lexer).val = $1 } -| ASSIGN IDENTIFIER '=' expr ';' { +| ASSIGN IDENTIFIER '=' expr1 ';' { name, expr := $2, $4 yylex.(*lexer).val = func(ctx Context) interface{} { ctx.Set(name, expr(ctx)) @@ -51,7 +51,6 @@ expr: return nil } } -| expr '|' IDENTIFIER { $$ = makeFilter($1, $3) } | expr '[' expr ']' { e, i := $1, $3 $$ = func(ctx Context) interface{} { @@ -70,10 +69,15 @@ expr: return nil } } + +expr1: + expr +| expr1 '|' IDENTIFIER { $$ = makeFilter($1, $3, nil) } +| expr1 '|' KEYWORD expr { $$ = makeFilter($1, $3, $4) } ; rel: - expr + expr1 | expr EQ expr { a, b := $1, $3 $$ = func(ctx Context) interface{} { diff --git a/expressions/filters.go b/expressions/filters.go index fd3a33c..a929e65 100644 --- a/expressions/filters.go +++ b/expressions/filters.go @@ -9,12 +9,16 @@ import ( type valueFn func(Context) interface{} -func joinFilter(in []interface{}) interface{} { +func joinFilter(in []interface{}, sep interface{}) interface{} { a := make([]string, len(in)) + s := ", " + if sep != nil { + s = fmt.Sprint(sep) + } for i, x := range in { a[i] = fmt.Sprint(x) } - return strings.Join(a, ", ") + return strings.Join(a, s) } func sortFilter(in []interface{}) []interface{} { @@ -26,12 +30,31 @@ func sortFilter(in []interface{}) []interface{} { return a } -var filters = map[string]interface{}{ - "join": joinFilter, - "sort": sortFilter, +func splitFilter(in, sep string) interface{} { + return strings.Split(in, sep) } -func makeFilter(f valueFn, name string) valueFn { +var filters = map[string]interface{}{} + +func init() { + DefineStandardFilters() +} + +func DefineStandardFilters() { + DefineFilter("join", joinFilter) + DefineFilter("sort", sortFilter) + DefineFilter("split", splitFilter) +} + +func DefineFilter(name string, fn interface{}) { + rf := reflect.ValueOf(fn) + if rf.Kind() != reflect.Func || rf.Type().NumIn() < 0 || rf.Type().NumOut() != 1 { + panic(fmt.Errorf("a filter must be a function with at least one input and exactly one output")) + } + filters[name] = fn +} + +func makeFilter(f valueFn, name string, param valueFn) valueFn { fn, ok := filters[name] if !ok { panic(fmt.Errorf("unknown filter: %s", name)) @@ -39,6 +62,9 @@ func makeFilter(f valueFn, name string) valueFn { fr := reflect.ValueOf(fn) return func(ctx Context) interface{} { args := []interface{}{f(ctx)} + if param != nil { + args = append(args, param(ctx)) + } in := convertArguments(fr, args) r := fr.Call(in)[0] return r.Interface() diff --git a/expressions/generics.go b/expressions/generics.go index 0801784..765dc2e 100644 --- a/expressions/generics.go +++ b/expressions/generics.go @@ -30,6 +30,9 @@ func convertType(val interface{}, t reflect.Type) reflect.Value { if r.Type().ConvertibleTo(t) { return r.Convert(t) } + if reflect.PtrTo(r.Type()) == t { + return reflect.ValueOf(&val) + } switch t.Kind() { case reflect.Slice: if r.Kind() != reflect.Array && r.Kind() != reflect.Slice { @@ -42,7 +45,7 @@ func convertType(val interface{}, t reflect.Type) reflect.Value { } return x } - panic(fmt.Errorf("convertType: can't convert %v to %v", val, t)) + panic(fmt.Errorf("convertType: can't convert %#v<%s> to %v", val, r.Type(), t)) } // Convert args to match the input types of fr, which should be a function reflection. diff --git a/expressions/scanner.go b/expressions/scanner.go index ebf9ad8..9266adf 100644 --- a/expressions/scanner.go +++ b/expressions/scanner.go @@ -12,17 +12,18 @@ var _expression_actions []byte = []byte{ 0, 1, 0, 1, 1, 1, 2, 1, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1, 16, 1, 17, - 1, 18, 1, 19, 1, 20, 2, 2, - 3, 2, 2, 4, 2, 2, 5, 2, - 2, 6, 2, 2, 7, 2, 2, 8, + 1, 18, 1, 19, 1, 20, 1, 21, + 2, 2, 3, 2, 2, 4, 2, 2, + 5, 2, 2, 6, 2, 2, 7, 2, + 2, 8, } var _expression_key_offsets []byte = []byte{ 0, 1, 2, 3, 4, 5, 6, 7, 9, 36, 39, 40, 41, 42, 43, 46, - 48, 51, 52, 59, 67, 75, 83, 91, - 99, 107, 115, 123, 131, 139, 147, 155, - 163, 171, 179, + 48, 51, 52, 60, 69, 78, 87, 96, + 105, 114, 123, 132, 141, 150, 159, 168, + 177, 186, 195, } var _expression_trans_keys []byte = []byte{ @@ -32,32 +33,34 @@ var _expression_trans_keys []byte = []byte{ 111, 116, 9, 13, 48, 57, 60, 62, 65, 90, 98, 122, 32, 9, 13, 61, 34, 97, 39, 46, 48, 57, 48, 57, - 46, 48, 57, 61, 95, 48, 57, 65, - 90, 97, 122, 95, 110, 48, 57, 65, - 90, 97, 122, 95, 100, 48, 57, 65, - 90, 97, 122, 95, 111, 48, 57, 65, - 90, 97, 122, 95, 110, 48, 57, 65, - 90, 97, 122, 95, 116, 48, 57, 65, - 90, 97, 122, 95, 97, 48, 57, 65, - 90, 98, 122, 95, 105, 48, 57, 65, - 90, 97, 122, 95, 110, 48, 57, 65, - 90, 97, 122, 95, 115, 48, 57, 65, - 90, 97, 122, 95, 97, 48, 57, 65, - 90, 98, 122, 95, 108, 48, 57, 65, - 90, 97, 122, 95, 115, 48, 57, 65, - 90, 97, 122, 95, 101, 48, 57, 65, - 90, 97, 122, 95, 114, 48, 57, 65, - 90, 97, 122, 95, 114, 48, 57, 65, - 90, 97, 122, 95, 117, 48, 57, 65, - 90, 97, 122, + 46, 48, 57, 61, 58, 95, 48, 57, + 65, 90, 97, 122, 58, 95, 110, 48, + 57, 65, 90, 97, 122, 58, 95, 100, + 48, 57, 65, 90, 97, 122, 58, 95, + 111, 48, 57, 65, 90, 97, 122, 58, + 95, 110, 48, 57, 65, 90, 97, 122, + 58, 95, 116, 48, 57, 65, 90, 97, + 122, 58, 95, 97, 48, 57, 65, 90, + 98, 122, 58, 95, 105, 48, 57, 65, + 90, 97, 122, 58, 95, 110, 48, 57, + 65, 90, 97, 122, 58, 95, 115, 48, + 57, 65, 90, 97, 122, 58, 95, 97, + 48, 57, 65, 90, 98, 122, 58, 95, + 108, 48, 57, 65, 90, 97, 122, 58, + 95, 115, 48, 57, 65, 90, 97, 122, + 58, 95, 101, 48, 57, 65, 90, 97, + 122, 58, 95, 114, 48, 57, 65, 90, + 97, 122, 58, 95, 114, 48, 57, 65, + 90, 97, 122, 58, 95, 117, 48, 57, + 65, 90, 97, 122, } var _expression_single_lengths []byte = []byte{ 1, 1, 1, 1, 1, 1, 1, 0, 17, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, + 1, 1, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, } var _expression_range_lengths []byte = []byte{ @@ -71,9 +74,9 @@ var _expression_range_lengths []byte = []byte{ var _expression_index_offsets []byte = []byte{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 39, 42, 44, 46, 48, 50, 53, - 55, 58, 60, 65, 71, 77, 83, 89, - 95, 101, 107, 113, 119, 125, 131, 137, - 143, 149, 155, + 55, 58, 60, 66, 73, 80, 87, 94, + 101, 108, 115, 122, 129, 136, 143, 150, + 157, 164, 171, } var _expression_indicies []byte = []byte{ @@ -84,20 +87,22 @@ var _expression_indicies []byte = []byte{ 27, 11, 18, 20, 22, 22, 10, 11, 11, 28, 30, 29, 2, 1, 32, 31, 2, 8, 33, 18, 31, 9, 29, 9, - 18, 34, 35, 31, 22, 22, 22, 22, - 29, 22, 37, 22, 22, 22, 36, 22, - 38, 22, 22, 22, 36, 22, 39, 22, - 22, 22, 36, 22, 40, 22, 22, 22, - 36, 22, 41, 22, 22, 22, 36, 22, - 42, 22, 22, 22, 36, 22, 43, 22, - 22, 22, 36, 22, 44, 22, 22, 22, - 36, 22, 38, 22, 22, 22, 36, 22, - 45, 22, 22, 22, 36, 22, 46, 22, - 22, 22, 36, 22, 47, 22, 22, 22, - 36, 22, 48, 22, 22, 22, 36, 22, - 38, 22, 22, 22, 36, 22, 49, 22, - 22, 22, 36, 22, 47, 22, 22, 22, - 36, + 18, 34, 35, 31, 36, 22, 22, 22, + 22, 29, 36, 22, 38, 22, 22, 22, + 37, 36, 22, 39, 22, 22, 22, 37, + 36, 22, 40, 22, 22, 22, 37, 36, + 22, 41, 22, 22, 22, 37, 36, 22, + 42, 22, 22, 22, 37, 36, 22, 43, + 22, 22, 22, 37, 36, 22, 44, 22, + 22, 22, 37, 36, 22, 45, 22, 22, + 22, 37, 36, 22, 39, 22, 22, 22, + 37, 36, 22, 46, 22, 22, 22, 37, + 36, 22, 47, 22, 22, 22, 37, 36, + 22, 48, 22, 22, 22, 37, 36, 22, + 49, 22, 22, 22, 37, 36, 22, 39, + 22, 22, 22, 37, 36, 22, 50, 22, + 22, 22, 37, 36, 22, 48, 22, 22, + 22, 37, } var _expression_trans_targs []byte = []byte{ @@ -105,19 +110,19 @@ var _expression_trans_targs []byte = []byte{ 6, 15, 8, 9, 10, 11, 12, 13, 14, 15, 16, 8, 10, 17, 18, 19, 21, 28, 32, 33, 8, 8, 8, 8, - 1, 7, 8, 8, 8, 20, 18, 22, - 23, 24, 25, 26, 27, 29, 30, 31, - 18, 34, + 1, 7, 8, 8, 8, 8, 20, 18, + 22, 23, 24, 25, 26, 27, 29, 30, + 31, 18, 34, } var _expression_trans_actions []byte = []byte{ - 27, 0, 9, 0, 0, 0, 0, 7, - 0, 31, 17, 0, 46, 5, 5, 5, - 5, 37, 0, 11, 37, 0, 43, 0, - 0, 0, 0, 0, 23, 29, 15, 25, - 0, 0, 19, 13, 21, 0, 40, 0, + 29, 0, 9, 0, 0, 0, 0, 7, + 0, 33, 19, 0, 48, 5, 5, 5, + 5, 39, 0, 11, 39, 0, 45, 0, + 0, 0, 0, 0, 25, 31, 15, 27, + 0, 0, 21, 13, 17, 23, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 0, + 0, 36, 0, } var _expression_to_state_actions []byte = []byte{ @@ -139,9 +144,9 @@ var _expression_from_state_actions []byte = []byte{ var _expression_eof_trans []byte = []byte{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 29, 30, 32, 32, 32, 32, 30, - 35, 32, 30, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, + 35, 32, 30, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, } const expression_start int = 8 @@ -171,7 +176,7 @@ func newLexer(data []byte) *lexer { pe: len(data), } -//line scanner.go:175 +//line scanner.go:180 { lex.cs = expression_start lex.ts = 0 @@ -188,7 +193,7 @@ func (lex *lexer) Lex(out *yySymType) int { tok := 0 -//line scanner.go:192 +//line scanner.go:197 { var _klen int var _trans int @@ -208,7 +213,7 @@ _resume: //line NONE:1 lex.ts = ( lex.p) -//line scanner.go:212 +//line scanner.go:217 } } @@ -296,10 +301,10 @@ _eof_trans: lex.act = 9; case 7: //line scanner.rl:45 - lex.act = 10; + lex.act = 11; case 8: -//line scanner.rl:93 - lex.act = 12; +//line scanner.rl:94 + lex.act = 13; case 9: //line scanner.rl:82 lex.te = ( lex.p)+1 @@ -331,11 +336,16 @@ _eof_trans: { tok = RELATION; out.name = lex.token(); ( lex.p)++; goto _out } case 14: -//line scanner.rl:93 +//line scanner.rl:91 + lex.te = ( lex.p)+1 +{ tok = KEYWORD; out.name = string(lex.data[lex.ts:lex.te-1]); ( lex.p)++; goto _out + } + case 15: +//line scanner.rl:94 lex.te = ( lex.p)+1 { tok = int(lex.data[lex.ts]); ( lex.p)++; goto _out } - case 15: + case 16: //line scanner.rl:50 lex.te = ( lex.p) ( lex.p)-- @@ -349,7 +359,7 @@ _eof_trans: ( lex.p)++; goto _out } - case 16: + case 17: //line scanner.rl:45 lex.te = ( lex.p) ( lex.p)-- @@ -359,23 +369,23 @@ _eof_trans: ( lex.p)++; goto _out } - case 17: -//line scanner.rl:92 - lex.te = ( lex.p) -( lex.p)-- - case 18: //line scanner.rl:93 lex.te = ( lex.p) ( lex.p)-- -{ tok = int(lex.data[lex.ts]); ( lex.p)++; goto _out - } + case 19: -//line scanner.rl:93 -( lex.p) = ( lex.te) - 1 +//line scanner.rl:94 + lex.te = ( lex.p) +( lex.p)-- { tok = int(lex.data[lex.ts]); ( lex.p)++; goto _out } case 20: +//line scanner.rl:94 +( lex.p) = ( lex.te) - 1 +{ tok = int(lex.data[lex.ts]); ( lex.p)++; goto _out + } + case 21: //line NONE:1 switch lex.act { case 3: @@ -406,7 +416,7 @@ _eof_trans: {( lex.p) = ( lex.te) - 1 tok = RELATION; out.name = lex.token(); ( lex.p)++; goto _out } - case 10: + case 11: {( lex.p) = ( lex.te) - 1 tok = IDENTIFIER @@ -414,13 +424,13 @@ _eof_trans: ( lex.p)++; goto _out } - case 12: + case 13: {( lex.p) = ( lex.te) - 1 tok = int(lex.data[lex.ts]); ( lex.p)++; goto _out } } -//line scanner.go:424 +//line scanner.go:434 } } @@ -434,7 +444,7 @@ _again: //line NONE:1 lex.ts = 0 -//line scanner.go:438 +//line scanner.go:448 } } @@ -453,7 +463,7 @@ _again: _out: {} } -//line scanner.rl:97 +//line scanner.rl:98 return tok diff --git a/expressions/scanner.rl b/expressions/scanner.rl index 3031712..fd00235 100644 --- a/expressions/scanner.rl +++ b/expressions/scanner.rl @@ -88,6 +88,7 @@ func (lex *lexer) Lex(out *yySymType) int { "==" => { tok = EQ; fbreak; }; ("!=" | ">" | ">" | ">=" | "<=") => Relation; ("and" | "or" | "contains") => Relation; + ident ':' => { tok = KEYWORD; out.name = string(lex.data[lex.ts:lex.te-1]); fbreak; }; ident => Ident; space+; any => { tok = int(lex.data[lex.ts]); fbreak; }; diff --git a/expressions/y.go b/expressions/y.go index 5b37041..eed96e2 100644 --- a/expressions/y.go +++ b/expressions/y.go @@ -23,9 +23,10 @@ type yySymType struct { const LITERAL = 57346 const IDENTIFIER = 57347 -const RELATION = 57348 -const ASSIGN = 57349 -const EQ = 57350 +const KEYWORD = 57348 +const RELATION = 57349 +const ASSIGN = 57350 +const EQ = 57351 var yyToknames = [...]string{ "$end", @@ -33,15 +34,16 @@ var yyToknames = [...]string{ "$unk", "LITERAL", "IDENTIFIER", + "KEYWORD", "RELATION", "ASSIGN", "EQ", "'.'", + "'|'", "'<'", "'>'", "';'", "'='", - "'|'", "'['", "']'", } @@ -64,42 +66,42 @@ const yyLast = 35 var yyAct = [...]int{ - 12, 9, 13, 14, 4, 9, 10, 11, 9, 7, - 10, 11, 23, 10, 11, 15, 18, 19, 20, 21, - 22, 9, 5, 6, 24, 3, 10, 11, 5, 6, - 17, 16, 8, 1, 2, + 5, 13, 11, 11, 14, 15, 11, 4, 12, 12, + 27, 8, 12, 20, 21, 22, 23, 25, 10, 26, + 16, 28, 10, 19, 24, 6, 7, 17, 18, 3, + 6, 7, 9, 1, 2, } var yyPact = [...]int{ - 18, -1000, -3, 27, -8, -1000, -1000, -1000, 2, 26, - 25, 24, 24, 24, 24, 24, -1000, -1000, -4, -1, - -1, -1, 12, -1000, -1000, + 21, -1000, -3, 27, 11, -8, -1000, -1000, -1000, 5, + 22, 18, 26, 26, 26, 26, 26, -1000, 26, -1000, + -7, -4, -4, -4, 7, -4, -4, -1000, -1000, } var yyPgo = [...]int{ - 0, 4, 34, 33, + 0, 0, 34, 7, 33, } var yyR1 = [...]int{ - 0, 3, 3, 1, 1, 1, 1, 1, 2, 2, - 2, 2, + 0, 4, 4, 1, 1, 1, 1, 3, 3, 3, + 2, 2, 2, 2, } var yyR2 = [...]int{ - 0, 2, 5, 1, 1, 3, 3, 4, 1, 3, - 3, 3, + 0, 2, 5, 1, 1, 3, 4, 1, 3, 4, + 1, 3, 3, 3, } var yyChk = [...]int{ - -1000, -3, -2, 7, -1, 4, 5, 12, 5, 9, - 14, 15, 8, 10, 11, 13, 5, 5, -1, -1, - -1, -1, -1, 16, 12, + -1000, -4, -2, 8, -3, -1, 4, 5, 14, 5, + 11, 10, 16, 9, 12, 13, 15, 5, 6, 5, + -1, -1, -1, -1, -3, -1, -1, 17, 14, } var yyDef = [...]int{ - 0, -2, 0, 0, 8, 3, 4, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 6, 0, 9, - 10, 11, 0, 7, 2, + 0, -2, 0, 0, 10, 7, 3, 4, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 5, + 0, 11, 12, 13, 0, 7, 9, 6, 2, } var yyTok1 = [...]int{ @@ -107,19 +109,19 @@ var yyTok1 = [...]int{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 9, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 12, - 10, 13, 11, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 10, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, + 12, 15, 13, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 15, 3, 16, 3, 3, 3, 3, 3, 3, + 3, 16, 3, 17, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 14, + 3, 3, 3, 3, 11, } var yyTok2 = [...]int{ - 2, 3, 4, 5, 6, 7, 8, + 2, 3, 4, 5, 6, 7, 8, 9, } var yyTok3 = [...]int{ 0, @@ -511,14 +513,8 @@ yydefault: } } case 6: - yyDollar = yyS[yypt-3 : yypt+1] - //line expressions.y:54 - { - yyVAL.f = makeFilter(yyDollar[1].f, yyDollar[3].name) - } - case 7: yyDollar = yyS[yypt-4 : yypt+1] - //line expressions.y:55 + //line expressions.y:54 { e, i := yyDollar[1].f, yyDollar[3].f yyVAL.f = func(ctx Context) interface{} { @@ -537,9 +533,21 @@ yydefault: return nil } } - case 9: + case 8: yyDollar = yyS[yypt-3 : yypt+1] - //line expressions.y:77 + //line expressions.y:75 + { + yyVAL.f = makeFilter(yyDollar[1].f, yyDollar[3].name, nil) + } + case 9: + yyDollar = yyS[yypt-4 : yypt+1] + //line expressions.y:76 + { + yyVAL.f = makeFilter(yyDollar[1].f, yyDollar[3].name, yyDollar[4].f) + } + case 11: + yyDollar = yyS[yypt-3 : yypt+1] + //line expressions.y:81 { a, b := yyDollar[1].f, yyDollar[3].f yyVAL.f = func(ctx Context) interface{} { @@ -547,9 +555,9 @@ yydefault: return GenericCompare(aref, bref) == 0 } } - case 10: + case 12: yyDollar = yyS[yypt-3 : yypt+1] - //line expressions.y:84 + //line expressions.y:88 { a, b := yyDollar[1].f, yyDollar[3].f yyVAL.f = func(ctx Context) interface{} { @@ -557,9 +565,9 @@ yydefault: return GenericCompare(aref, bref) < 0 } } - case 11: + case 13: yyDollar = yyS[yypt-3 : yypt+1] - //line expressions.y:91 + //line expressions.y:95 { a, b := yyDollar[1].f, yyDollar[3].f yyVAL.f = func(ctx Context) interface{} {