SICP 読み (390) 5.5 翻訳系

なんか知らんがマクロを使うと意外に簡単だった。
以下、car だの cdr だのの実装ッス

ScmObj Scm_Car(ScmObj obj)
{
	return SCM_CAR(obj);
}

ScmObj Scm_Cdr(ScmObj obj)
{
	return SCM_CDR(obj);
}

ScmObj Scm_Caar(ScmObj obj)
{
	return SCM_CAAR(obj);
}

ScmObj Scm_Cadr(ScmObj obj)
{
	return SCM_CADR(obj);
}

ScmObj Scm_Cdar(ScmObj obj)
{
	return SCM_CDAR(obj);
}

ScmObj Scm_Cddr(ScmObj obj)
{
	return SCM_CDDR(obj);
}

ScmObj Scm_Caaar(ScmObj obj)
{
	return SCM_CAR(SCM_CAAR(obj));
}

ScmObj Scm_Caadr(ScmObj obj)
{
	return SCM_CAR(SCM_CADR(obj));
}

ScmObj Scm_Cadar(ScmObj obj)
{
	return SCM_CAR(SCM_CDAR(obj));
}

ScmObj Scm_Caddr(ScmObj obj)
{
	return SCM_CAR(SCM_CDDR(obj));
}

ScmObj Scm_Cdaar(ScmObj obj)
{
	return SCM_CDR(SCM_CAAR(obj));
}

ScmObj Scm_Cdadr(ScmObj obj)
{
	return SCM_CDR(SCM_CADR(obj));
}

ScmObj Scm_Cddar(ScmObj obj)
{
	return SCM_CDR(SCM_CDAR(obj));
}

ScmObj Scm_Cdddr(ScmObj obj)
{
	return SCM_CDR(SCM_CDDR(obj));
}

ScmObj Scm_Caaaar(ScmObj obj)
{
	return SCM_CAAR(SCM_CAAR(obj));
}

ScmObj Scm_Caaadr(ScmObj obj)
{
	return SCM_CAAR(SCM_CADR(obj));
}

ScmObj Scm_Caadar(ScmObj obj)
{
	return SCM_CAAR(SCM_CDAR(obj));
}

ScmObj Scm_Caaddr(ScmObj obj)
{
	return SCM_CAAR(SCM_CDDR(obj));
}

ScmObj Scm_Cadaar(ScmObj obj)
{
	return SCM_CADR(SCM_CAAR(obj));
}

ScmObj Scm_Cadadr(ScmObj obj)
{
	return SCM_CADR(SCM_CADR(obj));
}

ScmObj Scm_Caddar(ScmObj obj)
{
	return SCM_CADR(SCM_CDAR(obj));
}

ScmObj Scm_Cadddr(ScmObj obj)
{
	return SCM_CADR(SCM_CDDR(obj));
}

ScmObj Scm_Cdaaar(ScmObj obj)
{
	return SCM_CDAR(SCM_CAAR(obj));
}

ScmObj Scm_Cdaadr(ScmObj obj)
{
	return SCM_CDAR(SCM_CADR(obj));
}

ScmObj Scm_Cdadar(ScmObj obj)
{
	return SCM_CDAR(SCM_CDAR(obj));
}

ScmObj Scm_Cdaddr(ScmObj obj)
{
	return SCM_CDAR(SCM_CDDR(obj));
}

ScmObj Scm_Cddaar(ScmObj obj)
{
	return SCM_CDDR(SCM_CAAR(obj));
}

ScmObj Scm_Cddadr(ScmObj obj)
{
	return SCM_CDDR(SCM_CADR(obj));
}

ScmObj Scm_Cdddar(ScmObj obj)
{
	return SCM_CDDR(SCM_CDAR(obj));
}

ScmObj Scm_Cddddr(ScmObj obj)
{
	return SCM_CDDR(SCM_CDDR(obj));
}

次は ...

というコトで空き時間で Scm_Length() 対応。試験はちょっと工夫して以下

void test_scheme_Scm_Length(void)
{
	int i;
	ScmObj obj;

	for(i = 0, obj = SCM_NIL; i < 10; i++, Scm_Cons(SCM_MAKE_INT(i), obj)) {
		CU_ASSERT_EQUAL(i, Scm_Length(obj));
	}
}

今はこんなカンジなので試験にはパスしません。

int Scm_Length(ScmObj obj)
{
	return 0;
}

これは FOR_EACH なマクロを使えば良いのか。

int Scm_Length(ScmObj obj)
{
	int i = 0;
	ScmObj tmp;

	SCM_FOR_EACH(tmp, obj) i++;

	return i;
}

で、試験してみたら通らん。むむむ、とウナリつつ試験のコードに誤りを発見。正しくは

	for(i = 0, obj = SCM_NIL; i < 10; i++, obj = Scm_Cons(SCM_MAKE_INT(i), obj)) {

でした。とほほ。次の CopyList は大変そうなカンジ。

CopyList

うーん。入れ子になったリストは再帰で処理せざるを得ないのかなぁ。って実装考える前に試験か。
で、試験考え中に eq? とか equal? とかがあれば試験が楽な事に思い至る。CopyList の戻りとコピー元は equal? が真で eq? とか eqv? は偽になるんかな。ちょっと手を戻して equivalence なソレを作ってから試験を書いた方が楽そげ。
でも、あのあたり微妙だったのでちょっと気分的には重い。

今日はばたばた

してるなぁ。明日はイベント入ってて現実トウヒは不可能。しかも業務終了後はイベント打ち上げだろうし。(しかもそのイベントにどう関わるか、について現時点でも微妙という妙な事態)
そりゃ良いのですが、上記の eq? とか equal? とかがあれば云々、についてはダウトな事が実装検討時に判明。わしの認識が微妙なのかもしれませんが

  • CopyList の戻りなリストの要素は全てコピー元と値は同じでオブジェクトとして違うモノである必要がある
  • てーコトは eq? は偽で equal? が真になれば良い

あ、やっぱあってるの??でも eq? の処理は中身のチェックを全部やらない方針で検討してるんでやっぱチェックは別な方法使わないと駄目です。equal? は使えるのか。でも実装面倒スギ。でも今の所オブジェクトとして扱う事ができるのは

  • immediate
    • true
    • false
    • nil
    • undefined
    • unbound
  • fixnum
  • character
  • class object (これは表に出てこないから等価述語に盛り込まなくて良い??)
  • pair object

だけなので、それぞれとして同じ値かどうか、を見れば良いのかなぁ。でもこれだけしかないのに処理的には煩雑になりそう。gauche.h に便利マクロがある、とか??
手順としては cdr をめくっていきながら (cdr が pair でなくなったら停止) car について

  • 型が同じか (同じでないとダウト)
  • immediate、fixnum、character ならポインタ値が同じでないとダウト
  • pair だったらポインタ値が同じだとダウト
  • pair の場合は中身 (car と cdr) の検証
  • pair の場合は再帰にせざるを得ない??

という形で良いのかなぁ。微妙なカンジ。