2010年6月2日水曜日

vallog: syntax-rules: bind-variables

vallog: syntax-rules: bind-variables


「...」だと、こうは書けないですよね。。


多分こう書くのではないでしょうか。
(define-syntax bind-variables
(syntax-rules ()
((_ () form ...)
(begin form ...))
;; ここはオリジナルの syntax-error がどんな挙動か分からないので割愛
;; error で置き換えてみたが、本体に form ... が無い、と怒られた
;; ((_ ((var val0 val1 ...) ...) form ...)
;; (error "bind-variables illegal binding" (var val0 val1 ...)))
((_ ((var val) more-bindings ...) form ...)
(let ((var val)) (bind-variables (more-bindings ...) form ...)))
((_ ((var) more-bindings ...) form ...)
(let ((var #f)) (bind-variables (more-bindings ...) form ...)))
((_ (var more-bindings ...) form ...)
;; ここは、本当は上のパターンに差し替えたほうが綺麗かも
(let ((var #f)) (bind-variables (more-bindings ...) form ...)))
((_ bindings form ...)
(error "Bindings must be a list." bindings))
))
;; ;; 実行例
;; > (bind-variables ((a 1)
;; (b)
;; c
;; e
;; (d (+ a 3)))
;; (list a b c d e))
;; (1 #f #f 4 #f)
;; > (let ((a 1))
;; (bind-variables ((b)
;; c
;; e
;; (d (+ a 3)))
;; (list a b c d e)))
;; (1 #f #f 4 #f)
;; > (let ((a 1))
;; (let ((b #t))
;; (bind-variables (c
;; e
;; (d (+ a 3)))
;; (list a b c d e))))
;; (1 #t #f 4 #f)
;; > (bind-variables (a b c d e)
;; (list a b c d e))
;; (#f #f #f #f #f)
;; > (bind-variables ((a) (b) (c) (d) (e))
;; (list a b c d e))
;; (#f #f #f #f #f)
;; > (bind-variables (a (b 1) (c 2) d (e))
;; (list a b c d e))
;; (#f 1 2 #f #f)
;; >


オリジナルのコードだとsyntax-errorっての使ってますが、これはR5RSで定義されていないので、errorに差し替えています。
もっとも、2番目のパターンだとそれじゃあ怒られたので、syntax-errorの挙動がしりたいトコなんですけどねえ。

いずれにせよ、省略子で書いた方がパターン的にはシンプルなのではないでしょうか。

0 件のコメント:

コメントを投稿