~ chicken-core (chicken-5) 8f79e95e7a50a216f1c46e472263d566ef06de66
commit 8f79e95e7a50a216f1c46e472263d566ef06de66
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Thu May 20 17:50:28 2010 +0200
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Thu May 20 17:50:28 2010 +0200
added ##sys#parse-keyword-argument-list
diff --git a/expand.scm b/expand.scm
index 043a6f3a..13e4ee7d 100644
--- a/expand.scm
+++ b/expand.scm
@@ -1922,3 +1922,73 @@
(set-module-sexports! mod sexports))))
(define ##sys#module-table '())
+
+
+;;; Procedure to pre-parse keyword argument lists
+
+(define ##sys#parse-keyword-argument-list
+ (let ((reverse reverse)
+ (string-append string-append))
+ (lambda (arglist k+d k #!key (rename identity) (warn? #t) location)
+ (let ((%let (rename 'let)))
+ (define (warn msg . args)
+ (when warn?
+ (apply
+ ##sys#warn
+ (if location
+ (string-append
+ "(" (##sys#symbol->string location) ") "
+ msg)
+ msg)
+ args)))
+ (define (kw->sym kw)
+ (##sys#string->symbol (##sys#symbol->string kw)))
+ (let loop ((args arglist) (bindings '()))
+ (cond ((null? args)
+ `(,%let ,(map cdr (reverse bindings))
+ (,%let ; bind variables with names of keyword args
+ ,(let loop ((k+d k+d)) ; in case defaults refer to them
+ (if (null? k+d)
+ '()
+ (let* ((x (car k+d))
+ (kw (car x))
+ (def (cdr x)))
+ (cond ((assq kw bindings) =>
+ (lambda (a)
+ (cons (list (kw->sym kw) (cadr a))
+ (loop (cdr k+d)))))
+ (else
+ (cons (list (kw->sym kw) def)
+ (loop (cdr k+d))))))))
+ ,(k (let loop ((k+d k+d))
+ (if (null? k+d)
+ '()
+ (let* ((x (car k+d))
+ (kw (car x)))
+ (cond ((assq kw bindings) =>
+ (lambda (a)
+ (cons (cadr a) (loop (cdr k+d)))))
+ (else
+ (cons (kw->sym kw)
+ (loop (cdr k+d))))))))))))
+ ((not (pair? args))
+ (warn "invalid argument list syntax" arglist)
+ #f)
+ (else
+ (let ((arg (car args))
+ (rest (cdr args)))
+ (cond ((keyword? arg)
+ (cond ((assq arg k+d) =>
+ (lambda (a)
+ (cond ((not (pair? rest))
+ (warn "missing keyword argument value" arg arglist)
+ #f)
+ (else
+ (let ((tmp (gensym arg)))
+ (loop
+ (cdr rest)
+ (cons (list arg tmp (car rest)) bindings)))))))
+ (else
+ (warn "unrecognized keyword argument" arg arglist)
+ #f)))
+ (else #f))))))))))
Trap