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