とりあえず、そのようなものに苦しんでいる。
syntax-caseの実装をライブラリではなく、builtinな実装に切り替えた。(可能ならライブラリにしたいが、今のところ不可能そうなので)
っで、(何度となくぶつかったが)ぶつかった壁がこれ。
こんなコードが怒られる。
(syntax-case (list (f (syntax c2) (syntax (c3 ...)))) () ((rest) (let () (syntax-case c1 (=>) ((e0) (print (syntax rest)) (syntax (let ((t e0)) (if t t rest)))) ((e0 => e1) (syntax (let ((t e0)) (if t (e1 t) rest)))) ((e0 e1 e2 ...) (print (syntax rest)) (syntax (if e0 (begin e1 e2 ...) rest)))))))これはR6RSの何章かにあったcondのsyntax-case版実装を走らせて、途中経過をダンプしたもの。
何がまずいかというと、restが外側のsyntax-caseでパターン変数として現れているのだが、現状の実装では内側のsyntax-caseから外側のsyntax-caseのパターン変数は見えない。
現状の実装としては、
syntax-caseが現れたら、それのパターンとそのパターンの情報、出力部分とフェンダーをクロージャー化したものをmatch-syntax-caseという関数に渡して返している。っで、それがもう一回S式→内部表現の関数に渡されるという感じ。
自分でもここまではすっきりかけたなぁと自画自賛していたのだが(まぁ、Ypsilonの実装からかなり盗んだからだが・・・)、この自由パターン変数が現れてちょっと(だいぶ)躓いている。
上記にも書いたが、パターンのメタ情報はmatch-syntax-caseに渡しているため、どこかから取り出すということができない。この際、Ypsilonでは.varsというトップレベルの変数に入れて、実際に置き換えを行う際にテンプレートの変数が自由パターン変数かどうかをチェックしている。ように見える。
現状、そのような変数を導入してないので、どうしたものかということになるのだが、どうしたものか。
No comments:
Post a Comment