2011/06/05

ifをcondで書け

って以外意外と面倒なんだな。。

syntax-rulesで
(define-syntax new-if
  (syntax-rules ()
    ((_ predicate then-clause else-clause)
     (cond (predicate then-clause)
           (else else-clause)))
    ((_ pred then)
     (new-if pred then (undefined)))))

(unwrap-syntax (%macroexpand (new-if #f (print "hoge")(print "fuga"))))
;; -> (cond (#f (print "hoge")) (else (print "fuga")))
(unwrap-syntax (%macroexpand (new-if #t (print "hoge")(print "fuga"))))
;; -> (cond (#t (print "hoge")) (else (print "fuga")))
(unwrap-syntax (%macroexpand (new-if #f (print "hoge"))))
;; -> (cond (#f (print "hoge")) (else (undefined)))
(unwrap-syntax (%macroexpand (new-if #t (print "hoge"))))
;; -> (cond (#t (print "hoge")) (else (undefined)))
(unwrap-syntax (%macroexpand (new-if #t (print "hoge")(print "fuga")(print "?"))))
;; -> *** ERROR: Compile Error: malformed if

define-macroで
(define-macro (new-if predicate then-clause . else-clause)
  `(cond (,predicate ,then-clause)
         ,(cond ((null? else-clause)`(else ,(undefined)))
                ((null? (cdr else-clause))`(else ,@else-clause))
                (else (error "malformed if")))))


(unwrap-syntax (%macroexpand (new-if #f (print "hoge")(print "fuga"))))
;; -> (cond (#f (print "hoge")) (else (print "fuga")))
(unwrap-syntax (%macroexpand (new-if #t (print "hoge")(print "fuga"))))
;; -> (cond (#t (print "hoge")) (else (print "fuga")))
(unwrap-syntax (%macroexpand (new-if #f (print "hoge"))))
;; -> (cond (#f (print "hoge")) (else #<undef>))
(unwrap-syntax (%macroexpand (new-if #t (print "hoge"))))
;; -> (cond (#t (print "hoge")) (else #<undef>))
(unwrap-syntax (%macroexpand (new-if #t (print "hoge")(print "fuga")(print "?"))))
;; -> *** ERROR: Compile Error: malformed if

0 件のコメント:

コメントを投稿