(node *Node)
| 7 | type sumRange struct{} |
| 8 | |
| 9 | func (*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 | } |
nothing calls this directly
no test coverage detected