Sagittariusで発見して、Gaucheでも再現するという不思議なバグの話。
以下のコード
(define-syntax hoge
(syntax-rules ()
((_ args ...)
(letrec-syntax
((find (syntax-rules ()
((_ a b c)
(next a b))))
(next (syntax-rules ()
((_ a b c)
(find a b c))
((_ a b)
(print a b)))))
(find args ...)))))
(hoge 1 2 3)
findとかnextはSSAXのマクロから取っているだけで別に名前はなんでもいい。これを実行すると、unknown variable nextというのが出る。でも、letrec-syntaxの部分だけ取り出して実行すると動く。
原因は分かっていて、識別子の比較が弱いためにコンパイル時環境のlookupが失敗しているのだ。
不思議なこととしては、最初のhogeが展開されたときに作成される識別子は正しく作成されている(この場合は同じアドレスという意味)のに、lookup時はなぜか失敗する。
コンパイル時環境のlookupはGaucheとほぼ同じなのだが、syntax-rulesの実装はまるで違う(はず)。なのに両方でこれが発生するということは、まぁ、そこなんだろう。もしくは、syntax-rules内で予定外の識別子がrenameされたかのどちらかなんだけど。
原因を追究していたのだが、疲れたので息抜きに書いてみた。
No comments:
Post a Comment