# HG changeset patch # User Steve Losh # Date 1544234339 18000 # Node ID 73c14a96cb0eec2166702885efd6578c91151c88 # Parent f2f853a0d29e98b8a3426ab33effc00f435e476d Add DO-IRANGE diff -r f2f853a0d29e -r 73c14a96cb0e package.lisp --- 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 diff -r f2f853a0d29e -r 73c14a96cb0e src/control-flow.lisp --- 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))))))) + +