MCPcopy Index your code
hub / github.com/expr-lang/expr / Visit

Method Visit

optimizer/sum_range.go:9–68  ·  view source on GitHub ↗
(node *Node)

Source from the content-addressed store, hash-verified

7type sumRange struct{}
8
9func (*sumRange) Visit(node *Node) {
10 // Pattern 1: sum(m..n) or sum(m..n, predicate) where m and n are constant integers
11 if sumBuiltin, ok := (*node).(*BuiltinNode); ok &&
12 sumBuiltin.Name == "sum" &&
13 (len(sumBuiltin.Arguments) == 1 || len(sumBuiltin.Arguments) == 2) {
14 if rangeOp, ok := sumBuiltin.Arguments[0].(*BinaryNode); ok && rangeOp.Operator == ".." {
15 if from, ok := rangeOp.Left.(*IntegerNode); ok {
16 if to, ok := rangeOp.Right.(*IntegerNode); ok {
17 m := from.Value
18 n := to.Value
19 if n >= m {
20 count := n - m + 1
21 // Use the arithmetic series formula: (n - m + 1) * (m + n) / 2
22 sum := count * (m + n) / 2
23
24 if len(sumBuiltin.Arguments) == 1 {
25 // sum(m..n)
26 patchWithType(node, &IntegerNode{Value: sum})
27 } else if len(sumBuiltin.Arguments) == 2 {
28 // sum(m..n, predicate)
29 if result, ok := applySumPredicate(sum, count, sumBuiltin.Arguments[1]); ok {
30 patchWithType(node, &IntegerNode{Value: result})
31 }
32 }
33 }
34 }
35 }
36 }
37 }
38
39 // Pattern 2: reduce(m..n, # + #acc) where m and n are constant integers
40 if reduceBuiltin, ok := (*node).(*BuiltinNode); ok &&
41 reduceBuiltin.Name == "reduce" &&
42 (len(reduceBuiltin.Arguments) == 2 || len(reduceBuiltin.Arguments) == 3) {
43 if rangeOp, ok := reduceBuiltin.Arguments[0].(*BinaryNode); ok && rangeOp.Operator == ".." {
44 if from, ok := rangeOp.Left.(*IntegerNode); ok {
45 if to, ok := rangeOp.Right.(*IntegerNode); ok {
46 if isPointerPlusAcc(reduceBuiltin.Arguments[1]) {
47 m := from.Value
48 n := to.Value
49 if n >= m {
50 // Use the arithmetic series formula: (n - m + 1) * (m + n) / 2
51 sum := (n - m + 1) * (m + n) / 2
52
53 // Check for optional initialValue (3rd argument)
54 if len(reduceBuiltin.Arguments) == 3 {
55 if initialValue, ok := reduceBuiltin.Arguments[2].(*IntegerNode); ok {
56 result := initialValue.Value + sum
57 patchWithType(node, &IntegerNode{Value: result})
58 }
59 } else {
60 patchWithType(node, &IntegerNode{Value: sum})
61 }
62 }
63 }
64 }
65 }
66 }

Callers

nothing calls this directly

Calls 3

patchWithTypeFunction · 0.85
applySumPredicateFunction · 0.85
isPointerPlusAccFunction · 0.85

Tested by

no test coverage detected