YamaKen
yamak****@bp*****
2005年 10月 9日 (日) 12:14:49 JST
At Sat, 8 Oct 2005 17:57:25 -0700, jun.l****@gmail***** wrote: > > On Sat, 08 Oct 2005 10:15:45 +0900 > YamaKen <yamak****@bp*****> wrote: > > > > > struct ScmCPortVTbl { > > > > ScmObj (*type)(ScmCPort cport); /* returns a symbol */ > > ついでに突っ込まれそうなんで説明しておきますが、手動でシンボル > > ('ScmStrPortとか)を割り当てるとユーザ定義のportと衝突する可能性 > > があるので、cons cellを割り当ててそれをIDとした方がよいです。 > > Macro 用の hygienic な symbol を用意することになりそうな予感。 Schemeのコード上でportの実装を識別したい場合があるという事ですか? 私はCレベルでのダウンキャスト向け型情報としか考えてなかったんで すが(get-output-string等で必要)。 > > > > 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に保持するような場合に必要です。 > > そんなもんなんですか。Pipe なんか使ったこと無いのでよくわかりませんが。 すいません。やっぱ3つともcloseにまとめてOKです。pipeについては fork時にread端を閉じるという概念が何か別のものと記憶混濁してたよ うです。混乱させてすいません orz > close_in()/close_out() の pair が close() にできない仕事をするのは > read/write で開いた stream の一方の access だけを切るときだけですが、 > そんな操作はclose(2) からして用意されてなさそうです (当然 stdio にも)。 これはSchemeのportオブジェクトレベルでやっとけば十分でしたね。 close_input_port(ScmObj port) { SCM_PORT_DIRECTION(port) &= ~SCM_PORTDIR_INPUT; if (SCM_PORT_DIRECTION(port) == SCM_PORTDIR_NONE) SCM_PORT_CLOSE(port); /* also frees port->cport */ } > > > > /* input */ > > > > int (*getc)(ScmCPort cport); > > > > int (*peek_char)(ScmCPort cport); > > > > int (*char_readyp)(ScmCPort cport); > > これは get_byte(), peek_byte(), byte_readyp() or number_of_bytes_ready > () にしましょう。Multibyte port を読むとき次の文字が何 bytes 含むかの判 > 定は SigScheme 側で書きたいところです。 その方がいいですね。3つ目の関数名はbytelen_ready()なんてどうでしょ う。 > > > > /* 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側の都合です。 > > ああそうか。了解。display() は strlen() する wrapper 関数にしてもいいか > もしれませんね。 ScmFilePortとScmStrPortの場合は直接libc関数に対応付けた方が効率 的なので分けときたいと思います。他のportを実装するためのデフォル ト実装としてwrapper版display()を用意しとくのはいいと思います。 それから、関数名はget_byte()に合わせてn?put_str()等にした方がい いかも。 ------------------------------- ヤマケン yamak****@bp*****