Let's start Scheme

2012-09-05

マクロ展開時のライブラリ

以下のツイートを発見。
動かないのは許せない(というか、バグだし)ので、原因を探る。元コードはきっとこれだろう。
文字列補間 - 主題のない日記 
とりあえず、走らせる。&assertionか。なんとなく既に嫌な予感がしている。 いろいろ省略して原因箇所:
(datum->syntax #'string-interpolate 'x->string)
これ。全体というよりも、#'string-interpolateの部分のみ。

何故か?これ多分マクロ展開器の根幹の問題で、(syntax foo)という構文は定義されたライブラリ内ではなくimportされた先のライブラリで解決される。つまり、識別子が所属するライブラリがおかしいのである。なので、datum->syntax手続きが、#'string-interpolateからx->stringを作る際に本来ならば定義されたライブラリの情報を付加しないといけないんだけど、importしたライブラリの情報を付加する。結果、unbound variableといって怒られる。

とりあえず、一時的なしのぎとしてx->stringもexportしてしまうのが最も簡単な解決方法であろう。0.3.6以降のどこかで頑張って直そう。ちょっと(かなり?)大き目のバグが2つになった。燃える(φΛφ)

やはりいろいろな人に検証してもらうのは非常にありがたい。僕一人では恐らく未来永劫気づかなかったバグだ。

今日は脳汁が大量に出ていたらしい、これ書いて長丁場なバグ取りを予想していたのだが、意外とさくっと直せた。

以下が直した方法:
【syntaxの展開】
  1.  (syntax k)のようなシンボルを取るものはそれ自身がマクロ捕捉時のライブラリ内で定義されているかチェック
  2. 定義されていてかつ基になったテンプレートがパターン変数でなければシンボルのラップにマクロ捕捉時の環境を使う
  3. 1.と2.のチェックから外れる場合は実行時環境をシンボルのラップに使う
 【datum->syntax】
  1. template-idと実行時環境のライブラリを比較。同じなら実行時環境をラップに使う
  2. 違うならばマクロ捕捉時の環境を使う
正直、上記の解決方法が「正しい」かどうかまったく自身がない。抜けがある気がしてしょうがないからである。とりあえず、全てのテストケースが通ってかつ、バグが直っているので現状では正しいということにしておく。

No comments:

Post a Comment