Let's start Scheme

2010-11-12

syntax-case続き

とりあえず、こういう方針でいこうという考えをまとめておく。

syntax-case自体はコンパイラとは関係ない(ないことはないが)、ライブラリとする。
define-syntaxで定義された構文は変換器を返し、変換器が変換する。
(Gaucheはそうしてると思う。ソース見る限り・・・今のところsyntax-rules限定っぽいけど)
define-syntaxで定義された構文にS式が与えられた場合、構文オブジェクトとしてすべての引数を与える。
こんな感じ?
(define-syntax sample
  (lambda (x)
    (syntax-case x ()
      ....)))
(sample 1 2 3) ;; <- この1 2 3っていうのがsyntax-caseによって処理されるために構文オブジェクトになる
ということは、マクロを展開する際に、S式をいったん構文オブジェクトにする必要がありそう。 これで、syntax-caseを定義するとすると
(define-syntax syntax-case
  (lambda (x)
    ... ;; いろいろ定義がいりそう?
    ;; x は構文オブジェクト。matchはAndrew Wrightみたいなの(構文オブジェクトにも対応)
    (match x
      ((_ e ((? literal? literals) ...) clauses ...)
        ...)))) ;; きっといろいろする
っで、こいつ自体が変換器なので、syntax-rulesはこう書いて
(define-syntax with-syntax
  (lambda (x)
    (syntax-case x ()
      ((_ () e1 e2 ...)             (syntax (begin e1 e2 ...)))
      ((_ ((out in)) e1 e2 ...)     (syntax (syntax-case in ()
                                              (out (begin e1 e2 ...)))))
      ((_ ((out in) ...) e1 e2 ...) (syntax (syntax-case (list in ...) ()
                                              ((out ...) (begin e1 e2 ...))))))))
(define-syntax syntax-rules
  (lambda (x)
    (define clause
      (lambda (y)
        (syntax-case y ()
          (((keyword . pattern) template)
           (syntax ((dummy . pattern) (syntax template))))
          (_
           (syntax-violation 'syntax-rules "Invalid expression" x)))))
    (syntax-case x ()
      ((_ (k ...) cl ...)
       (for-all identifier? (syntax (k ...)))
       (with-syntax (((cl ...) (map clause (syntax (cl ...)))))
         (syntax
          (lambda (x) (syntax-case x (k ...) cl ...))))))))
syntax-rulesで定義された構文は 構文 -> syntax-rules変換器 -> syntax-case変換器 -> ごにょごにょ という感じになるはず。 こんなのは
(define-syntax print
  (syntax-rules ()
    ((_ o)
     (begin (display o) (newline)))
    ((_ o1 o2 ...)
     (begin
       (display o1)(newline)
       (print o2 ...)))))
(print 1 2)
こうなる?
(print 1 2) -> (transformer syntax-rules '(syntax-object (print 1 2)))
: with-syntaxは略
-> (transformer syntax-case '(syntax-object ...#;多分この辺にsyntax-rulesで作られたtempleteが入る (print 1 2)))

正しいのかよくわからん。その上、どう実装していいのかもよくわからん・・・

No comments:

Post a Comment