[plt-scheme] Where is macroexpand in PLT Scheme?
Bill Clementson <bill_clementson at yahoo.com> writes:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> I wanted to expand a macro in Scheme today. I had a
> look for "macroexpand" in R5RS and the PLT
> documenation. Didn't find it. At least, not in R5RS.
`macroexpand' would only be useful as a top-level debugging tool. It
would be quite difficult to make it work `correctly' with R5RS macros.
I'm guessing that is one reason it is not in R5RS.
> In PLT Scheme, the following code seems to be roughly
> equivalent to macroexpand:
>
> (syntax-object->datum (expand-to-top-form '(some-macro
> some-params)))
Roughly, yes.
> Seems odd that there isn't some more convenient way to
> do a macro expansion.
I stole this from Eli Barzilay and put it in my mzscheme.rc file:
;;; Syntax debugging
;;; -test or (-test) returns current syntax object as an s-expression
;;; (-test foo) set current
;;; (-test :this) show current
;;; (-test :expand) expand current (possibly in a context)
;;; (-test :expand-once) expand one step
;;; (-test :expand*) expand one step repeatedly
;;; (-test :pp) pprint current
(define-syntax -test
(let ((v #f)
(->datum (lambda (x) (if (syntax? x) (syntax-object->datum x) x))))
(lambda (stx)
(syntax-case stx ()
((_ m)
(let ((msg #'m))
(let loop ((new (case (->datum msg)
((:this :pp) v)
((:expand) (expand v))
((:expand-once :expand*) (expand-once v))
(else msg))))
(if (eq? ':pp (->datum msg))
((dynamic-require '(lib "pretty.ss") 'pretty-print)
(->datum new))
(printf "--> ~s\n" (->datum new)))
(let ((old v))
(set! v new)
(when (eq? (->datum msg) ':expand*)
(if (equal? (->datum new) (->datum old))
(printf "--> ...\n")
(loop (expand-once v))))))
#'(void)))
(_ #`'#,v)))))