@@ -30,6 +30,7 @@ var predicates = map[string]struct {
3030 "findLastIndex" : {2 },
3131 "groupBy" : {2 },
3232 "countBy" : {2 },
33+ "reduce" : {3 },
3334}
3435
3536type parser struct {
@@ -357,6 +358,9 @@ func (p *parser) parseCall(token Token) Node {
357358
358359 if b , ok := predicates [token .Value ]; ok {
359360 p .expect (Bracket , "(" )
361+
362+ // TODO: Refactor parser to use builtin.Builtins instead of predicates map.
363+
360364 if b .arity == 1 {
361365 arguments = make ([]Node , 1 )
362366 arguments [0 ] = p .parseExpression (0 )
@@ -366,6 +370,18 @@ func (p *parser) parseCall(token Token) Node {
366370 p .expect (Operator , "," )
367371 arguments [1 ] = p .parseClosure ()
368372 }
373+
374+ if token .Value == "reduce" {
375+ arguments = make ([]Node , 2 )
376+ arguments [0 ] = p .parseExpression (0 )
377+ p .expect (Operator , "," )
378+ arguments [1 ] = p .parseClosure ()
379+ if p .current .Is (Operator , "," ) {
380+ p .next ()
381+ arguments = append (arguments , p .parseExpression (0 ))
382+ }
383+ }
384+
369385 p .expect (Bracket , ")" )
370386
371387 node = & BuiltinNode {
@@ -596,9 +612,21 @@ func (p *parser) parsePipe(node Node) Node {
596612
597613 if b , ok := predicates [identifier .Value ]; ok {
598614 p .expect (Bracket , "(" )
615+
616+ // TODO: Refactor parser to use builtin.Builtins instead of predicates map.
617+
599618 if b .arity == 2 {
600619 arguments = append (arguments , p .parseClosure ())
601620 }
621+
622+ if identifier .Value == "reduce" {
623+ arguments = append (arguments , p .parseClosure ())
624+ if p .current .Is (Operator , "," ) {
625+ p .next ()
626+ arguments = append (arguments , p .parseExpression (0 ))
627+ }
628+ }
629+
602630 p .expect (Bracket , ")" )
603631
604632 node = & BuiltinNode {
0 commit comments