Skip to content

Instantly share code, notes, and snippets.

@toomasv
Last active May 24, 2020 07:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toomasv/e72996ed5b97bed9c59a9c4858864fb0 to your computer and use it in GitHub Desktop.
Save toomasv/e72996ed5b97bed9c59a9c4858864fb0 to your computer and use it in GitHub Desktop.
Range and step ops
Red [
Description: "Some range and step ops"
Date: 21-May-2020
]
;Simple range op!
;works when a < b and with integer! and date! only
..: make op! func [a [integer! date!] b [integer! date!] /local i out][
out: copy [] repeat i b - a + 1 [append out i - 1 + a]
]
;Simple step op!, proxy for `extract`
;works with integer! only
|: make op! func [a [block!] b [integer!]][extract a b]
;Advanced range op!
;works with all scalar! types in both directions
...: make op! func [a [scalar!] b [scalar!] /local i step][
if a = b [return a]
if (type? a) <> (type? b) [cause-error 'user 'message ["Types mismatch in range!"]]
step: pick [1% 1] percent? a
if a > b [step: 0 - step]
comp: get pick [< >] a > b
collect [
until [
keep a
a: a + step
a comp b
]
]
]
;Advanced step op!
;works with any step appropriate for range types; negative step ensures end matching
||: make op! function [range [block!] step [scalar!]][
if zero? step [cause-error 'user 'message ["Range doesn't advance!"]]
if range/1 = range/2 [return range/1]
if (type? range/1) <> (type? range/2) [cause-error 'user 'message ["Types mismatch in range!"]]
range: copy range
if neg?: attempt [negative? step][reverse range]
op: get pick [+ -] to logic! any [
all [range/1 < range/2 positive? step]
all [range/2 < range/1 negative? step]
]
comp: get pick [< >] range/1 > range/2
out: collect [
until [
keep range/1
range/1: range/1 op step
range/1 comp range/2
]
]
either neg? [reverse out][out]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment