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  }