[Anthy-dev 2509] Re: r5rs: portの抽象化

Back to archive index

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*****



Anthy-dev メーリングリストの案内
Back to archive index