Let's start Scheme

2011-03-04

syntax-caseの実装

結局MIT Schemeのsyntax-rulesの実装を移植して現在syntax-rulesとsyntax-caseを実装中。
syntax-rulesはYpsilonのストレステストが動かないが(正しくマクロのマッチングが行われない)、まぁ通常用途には使える程度に動いてる。
っで、syntax-caseなのだが、とりあえず、動作結果を確認するために以下のようなものをYpsilonに喰わせてみた。
(import (rnrs))

(define-syntax fuga
  (lambda (x)
    (syntax-case x ()
      ((_ r ...)
       (begin
  (display x)(newline)
  (syntax
   (list '(r (r ...)) ...)))))))
(display (macro-expand (fuga 1 2 3)))
で、結果はこんな感じ
(fuga 1 2 3)
((1 (1 2 3)) (2 (1 2 3)) (3 (1 2 3)))
これが意味するところとしては、マクロ内で定義された構文オブジェクト意外はマクロ展開時に実行されているということ。
っで、macro-expandの部分を%macroexpandに変更してSagittariusにも喰わせてみると。こんな感じ。
(begin
 (display x)
 (newline)
 (#<syntax list>
  (#<syntax quote> (1 (1 2 3)))
  (#<syntax quote> (2 (1 2 3)))
  (#<syntax quote> (3 (1 2 3)))))
ここから察するに、もう一段階実行してやって、構文オブジェクトで包まれてる部分を取り除いてやればよさそうだ。
問題はいくつかあって、
  • コンパイラは構文オブジェクトを見つけた際に、(組み込みかユーザー定義かの差はあるが)マクロ展開を行おうとする
  • もう一段階実行した際に、構文オブジェクト以外の部分がコンパイル実行されるため、たとえばシンボルをリストにしようとした際にVMがエラーを通知する
とりあえず、思いつくだけで2つか。まだありそうだが。前者はコンパイラに(また)条件式を追加する必要がある。(いやだなぁ)
後者はどうしようかねぇ。考えるか。

No comments:

Post a Comment