YamaKen
yamak****@bp*****
2005年 10月 8日 (土) 10:15:45 JST
At Fri, 7 Oct 2005 17:37:09 -0700, jun.l****@gmail***** wrote: > On Sat, 08 Oct 2005 01:55:36 +0900 > YamaKen <yamak****@bp*****> wrote: > > SigSchemeにstring portが追加されましたが、インタプリタ側がこれを > > 認知して個別対応する必要があるのでメンテナンス性や今後の拡張に難 > > があると感じています。また、Schemeで書かれたportへの対応が不十分 > > です。 > > > > そこで以下のような抽象化によりタイプ依存コードを隠蔽する事を提案 > > します。どうでしょうか。 > > struct ScmCPortVTbl { > > ScmObj (*type)(ScmCPort cport); /* returns a symbol */ > > 変数にした方がいいでしょう。途中でコロコロ変わる必要は無いし、変わられて > も困る。 これは変数にしようか迷ったんですが、constなグローバル変数として テーブルを初期化するにはstorageの初期化が必要なScmObjは都合が悪 いので関数にしました。動的にIDを変える目的ではないです。 ただどっちにしろID(a symbol)はinit時にprotectedなグローバル変数 に保持する事になるんで、vtblの初期化もその時に行ってしまえば手間 は変わらないですね。変数にしましょう。 ついでに突っ込まれそうなんで説明しておきますが、手動でシンボル ('ScmStrPortとか)を割り当てるとユーザ定義のportと衝突する可能性 があるので、cons cellを割り当ててそれをIDとした方がよいです。 > > int (*finalize)(ScmCPort cport); > > int (*close_input)(ScmCPort cport); > > int (*close_output)(ScmCPort cport); > > 全部 close 一つでまとめたらいいのでは? 入出力 port の一方向だけ塞がなく > てはいけない場面というのを思いつかないんですが。 まずfinalizeとcloseは区別する必要があります。closeはコードの指示 で明示的に閉じる場合、finalizeはsweep時のScmCPort解放です。単な るfree(3)では済まないような構造を持っている場合に必要です。 それからin/outを区別してのcloseですが、pipe(2)で得たfdを fdopen(3)経由でScmFilePortに保持するような場合に必要です。 > > /* input */ > > int (*getc)(ScmCPort cport); > > int (*peek_char)(ScmCPort cport); > > int (*char_readyp)(ScmCPort cport); > > /* output */ > > int (*vprintf)(ScmCPort cport, const char *str, va_list args); > > int (*display)(ScmCPort cport, const char *str); > > size_t (*ndisplay)(ScmCPort cport, size_t size, const char *str); > > ndisplay は要らないと思う。Port の許容量は無制限が普通 (ですよね?)。 これはnull-terminatedでない文字列を渡すために入れました。port側 の都合ではなくcaller側の都合です。 これにより"hoge %d fuga"のような文字列をコピーする事なく"hoge " "32" " fuga"のように分割して渡す事ができるようになります。本当は SigSchemeからprintf自体を排除する方がいいんですが、まだそこまで 徹底しない方がいいでしょう。 …というような事はちゃんと説明しとかないといかんですね。 突っ込み入るような気はしていたので。 ------------------------------- ヤマケン yamak****@bp*****