You can use the functions from macro-debugger/expand to do this (within limits). Here's a very rough example program that reads one term from stdin and shows its expansion with the given hiding policy (discarding hygiene information---beware).

usage: racket expand.rkt < your-example-file.rkt

Ryan


On 8/10/20 3:44 PM, Éric Tanter wrote:
Hi,

I’d like to use the Racket macro expander to translate programs from a given source language to a target language (both scheme-ish).

However, the expansion that `raco expand` does is too violent for my purposes---I would need a way to specify macro hiding (as in the macro stepper), in order to control the level of abstraction of the expanded code. Is that possible?
[see example below]

Thanks,

— Éric

; test.rkt
(define-syntax-rule (swap x y)
   (let ([tmp x])
     (set! x y)
     (set! y tmp)))

(define a 10)
(define b 20)
(swap a b)

; I’d like to obtain:

…prelude…
(define a 10)
(define b 20)
(let ([tmp a])
     (set! a b)
     (set! b tmp)))

; but raco expand gives me the full story:

(module test play
   (#%module-begin
    (module configure-runtime '#%kernel
     (#%module-begin (#%require racket/runtime-config) (#%app configure '#f)))
    (#%provide b swap a)
    (define-syntaxes
     (swap)
     (lambda (user-stx)
       (let-values (((arg) user-stx))
         (let-values (((rslt)
                       (#%app
                        (lambda (e)
                          (if (#%app stx-pair? e)
                            (if (#%app (lambda (e) null) (#%app stx-car e))
                              (#%app
                               (lambda (e)
                                 (if (#%app stx-pair? e)
                                   (#%app
                                    cons/#f
                                    (#%app stx-car e)
                                    (#%app
                                     (lambda (e)
                                       (if (#%app stx-pair? e)
                                        (let-values (((mh) (#%app stx-car e)))
                                           (if mh
                                             (if (#%app
                                                  stx-null/#f
                                                  (#%app stx-cdr e))
                                               mh
                                               '#f)
                                             '#f))
                                         '#f))
                                     (#%app stx-cdr e)))
                                   '#f))
                               (#%app stx-cdr e))
                              '#f)
                            '#f))
                        arg)))
           (if rslt
             (let-values (((sc1) (#%app unsafe-car rslt))
                          ((sc2) (#%app unsafe-cdr rslt)))
               (let-values ()
                 (#%app
                  syntax-protect
                 (let-values (((loc) (#%app check-loc 'syntax/loc user-stx)))
                    (#%app
                     t-subst
                     loc
                     (quote-syntax (let _ (set! _ _) (set! _ tmp)))
                     '(1 recur 2 recur 3)
                     (#%app
                      t-resyntax
                      '#f
                      (quote-syntax STX)
                      (#%app
                       t-list
                       (#%app t-subst '#f (quote-syntax (tmp _)) '(1) sc1)))
                     (#%app list '(1 2) sc1 sc2)
                     (#%app list '(1) sc2))))))
             (let-values (((rslt) (#%app (lambda (e) null) arg)))
               (if rslt
                 (let-values ()
                   (let-values () (#%app pattern-failure user-stx '(x y))))
                 (#%app raise-syntax-error '#f '"bad syntax" arg))))))))
    (define-values (a) '10)
    (define-values (b) '20)
    (#%app
     call-with-values
     (lambda () (let-values (((tmp) a)) (set! a b) (set! b tmp)))
     print-values)))

--
You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com <mailto:racket-users+unsubscr...@googlegroups.com>. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/94E20736-F1F7-4073-B3FA-505ADD71DB4F%40dcc.uchile.cl <https://groups.google.com/d/msgid/racket-users/94E20736-F1F7-4073-B3FA-505ADD71DB4F%40dcc.uchile.cl?utm_medium=email&utm_source=footer>.

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/767ebe77-95ed-d9f7-4d00-6391482d15a9%40gmail.com.
#lang racket/base
(require syntax/modread
         macro-debugger/expand
         racket/pretty)

;; Read a term from stdin, expand, and show expansion (but only of
;; selected identifiers).

(define stx (with-module-reading-parameterization
              (lambda () (read-syntax #f (current-input-port)))))

;; Replace this with the predicate you care about...
(define (show-macro? id)
  (memq (syntax-e id) '(swap)))

(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))

(pretty-print
 (syntax->datum
  (parameterize ((current-namespace ns))
    (expand/show-predicate stx show-macro?))))

Reply via email to