# HG changeset patch # User Steve Losh # Date 1621832713 14400 # Node ID 91ea751ccd9f1b6ace12946efb7a434b22b3adbb # Parent acf6a1d4de2e9a202373d37df55a8d5ce05ad7e9 Add do-vector diff -r acf6a1d4de2e -r 91ea751ccd9f src/control-flow.lisp --- a/src/control-flow.lisp Sun May 23 16:53:10 2021 -0400 +++ b/src/control-flow.lisp Mon May 24 01:05:13 2021 -0400 @@ -431,6 +431,38 @@ `(dotimes (,(gensym) ,n) ,@body)) +(defmacro do-vector ((var-or-vars vector) &body body) + "Iterate over `vector`, performing `body` with `var-or-vars` bound. + + `var-or-vars` can be one of the following: + + * `value-symbol` + * `(value-symbol)` + * `(index-symbol value-symbol)` + + Successive elements of `vector` will be bound to `value-symbol` while `body` + is executed. If `index-symbol` is given, the current index will be bound to + it. + + Returns `nil`. + + " + (setf var-or-vars (alexandria:ensure-list var-or-vars)) + (alexandria:once-only (vector) + (let ((i nil) + (v nil) + (len (gensym "LEN"))) + (ecase (length var-or-vars) + (1 (setf i (gensym "I") + v (first var-or-vars))) + (2 (setf i (first var-or-vars) + v (second var-or-vars)))) + `(do ((,len (length ,vector)) + (,i 0 (1+ ,i))) + ((>= ,i ,len)) + (let ((,v (aref ,vector ,i))) + ,@body))))) + (defmacro do-range (ranges &body body) "Perform `body` on the given `ranges`. diff -r acf6a1d4de2e -r 91ea751ccd9f src/package.lisp --- a/src/package.lisp Sun May 23 16:53:10 2021 -0400 +++ b/src/package.lisp Mon May 24 01:05:13 2021 -0400 @@ -242,7 +242,8 @@ :do-repeat :do-range :do-irange - :do-file)) + :do-file + :do-vector)) (defpackage :losh.math