Skip to content

Instantly share code, notes, and snippets.

@wakita
Created August 29, 2012 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wakita/3506509 to your computer and use it in GitHub Desktop.
Save wakita/3506509 to your computer and use it in GitHub Desktop.
マクロ定義を環境に埋め込み,取り出す試み → でも失敗
;;; マクロ使用をマークするためのシンボル
(define jsx-mark-macro-usage
(string->symbol "JSX:Mark Macro Usage"))
;;; マクロ使用を環境に閉じ込めるための仕掛け
(define (encapsulate e)
`(,jsx-mark-macro-usage (lambda () ,e '())))
;;; encapsulate でマクロ使用を閉じ込めた箇所から,展開後の式を取り出す
(define (extract e)
(define env '())
(define (aux e)
(cond
((null? e) e)
((and (list? e) (eq? (car e) 'define))
(let* ((var (cadr e))
(e (caddr e)))
(set! env (cons `(,var . ,e) env))
`(define ,var ,(aux e))))
((and (list? e) (eq? (car e) jsx-mark-macro-usage))
(cadddr (assq (cadr e) env)))
((list? e) (map (lambda (e) (aux e)) e))
(#t e)))
(aux e))
;; ここから実験.まずは A.S. のマクロ定義
(define-syntax def
(syntax-rules ()
((_ var val) (define var val))))
;; (def v a) を encapsulate で lambda 環境に閉じ込めてからマクロ展開し,最後に extract を使って lambda 環境から解放してみた.
(let* ((e0 '(def v a))
(e1 (macro-expand (encapsulate e0)))
(e2 (extract e1)))
(display "An expression\n")
(pretty-print e0) (display "\n\nExpands to \n")
(pretty-print e1) (display "\n\nand becomes\n")
(pretty-print e2) (newline))
@wakita
Copy link
Author

wakita commented Aug 29, 2012

これを実行すると以下のようになります.

An expression
(def v a)

Expands to
(begin
(define \x2E;L4 (lambda () (letrec* ((v\x60;22* a)) '())))
(JSX:Mark\x20;Macro\x20;Usage \x2E;L4))

and becomes
(begin
(define \x2E;L4 (lambda () (letrec* ((v\x60;22* a)) '())))
(letrec* ((v\x60;22* a)) '()))

@wakita
Copy link
Author

wakita commented Aug 29, 2012

いくつか問題があります.

  • define が letrec* に化けてしまう.
  • 局所環境に閉じ込められたために,v として定義したかった名前が v\x60;22* に化けてしまった.

ということで,別の方法を考えないといけないようです.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment