pkg/list: adding range function as a builtin
this commit adds a range function which allows to generate a sequence
of numbers from a start point adding steps till a limit is reached.
For instance:
Range(0, 5, 2)
results in
[0, 2, 4]
Change-Id: I29eddca25c4c5206c226d518d617b7b69ab8852e
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3483
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/pkg/list/math.go b/pkg/list/math.go
index 4ce4ba3..d91adb5 100644
--- a/pkg/list/math.go
+++ b/pkg/list/math.go
@@ -86,6 +86,52 @@
return d, nil
}
+// Range generates a list of numbers using a start value, a limit value, and a
+// step value.
+//
+// For instance:
+//
+// Range(0, 5, 2)
+//
+// results in
+//
+// [0, 2, 4]
+//
+func Range(start, limit, step *internal.Decimal) ([]*internal.Decimal, error) {
+ if step.IsZero() {
+ return nil, fmt.Errorf("step must be non zero")
+ }
+
+ if !step.Negative && +1 == start.Cmp(limit) {
+ return nil, fmt.Errorf("end must be greater than start when step is positive")
+ }
+
+ if step.Negative && -1 == start.Cmp(limit) {
+ return nil, fmt.Errorf("end must be less than start when step is negative")
+ }
+
+ var vals []*internal.Decimal
+ num := start
+ for {
+ if !step.Negative && -1 != num.Cmp(limit) {
+ break
+ }
+
+ if step.Negative && +1 != num.Cmp(limit) {
+ break
+ }
+
+ vals = append(vals, num)
+ d := apd.New(0, 0)
+ _, err := internal.BaseContext.Add(d, step, num)
+ if err != nil {
+ return nil, err
+ }
+ num = d
+ }
+ return vals, nil
+}
+
// Sum returns the sum of a list non empty xs.
func Sum(xs []*internal.Decimal) (*internal.Decimal, error) {
d := apd.New(0, 0)