SICP 読み (384) 5.5 翻訳系

昨晩結構呑んでしまった。

問題 5.51

試験を以下のように修正。自宅な環境は 4tab なので良い。~/.emacs 見てみたら以下のような定義になっている。

(defun my-c-mode-common-hook ()
;   (c-set-style "linux") (setq indent-tabs-mode t) ;linux 式がいいとき
;      /usr/src/linux/Documentation/CodingStyle 参照
;   (c-set-style "k&r") ;k&r式がいいときはこれを有効にする
;   (c-set-style "gnu") ;デフォルトの設定
  (c-set-style "bsd")
  (setq tab-width 4)
  (setq c-basic-offset tab-width)
 )
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

自分メモは良いとして試験を以下のように修正。とりあえず eq? のみ

#include <CUnit/CUnit.h>

#include "gauche.h"

void test_scheme_Scm_EqP(void)
{
    int i, j;
    ScmObj primitive_tbl [] = { SCM_TRUE,
                                SCM_FALSE,
                                SCM_NIL,
                                SCM_EOF,
                                SCM_UNDEFINED,
                                SCM_UNBOUND };

    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_TRUE, SCM_TRUE));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_FALSE, SCM_FALSE));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_NIL, SCM_NIL));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_EOF, SCM_EOF));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_UNDEFINED, SCM_UNDEFINED));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_UNBOUND, SCM_UNBOUND));
  
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_MAKE_INT(0), SCM_MAKE_INT(0)));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_MAKE_CHAR('a'), SCM_MAKE_CHAR('a')));

    for(i = 0; i < 6; i++) {
        for(j = 0; j < 6; j++) {
            if (i == j) continue;
                CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(primitive_tbl[i], primitive_tbl[j]));
        }
    }

    CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_TRUE, SCM_MAKE_INT(0)));
    CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_TRUE, SCM_MAKE_CHAR('a')));

    CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_MAKE_INT(0), SCM_MAKE_INT(1)));
    CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_MAKE_CHAR('a'), 
                                       SCM_MAKE_CHAR('b')));

    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_OBJ(SCM_CLASS_BOOL), 
                                      SCM_OBJ(SCM_CLASS_BOOL)));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_OBJ(SCM_CLASS_CHAR), 
                                      SCM_OBJ(SCM_CLASS_CHAR)));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_OBJ(SCM_CLASS_CLASS), 
                                      SCM_OBJ(SCM_CLASS_CLASS)));
    CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_OBJ(SCM_CLASS_UNKNOWN), 
                                      SCM_OBJ(SCM_CLASS_UNKNOWN)));

    {
        int i, j;
        ScmObj classTbl [] = { SCM_CLASS_BOOL,
                               SCM_CLASS_CHAR,
                               SCM_CLASS_UNKNOWN };
        for(i = 0; i < 3; i++) {
            for(j = 0; j < 3; j++) {
                if (i == j) continue;
                CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_OBJ(classTbl[i]),
                                                   SCM_OBJ(classTbl[j])));
            }
        }
    }
}

うーん。tab をはてながどう解釈するか微妙だけどこのままコピペでいってみるか (謎
ちなみに実装は以下なので試験にはパスしません。

#include "gauche.h"

ScmObj Scm_EqP(ScmObj x, ScmObj y)
{
  return NULL;
}

ScmObj Scm_EqvP(ScmObj x, ScmObj y)
{
  return NULL;
}

ScmObj Scm_EqualP(ScmObj x, ScmObj y)
{
  return NULL;
}

それにしてもどうしたものやら。試験も今後リスト云々が出てきたら手を入れないと駄目な模様。

実装を以下にしたのですが、試験にパスしなかった。で、make clean したら一つを残してパスした。これは Makefile が微妙なんだろうな。

ScmObj Scm_EqP(ScmObj x, ScmObj y)
{
  if (!SCM_PTRP(x)) {
	  if (!SCM_PTRP(y)) {
		  return SCM_MAKE_BOOL(SCM_EQ(x, y));
	  } else {
		  return SCM_FALSE;
	  }
  }

  if (SCM_XTYPEP(x, SCM_CLASS_OF(y))) {
	  if (SCM_CLASSP(x)) {
		  if (SCM_CLASSP(y)) {
			  return SCM_MAKE_BOOL(SCM_EQ(x, y));
		  }
	  }
  }

  return SCM_FALSE;
}

微妙。
ちなみにパスしなかったのは以下の試験。

        CU_ASSERT_EQUAL(SCM_TRUE, Scm_EqP(SCM_OBJ(SCM_CLASS_BOOL), 
                                          SCM_OBJ(SCM_CLASS_BOOL)));

色んな意味で進捗がナニなので gauche-0.1 なソレを流用するかな (キレ気味