macro-expander

  • マクロ展開子を導入(3.13)。今までも and は if に書き換えてコンパイルしていたけど、マクロ展開をしてからコンパイルすることで、コードが少し明確になった。
  • util.match のおかげで式変形は簡単。
  • cond, and, or, when, unless をマクロで書き換え。let*, letrec も追加予定。
  • α-conversion はまだ。変数を探して rename するだけ?
;; 本体
(compile-program-iter
 (closure-conversion
  (assignment-conversion
   (tail-call-conversion
    (macro-expander expr))))
 env module main)
;;
(define (macro-expander expr)
  (match expr
    (('and) #t) ; (and) => #t
    (('and e) (let ((it (gensym)))
                `(let ((,it ,e))
                   (if ,it ,it #f)))) ; (and e) => (if e e #f)
    (('and e e* ...) ; (and x y ..) => (if x (and y ...) #f)
     (let ((it (gensym)))
       `(let ((,it ,e))
          (if ,it ,(macro-expander `(and ,@e*)) #f))))
;; 中略
    (('when test body0 body ...)
     `(if ,test (begin ,(macro-expander body0) ,@(macro-expander body))))
    (('unless test body0 body ...)
     `(if (not ,test) (begin ,(macro-expander body0) ,@(macro-expander body))))
    (_
     (cond
      ((pair? expr)
       (cons (macro-expander (car expr))
             (macro-expander (cdr expr))))
      (else
       expr)))))