[plt-scheme] Keyword argument macros

From: Joe Marshall (jmarshall at alum.mit.edu)
Date: Tue Jan 6 17:19:00 EST 2009

It's easy enough to do with syntax-rules.  I wrote a syntax-rules macro that
implements Common Lisp argument lists.  There are keywords such as
&optional, &rest, &aux, &key and &allow-other-keys.  Here is how the &aux
keyword is parsed out:

(define-syntax rewrite-aux
  (syntax-rules (&aux)
    ((rewrite-aux "start" lambda lambda-list body)
     (rewrite-aux "scan-lambda-list" lambda () lambda-list body))

    ((rewrite-aux "scan-lambda-list" lambda (lambda-list ...) (&aux .
params) body)
     (rewrite-aux "reverse-aux" lambda (lambda-list ...) () params body))

    ((rewrite-aux "scan-lambda-list" lambda (lambda-list ...) (param .
params) body)
     (rewrite-aux "scan-lambda-list" lambda (lambda-list ... param)
params body))

    ;; Didn't find an aux, just paste it back together.
    ((rewrite-aux "scan-lambda-list" lambda lambda-list () body)
     (lambda lambda-list . body))

    ((rewrite-aux "reverse-aux" lambda lambda-list reversed (aux . params) body)
     (rewrite-aux "reverse-aux" lambda lambda-list (aux . reversed)
params body))

    ((rewrite-aux "reverse-aux" lambda lambda-list reversed () body)
     (rewrite-aux "aux-found" lambda lambda-list reversed body))

    ((rewrite-aux "aux-found" lambda lambda-list (aux . params) body)
     (rewrite-aux "rewrite-one-aux" lambda lambda-list aux params body))

    ((rewrite-aux "rewrite-one-aux" lambda lambda-list (param init) params body)
     (rewrite-aux "aux-found" lambda lambda-list params ((let ((param
init)) . body))))

    ((rewrite-aux "rewrite-one-aux" lambda lambda-list (param) params body)
     (rewrite-aux "aux-found" lambda lambda-list params ((let ((param
(default-aux-value))) . body))))

    ((rewrite-aux "rewrite-one-aux" lambda lambda-list param params body)
     (rewrite-aux "aux-found" lambda lambda-list params ((let ((param
(default-aux-value))) . body))))

    ((rewrite-aux "aux-found" lambda lambda-list () body)
     (lambda lambda-list . body))))


Ok, it's a bit ugly, the gist of it is that you iteratively expand the
`rewrite-aux'
macro and accumulate the lambda-list in the third argument.  If you see
a list starting with &aux, you start collecting the aux args.



-- 
~jrm


Posted on the users mailing list.