~ 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