Let's start Scheme

2012-01-31

CiSEみたいなのがほしい

願望的に書いているが、現在使っているスタブジェネレータがちょっと使い辛くなってきた。いや、別に使い辛くはないのだが、拡張性が皆無だなぁということに気づいたのと、結構他のヘッダーファイルべったりな構成になっているのでSchemeのファイルなおしてCのヘッダー直してというのが面倒になってきた。
っで、GaucheのCiSEを眺めていたらすごく抽象化されていて美しいコードだなぁと。たぶんそのまま移植できるんだろうけど、それやったら面白くない上に結局理解してないから自分で拡張できない。ということでコードの分析。

基本的にほしい機能の部分としては、gauche.cgen.cise、gauche.cgen.stubの2つ。っでこれらが大きく依存しているのが、gauche.cgen.unit(以下ユニット)、gauche.cgen.literal(以下リテラル)。ツール的になのかフックなのかはまだ見てないけどgauche.cgen.typeがstubファイル内での<object>形式の記述をCに変換している。
ユニットではCのプリプロセッサと生のコードを扱う。生のコードがどう書かれるのかは知らない。それぞれを扱うクラスがあって、それぞれをどう出力するかの総称関数がある。
リテラルはSchemeのリテラルをCに変換するモジュール。リストとか文字列の変換。リテラルクラスが上記のユニットを継承して定義される。
CiSE内では基本的な変換部分しか定義されず、その他のモジュールでGauche固有の定義が入る。ただ、そうは言ってもCiSE内で定義されている構文にはScmObjとか入ってくる(let*とかfor-eachとか)
また、CiSEは環境を保持していて、トップレベル、ステートメント、式の3つがある。たとえばdefine-cfnはトップレベルでしか定義できないし、beginは全部いけるんだけどそれぞれ出力されるCのコードが違う。

とりあえずここまで踏まえて、まずどこまでやるかを考える。
  • 特に純粋なCファイルを出力する必要はない
  • 現状のStubファイルとVMインストラクションの手直しはがっつりやってもOK
  • SchemeファイルをCにする必要はない(gauche.cgen.precompモジュール相当はいらない)
として、方針。
  • ノード毎のクラスは取り入れたい
  • 環境+render部分を移植(だめじゃん)
  • 純粋なCiSE部分、Sagittarius固有定義というようにする
とした場合、ライブラリの構成を考えると、こんな感じだろうか?
                   +--------------+       +-------------+
                   |     CiSE     | ----- |     Unit    |
                   +--------------+       +-------------+
                          |                      |
                   +--------------+       +-------------+
                   |    Syntax    |       |   Literal   |
                   +--------------+       +-------------+
                          |                      |
                   +--------------+              |
                   |     Stub     | -------------+
                   +--------------+
CiSEではSagittariusに依存しない構文までサポート。letでは総称関数を作ってデフォルト型の定義を下位のライブラリで行うようにする。デフォルトの振る舞いはエラーでいい気がする。
SyntaxではSagittariusに依存する構文を入れる(for-eachとか)。
Stubは単なるエントリーポイントになるか、それとももう少し何か入れるかは考えてない。

No comments:

Post a Comment