ciseがR6RSにも欲しい
Gaucheにはgauche.cgen.ciseという(undocumentedで)便利なライブラリがあり、S式で書いたプログラムをC言語ソースに変換することが出来る。
これをそのままmoshに持ち込むのはちょっと大変なので、外堀を埋めていく形で少しづつ進めている。
- (fmt)ライブラリ。これはciseとは別の記法のS式から、読めるCコードを出力する。
- オブジェクトシステムのC言語インターフェース。
- マクロを展開するためのライブラリ(nmosh expander)。
もちろん元がC++なんだからC++のコードを出力すればという説も有るが、C++のコードを出力しても意味がない。平たく言えば(今後普及するであろう)OpenCLのコンパイラはCのコンパイラであり、C++でない。あと、C++には明確に機能するABIが無いため、実行中のランタイムを出力したコンパイラでなければ機能する追加コードを出力できない。(一般には、この問題に対処するためにCOMとかXPCOMのような手法が利用されてきたが、個人的な観点から言うとこれらには未来が無い。これは言語処理系をC++で書くべきではない重要な理由の一つ。)
単純に興味が有るのは、R6RSのライブラリシステムで実装できるかどうか。つまり、
(library (some library) (export compiled-function) (import (c compatible words) (only (rnrs base) define lambda define-syntax syntax-rules)) (define-syntax ...
のように、cise的に互換する(= C言語インターフェースを装備している)語彙と、R6RSのマクロシステムを混合して記述できるかどうか。
C言語ソースを出力するケースでは、expand時にはScheme側のオブジェクトシステムが使用でき、run時には使えないことになる。
今回移植したexpanderは、フェーズ毎の単語の有効性を確認する。つまり、マクロ展開時に使える語彙と、実行時に使える語彙を明確に区別することができる(psyntaxはこれが出来ない)。
結論としては、本来R6RSのライブラリシステムはこのようなケースを処理できない。これらはライブラリの語彙のみに着目していて、expand時に生成したオブジェクトはrun時にも使えることが前提になっている。
しかし、マクロの使用法によっては実行時にSchemeオブジェクトが残らないケースも考えられる。例えば展開時に生成したオブジェクトに対してdatum→syntaxを行うようなケースが該当する。