while ("im in s-expr");

 | 

2008-09-13

GaucheでC言語レベルでの手続きの定義

| 03:19

  • サンプル: Gauche interface for Vimの(vim-echomsg-port)
  • GaucheではC言語レベルで実装された手続きのことをsubrと呼んでいる。

1. 手続きの本体をC言語で実装

static ScmObj
vim_echomsg_port_proc(ScmObj *args, int nargs, void *data)
{
        return Scm_VimEchomsgPort();
}
  • argsは引数の配列。実際にはVMのスタックに詰まれた値へのポインタ(だと思う)。
  • nargsは引数の個数。
  • dataは手続き作成時に指定した値。

2. 手続きオブジェクトを定義

static SCM_DEFINE_STRING_CONST(vim_echomsg_port_NAME, "vim-echomsg-port",
                               16, 16);
static SCM_DEFINE_SUBR(vim_echomsg_port_STUB, 0, 0,
                       SCM_OBJ(&vim_echomsg_port_NAME), vim_echomsg_port_proc,
                       NULL, NULL);
  • 手続きオブジェクトvim_echomsg_port_STUBを定義。
  • 最初の0は必須引数の個数(ScmProcedureRec.required)。続く0は省略可能引数を取らないことを示す(1なら取る)(ScmProcedureRec.optional)。
  • SCM_OBJ(&vim_echomsg_port_NAME)は、多分、デバッグや外部表現用の情報(ScmProcedureRec.info)。これは別途、SCM_DEFINE_STRING_CONST()で定義しておく。
  • vim_echomsg_port_procはSchemeレベルからこの手続きが呼ばれたときに実行するC言語レベルの関数(ScmSubrRec.func)。
  • 最初のNULLは不明(ScmProcedureRec.inliner)。他のコードを見る限りNULLで良いみたい。
  • 最後のNULLはvim_echomsg_port_procの呼び出し時に渡される追加引数(ScmSubrRec.data)。今回は未使用。

3. モジュールへの束縛の追加

SCM_DEFINE(Scm_UserModule(), "vim-echomsg-port",
           SCM_OBJ(&vim_echomsg_port_STUB));
  • 特に説明は不要か。
  • これがないとSchemeレベルから参照しようがない。

その他

  • ライブラリ的なものは*.stubから自動生成すべき。でもstub関連は今一把握できてないので保留中。仮にできたとしても、Vimのソースツリー的にはsrc/if_gosh.cの1ファイルにまとまってた方が良いのでどうしたものか。
  • 次の課題: 本当はvimモジュールを作成して各種束縛はそこに追加し、後にuserモジュールからuseしたい。その辺りの処理。

Gauche interface for Vim (第2話)

| 01:44

ようやく形が見えてきたかな。

  • :gauche {script}を実装。
  • (vim-echomsg-port)と(vim-echoerr-port)を実装。
    • ただ逐次:echomsgしているので、(write '(something wonderful) (vim-echomsg-port))などで悲しいことになる。
    • ラッパーとして(vim-echomsg {obj})などを用意した方が便利だろう。
  • (current-input-port)などの初期値を/dev/null相当に変更。
    • 初期値は(standard-input-port)などであり、それをVim内で使われると色々と不味いため。
    • 本当は(standard-input-port)などの値を置き換えたいのだけど、それは不可能に近いので諦めた。
    • さらに言えば、誤って:gauche (read)などとした場合に備えて、読み込みや書き込みをすると警告を出すようにしたい。

あとは(vim-execute {vim-script})や(vim-eval {vim-script-of-an-expression})の実装をすれば最低限のものは完成。その前にGaucheの値とVim scriptの値の変換規則を決めておかないと。

トラックバック - http://cadr.g.hatena.ne.jp/ka-nacht/20080913
 |