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