Carp/core/ArrayExt.carp
2020-05-24 12:51:11 +02:00

32 lines
1.3 KiB
Plaintext

; we extend the array module, now that we have strings
(defmodule Array
(doc range "creates an array from `start` to `end` with `step` between them
(the elements must support `<`, `<=`, `>=`, and `to-int`).
It returns a `Result.Success` if the input was right, and a `Result.Error` if
the input given was wrong, containing an error message.")
(defn range [start end step]
(cond
(= step (zero))
(Result.Error @"`Array.range` cannot be called with step size `0`.")
(and (< start end) (< step (zero)))
(Result.Error @"`Array.range` cannot be called with a step size `< 0` and `start < end`.")
(and (> start end) (> step (zero)))
(Result.Error @"`Array.range` cannot be called with a step size `> 0` and `start > end`.")
(let-do [x (allocate (Int.inc (Int.abs (to-int (/ (- end start) step)))))
e start
i 0
op (if (< start end) <= >=)]
(while (op e end)
(do
(aset! &x i e)
(set! i (Int.inc i))
(set! e (+ e step))))
(Result.Success x))))
(doc range-or-default "is a version of [`range`](#range) that returns an empty
array on failure.")
(defn range-or-default [start end step]
(Result.from-success (range start end step) []))
)