I've added count, minimize, and maximize to ps-loop. Examples and patch follow.<br><br>Daniel<br><br><span style="font-family: courier new,monospace;">(ps (loop for x from 1 to 10 count x into c))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">=></span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">"var c = 0;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">for (var x = 1; x <= 10; x += 1) {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ++c;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">};"</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(ps (loop for x from 1 to 10 minimize x into y maximize x into z))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">=></span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">"var y = null;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">var z = null;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">for (var x = 1; x <= 10; x += 1) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> y = y == null ? x : Math.min(y, x);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> z = z == null ? x : Math.max(z, x);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">};"</span><br><br><br>From ee44a1647b9289c50c5fe1f2bc62c569aa0c990e Mon Sep 17 00:00:00 2001<br>From: Daniel Gackle <<a href="mailto:danielgackle@gmail.com">danielgackle@gmail.com</a>><br>
Date: Tue, 30 Jun 2009 19:52:12 -0600<br>Subject: [PATCH] Added support for COUNT, MINIMIZE and MAXIMIZE to PS-LOOP.<br><br>---<br> src/lib/ps-loop.lisp | 18 ++++++++++++++----<br> 1 files changed, 14 insertions(+), 4 deletions(-)<br>
<br>diff --git a/src/lib/ps-loop.lisp b/src/lib/ps-loop.lisp<br>index 1003b5d..0e20c9c 100644<br>--- a/src/lib/ps-loop.lisp<br>+++ b/src/lib/ps-loop.lisp<br>@@ -7,7 +7,8 @@<br> <br> (defvar *loop-keywords*<br> '(:for :do :when :unless :initially :finally :first-time :last-time :while :until<br>
- :from :to :below :downto :above :by :in :across :index := :then :sum :collect :into))<br>+ :from :to :below :downto :above :by :in :across :index := :then :sum :collect<br>+ :count :minimize :maximize :into))<br>
<br> (defun normalize-loop-keywords (args)<br> (mapcar<br>@@ -60,20 +61,29 @@<br> (when (and default-accum-kind (not (eq kind default-accum-kind)))<br> (error "PS-LOOP encountered illegal ~a: ~a was already declared, and there can only be one kind of default accumulation per loop." kind default-accum-kind))<br>
(unless default-accum-var<br>- (setf default-accum-var (ps-gensym kind)<br>+ (setf default-accum-var (ps-gensym (case kind<br>+ (:minimize 'min)<br>
+ (:maximize 'max)<br>+ (t kind)))<br> default-accum-kind kind))<br> (setf var default-accum-var))<br>
- (let ((initial (case kind (:sum 0) (:collect '(array)))))<br>+ (let ((initial (case kind<br>+ ((:sum :count) 0)<br>+ ((:maximize :minimize) nil)<br>
+ (:collect '(array)))))<br> (pushnew `(var ,var ,initial) prologue :key #'second))<br> (case kind<br> (:sum `(incf ,var ,term))<br>
+ (:count `(incf ,var))<br>+ (:minimize `(setf ,var (if (null ,var) ,term (min ,var ,term))))<br>+ (:maximize `(setf ,var (if (null ,var) ,term (max ,var ,term))))<br>
(:collect `((@ ,var :push) ,term))))<br> (body-clause (term)<br> (case term<br> ((:when :unless) (list (intern (symbol-name term))<br> (consume)<br>
(body-clause (consume-atom))))<br>- ((:sum :collect) (accumulate term (consume) (consume-if :into)))<br>+ ((:sum :collect :count :minimize :maximize) (accumulate term (consume) (consume-if :into)))<br>
(:do (consume-progn))<br> (otherwise (err "a PS-LOOP keyword" term))))<br> (for-from (var)<br>-- <br>1.6.1<br><br><br>