73c14a96cb0e

Add DO-IRANGE
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Fri, 07 Dec 2018 20:58:59 -0500
parents f2f853a0d29e
children 6b2d21a74a45
branches/tags (none)
files package.lisp src/control-flow.lisp

Changes

--- a/package.lisp	Fri Nov 23 10:55:35 2018 -0500
+++ b/package.lisp	Fri Dec 07 20:58:59 2018 -0500
@@ -188,7 +188,8 @@
     :when-let*
     :multiple-value-bind*
     :do-repeat
-    :do-range))
+    :do-range
+    :do-irange))
 
 
 (defpackage :losh.math
--- a/src/control-flow.lisp	Fri Nov 23 10:55:35 2018 -0500
+++ b/src/control-flow.lisp	Fri Dec 07 20:58:59 2018 -0500
@@ -453,4 +453,37 @@
            :for ,var :from ,from :below ,below
            :do ,(recur (rest ranges)))))))
 
+(defmacro do-irange (ranges &body body)
+  "Perform `body` on the given inclusive `ranges`.
 
+  Each range in `ranges` should be of the form `(variable from to)`.  During
+  iteration `body` will be executed with `variable` bound to successive values
+  in the range [`from`, `to`].
+
+  If multiple ranges are given they will be iterated in a nested fashion.
+
+  Example:
+
+    (do-irange ((x  0  2)
+                (y 10 11))
+      (pr x y))
+    ; =>
+    ; 0 10
+    ; 0 11
+    ; 1 10
+    ; 1 11
+    ; 2 10
+    ; 2 11
+
+  "
+  (assert (not (null ranges)) ()
+    "Ranges to iterate in DO-RANGE must not be null.")
+  (recursively ((ranges ranges))
+    (if (null ranges)
+      `(progn ,@body)
+      (destructuring-bind (var from to) (first ranges)
+        `(loop
+           :for ,var :from ,from :to ,to
+           :do ,(recur (rest ranges)))))))
+
+