ScmObj * as lvalue
出かける前にちょっと時間があるのでこれに返事。
SCM_NULLにdummy cellが割り当てられている事も仮定していて、ループの最初でそのcdr部にゴミが入る。
については誤解です。ret_tail には SCM_NULL のアドレスではなく、SCM_NULL を代入した変数 のアドレスが入ります。
で、私は別に SET_CDR() を使うことに不満を感じているわけではありません。そうではなくて、ScmObjInternal の car slot と cdr slot に違う意味を与えるのは果たして worthwhile だろうかと思っているんです。つまり、(例えば) 0xffe3 という数値が、置いてある位置によって違うオブジェクトを指すように解釈されるようなモデルです。コードで言うと、
ScmObj pair = CONS (0xffe3, 0xffe3); /* とすると… */ TYPE (CAR (pair)) == TYPE (CDR (pair)); /* とか、*/ EQ (CAR (pair), CDR (pair)); /* が偽だったりするかも知れない。*/
もし違いが生じないのであれば、別に与えられた ScmObj* の指す先が car slot だろうが cdr slot だろうが、(symbol の) vcell slot だろうが、SET() だけで抽象化してしまえる。そうすると generalized set! も自然に扱える、というか内部で generalized set! を使える。
こう書いた方がわかりやすいかな:
#define COPY_GCBIT(a, b) /* b から a に GC 情報などをコピる bit 演算 */ #define SET(cell, val) (*(cell) = (val), COPY_GCBIT(*(cell), (val))) #define SET_CDR(pair, val) SET(&CDR(pair), (val))
でも cache coloring はやりたいと思ってましたが実質できるだろうかどうだろうかと思っていたので、何か心積もりがあるなら楽しみにしてます(人任せかい)。
ちなみに list を配列のように並べて確保するというのは特許がどうとかって話をどこかで読んだ覚えがあるんですが、その辺大丈夫でしょうか。あれは hardware で実現するときだっけか。
最後に closure call の簡略化ですが、端的にはこういうことです。lookup_frame () 以外では端折ってるコードはエラー処理と変数宣言だけです。
ScmObj call_closure (ScmObj proc, ScmObj actuals, ScmObj env, /* など */) { ScmObj formals = CAR (CLOSURE_EXP (proc)); ScmObj actuals = args; env = extend_environment (formals, actuals, env); return ScmExp_begin (proc, args, eval_state) } ScmObj extend_environment (ScmObj formals, ScmObj actuals, ScmObj env) { ScmObj new_frame = CONS (formals, actuals); return CONS (new_frame, env); } ScmObj *lookup_frame (ScmObj var, ScmObj frame) { ScmObj formals = CAR (frame); ScmObj *actuals = &CDR (frame); for ( ;CONSP (formals); formals = CDR (formals), actuals = &CDR(*actuals)) search (); if (! found()) return NULL; if (SYMBOLP (formals) && EQ (formals, var)) return actuals; return &CAR (actuals); }