~ chicken-core (chicken-5) e2960480729bc1cec339024818495114487b4a4d
commit e2960480729bc1cec339024818495114487b4a4d
Author: Evan Hanson <evhan@foldling.org>
AuthorDate: Sat Jul 5 13:54:29 2014 +1200
Commit: Peter Bex <peter.bex@xs4all.nl>
CommitDate: Sat Jul 12 17:20:28 2014 +0200
Add full lambda list support for letrec-values bindings
Use the logic for multi-value assignment expansion already shared by
set!-values and ##sys#canonicalize-body for letrec-values, too.
Signed-off-by: Peter Bex <peter.bex@xs4all.nl>
diff --git a/NEWS b/NEWS
index dfaec6d6..6efec544 100644
--- a/NEWS
+++ b/NEWS
@@ -30,7 +30,8 @@
##sys#check-port-mode, ##sys#check-port*
- Syntax expander
- - define-values and set!-values now support full lambda lists
+ - define-values, set!-values and letrec-values now support full lambda
+ lists as binding forms
- C API
- Removed deprecated C_get_argument[_2] and
diff --git a/chicken-syntax.scm b/chicken-syntax.scm
index baf6a351..c815bc80 100644
--- a/chicken-syntax.scm
+++ b/chicken-syntax.scm
@@ -416,21 +416,20 @@
'letrec-values '()
(##sys#er-transformer
(lambda (form r c)
- (##sys#check-syntax 'letrec-values form '(_ list . _))
+ (##sys#check-syntax 'letrec-values form '(_ #((lambda-list . _) 0) . _))
(let ((vbindings (cadr form))
- (body (cddr form)))
- (let* ([vars (apply ##sys#append (map (lambda (x) (car x)) vbindings))]
- [aliases (map (lambda (v) (cons v (r (gensym v)))) vars)]
- [lookup (lambda (v) (cdr (assq v aliases)))] )
- `(##core#let
- ,(map (lambda (v) (##sys#list v '(##core#undefined))) vars)
- ,@(map (lambda (vb)
- `(##sys#call-with-values
- (##core#lambda () ,(cadr vb))
- (##core#lambda ,(map lookup (car vb))
- ,@(map (lambda (v) `(##core#set! ,v ,(lookup v))) (car vb)) ) ) )
- vbindings)
- ,@body) ) ) ) ) )
+ (body (cddr form)))
+ (let ((vars (map car vbindings))
+ (exprs (map cadr vbindings)))
+ `(##core#let
+ ,(map (lambda (v) (##sys#list v '(##core#undefined)))
+ (foldl (lambda (l v) ; flatten multi-value formals
+ (##sys#append l (##sys#decompose-lambda-list
+ v (lambda (a _ _) a))))
+ '()
+ vars))
+ ,@(map ##sys#expand-multiple-values-assignment vars exprs)
+ ,@body))))))
(##sys#extend-macro-environment
'nth-value
diff --git a/tests/syntax-tests.scm b/tests/syntax-tests.scm
index 59f7d63d..40c94704 100644
--- a/tests/syntax-tests.scm
+++ b/tests/syntax-tests.scm
@@ -62,6 +62,16 @@
(foo 33))
)
+;; letrec-values
+
+(t '(0 1 2 3 (4) (5 6))
+ (letrec-values ((() (values))
+ ((a) (values 0))
+ ((b c) (values 1 2))
+ ((d . e) (values 3 4))
+ (f (values 5 6)))
+ (list a b c d e f)))
+
;; from r5rs:
(t 45
Trap