2011/04/07

macroexpand %macroexpand unwrap-syntax

gauche の macroexpand, %macroexpand, unwrap-syntax 。お試しコード垂れ流し。
今まで macroexpand しか使ってなかった。on lisp の mac マクロとかを自前で用意してみたり。で、 %macroexpand ってのは、この mac 相当っぽいですね。
それと unwrap-syntax の存在を知りませんでした。これ便利だー。こんなのないかなーと思ってたんです。

取りあえず、昨日の receive* を使って。
(define-syntax receive*
  (syntax-rules ()
    ((_ () . body)
     (begin . body))
    ((_ ((var val)) . body)
     (receive var
         val
       (begin . body)))
    ((_ ((var val) x ...) . body)
     (receive var
         val
       (receive* (x ...) . body)))
    ))

それぞれこんな感じ。
(macroexpand '(receive* (((a b c)(values 1 2 3))
                         ((d e . rest)(values 4 5 6 7 8 9 10)))
                  (list a b c d e rest)))
;; (#<identifier user#receive> (a b c)
;;               (values 1 2 3)
;;               (#<identifier user#receive*> (((d e . rest) (values 4 5 6 7 8 9 10)))
;;                             (list a b c d e rest)))

(%macroexpand (receive* (((a b c)(values 1 2 3))
                         ((d e . rest)(values 4 5 6 7 8 9 10)))
                  (list a b c d e rest)))
;; (#<identifier user#receive> (a b c)
;;               (values 1 2 3)
;;               (#<identifier user#receive*> (((d e . rest) (values 4 5 6 7 8 9 10)))
;;                             (list a b c d e rest)))

(unwrap-syntax (%macroexpand (receive* (((a b c)(values 1 2 3))
                                        ((d e . rest)(values 4 5 6 7 8 9 10)))
                                 (list a b c d e rest))))
;; (receive (a b c)
;;     (values 1 2 3)
;;   (receive* (((d e . rest) (values 4 5 6 7 8 9 10)))
;;       (list a b c d e rest)))
再帰的に展開する macroexpand はないんでしたよね。Ypsilon にはあると、以前聞いたことがある気が。


scheme と common lisp のマクロの話。ここ読んでたら %macroexpand と unwrap-syntax のことが書いてあった。

プログラミングGauche

0 件のコメント:

コメントを投稿