github.com/expr-lang/expr@v1.16.9/optimizer/sum_array.go (about) 1 package optimizer 2 3 import ( 4 "fmt" 5 6 . "github.com/expr-lang/expr/ast" 7 ) 8 9 type sumArray struct{} 10 11 func (*sumArray) Visit(node *Node) { 12 if sumBuiltin, ok := (*node).(*BuiltinNode); ok && 13 sumBuiltin.Name == "sum" && 14 len(sumBuiltin.Arguments) == 1 { 15 if array, ok := sumBuiltin.Arguments[0].(*ArrayNode); ok && 16 len(array.Nodes) >= 2 { 17 Patch(node, sumArrayFold(array)) 18 } 19 } 20 } 21 22 func sumArrayFold(array *ArrayNode) *BinaryNode { 23 if len(array.Nodes) > 2 { 24 return &BinaryNode{ 25 Operator: "+", 26 Left: array.Nodes[0], 27 Right: sumArrayFold(&ArrayNode{Nodes: array.Nodes[1:]}), 28 } 29 } else if len(array.Nodes) == 2 { 30 return &BinaryNode{ 31 Operator: "+", 32 Left: array.Nodes[0], 33 Right: array.Nodes[1], 34 } 35 } 36 panic(fmt.Errorf("sumArrayFold: invalid array length %d", len(array.Nodes))) 37 }