aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2023-02-23 01:08:16 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2023-09-11 19:58:54 +0200
commit7bdc4a32ff775bca0158533c9e9af250f16cceb7 (patch)
treeb5d04869ec8867be717d37af97c1173d2922cd56
parentChange `kvlist->assq` and `group-by` to return pairs. (diff)
downloadcalp-7bdc4a32ff775bca0158533c9e9af250f16cceb7.tar.gz
calp-7bdc4a32ff775bca0158533c9e9af250f16cceb7.tar.xz
Extend `for'-macro to allow improper list elements.
-rw-r--r--module/hnh/util.scm13
-rw-r--r--tests/test/util.scm10
2 files changed, 23 insertions, 0 deletions
diff --git a/module/hnh/util.scm b/module/hnh/util.scm
index bbb1a5ec..ea7c0dd1 100644
--- a/module/hnh/util.scm
+++ b/module/hnh/util.scm
@@ -133,6 +133,19 @@
b1 body ...)))])
<collection>)))))
+ ((for (<var> <vars> ... . <tail>) in <collection> b1 body ...)
+ #'(call/ec
+ (lambda (break)
+ (map ((@ (ice-9 match) match-lambda)
+ [(<var> <vars> ... . <tail>)
+ (call/ec
+ (lambda (raw-continue)
+ (let ((continue
+ (case-lambda
+ (() #f)
+ (args (apply raw-continue args)))))
+ b1 body ...)))])
+ <collection>))))
((for <var> in <collection> b1 body ...)
(with-syntax ((break (datum->syntax stx 'break))
(continue (datum->syntax stx 'continue)))
diff --git a/tests/test/util.scm b/tests/test/util.scm
index d2fc2d81..41dbd7a3 100644
--- a/tests/test/util.scm
+++ b/tests/test/util.scm
@@ -51,6 +51,16 @@
(for (x c) in (zip (iota 12) (string->list "Hello, World"))
x))
+ (test-equal "for with improper list elements"
+ `(3 7)
+ (for (a . b) in '((1 . 2) (3 . 4))
+ (+ a b)))
+
+ (test-equal "for with longer improper list elements"
+ '(1 2 4)
+ (for (a b . c) in '((1 -1 . 1) (2 -2 . 2) (4 -4 . 4))
+ (* c (+ 1 a b))))
+
(test-equal "for break"
'x
(for x in (iota 10)