# HG changeset patch # User Steve Losh # Date 1479845262 0 # Node ID 66fc93caa1c653f00d942bb8d9fae09b70f22214 # Parent 344ee2fa239eacd3223b83e1a58f763058c618c6 Add iterate `FOR var MODULO divisor` driver diff -r 344ee2fa239e -r 66fc93caa1c6 losh.lisp --- 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)). diff -r 344ee2fa239e -r 66fc93caa1c6 package.lisp --- 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.")