Add iterate `FOR var MODULO divisor` driver
author |
Steve Losh <steve@stevelosh.com> |
date |
Tue, 22 Nov 2016 20:07:42 +0000 |
parents |
344ee2fa239e
|
children |
1c23d5693192
|
branches/tags |
(none) |
files |
losh.lisp package.lisp |
Changes
--- a/losh.lisp Mon Nov 21 11:10:49 2016 +0000
+++ b/losh.lisp Tue Nov 22 20:07:42 2016 +0000
@@ -707,6 +707,48 @@
;;;; Iterate ------------------------------------------------------------------
+(defmacro expand-iterate-sequence-keywords ()
+ '(list
+ :from iterate::from
+ :upfrom iterate::upfrom
+ :downfrom iterate::downfrom
+ :to iterate::to
+ :downto iterate::downto
+ :above iterate::above
+ :below iterate::below
+ :by iterate::by
+ :with-index iterate::with-index))
+
+
+(defmacro-driver (FOR var MODULO divisor &sequence)
+ "Iterate numerically modulo `divisor`.
+
+ This driver iterates just like the vanilla `for`, but each resulting value
+ will be modulo'ed by `divisor` before being bound to `var`.
+
+ Note that the modulo doesn't affect the *iteration*, it just affects the
+ variable you *see*. It is as if you had written two clauses:
+
+ (for temp :from foo :to bar)
+ (for var = (mod temp divisor))
+
+ Example:
+
+ (iterate (for i :from 0 :to 20 :by 3) (collect i))
+ (0 3 6 9 12 15 18)
+
+ (iterate (for i :modulo 10 :from 0 :to 20 :by 3) (collect i))
+ (0 3 6 9 2 5 8)
+
+ "
+ (let ((kwd (if generate 'generate 'for)))
+ (with-gensyms (i d)
+ `(progn
+ (with ,d = ,divisor)
+ (generate ,i ,@(expand-iterate-sequence-keywords))
+ (,kwd ,var next (mod (next ,i) ,d))))))
+
+
(defmacro-driver (FOR var PAIRS-OF-LIST list)
"Iterate over the all pairs of the (including (last . first)).
--- a/package.lisp Mon Nov 21 11:10:49 2016 +0000
+++ b/package.lisp Tue Nov 22 20:07:42 2016 +0000
@@ -122,25 +122,27 @@
(:use :iterate) ; need this for iterate's `for` symbol fuckery
(:documentation "Custom `iterate` drivers and clauses.")
(:export
- :pairs-of-list
+ :across-flat-array
:averaging
+ :cycling
+ :for-nested
+ :in-array
+ :in-lists
+ :in-sequences
+ :in-whatever
+ :index-of-flat-array
:into
- :timing
- :since-start-into
+ :macroexpand-iterate
+ :modulo
+ :pairs-of-list
:per-iteration-into
:real-time
:run-time
- :in-lists
- :in-sequences
- :in-whatever
- :in-array
- :across-flat-array
- :index-of-flat-array
- :cycling
- :for-nested
+ :since-start-into
+ :skip-origin
+ :timing
:within-radius
- :skip-origin
- :macroexpand-iterate))
+ ))
(defpackage :losh.hash-tables
(:documentation "Utilities for operating on hash tables.")