SICP 読み (383) 5.5 翻訳系

問題 5.11

HEAP と CLASS あたりを眺め中。
方向性としては ScmClassRec の print と cpl という属性は使わない、という事なので

SCM_DEFCLASS(Scm_ClassClass, "Class", NULL, NULL);

みたいな感じで良いのかな。あと、現時点で必要と思われるのは

  • Scm_BoolClass
  • Scm_CharClass
  • Scm_ClassClass
  • Scm_UnknownClass

になるはず。
って Scm_ClassClass は上記の式で定義できるのかなぁ。やっぱ Top も必要かも

ScmClass Scm_TopClass = {NULL, "Top", NULL, NULL};

で、

ScmClass Scm_ClassClass = {SCM_CLASS_TOP, "Class", NULL, NULL};

すれば

SCM_DEFINECLASS(Scm_BoolClass, "Bool", NULL, NULL);

な定義が可能、なのかなぁ。そろそろ試験ではないコードが出てきそげなので試験じゃない方の Makefile も修正が必要かも。
んで、Makefile 方面にゲンジツトウヒしそうになるのを止めて検討再開。とりあえず Top も含めた builtin なクラスがあれば HEAP 方面なマクロの試験はできるはず。
と言いつつ割込みが入りながらの作業中にやはり Makefile 方面に手を出してしまう。でも一応上記のクラス定義が入ったコードをコンパイルできたので HEAP なマクロの試験も可能になっているはず。

HEAP と CLASS

試験をしてみた。以下なソレでハマった。

void test_gauche_SCM_CLASS_OF(void)
{
  CU_ASSERT_EQUAL(NULL, SCM_CLASS_OF(Scm_TopClass));
}

コンパイルなエラーメセジが

test-HEAP.c:8: error: cannot convert to a pointer type

みたいなカンジ。ちょっと自己嫌悪。

void test_gauche_SCM_CLASS_OF(void)
{
  CU_ASSERT_EQUAL(NULL, SCM_CLASS_OF(SCM_CLASS_TOP));
}

このためにこのマクロがあったんだ、みたいな?? (とほほほ
一応以下のような試験にはパスしている模様。

void test_gauche_SCM_CLASS_OF(void)
{
  CU_ASSERT_EQUAL(NULL, SCM_CLASS_OF(SCM_CLASS_TOP));
  CU_ASSERT_EQUAL(SCM_CLASS_TOP, SCM_CLASS_OF(SCM_CLASS_CLASS));
  CU_ASSERT_EQUAL(SCM_CLASS_CLASS, SCM_CLASS_OF(SCM_CLASS_BOOL));
  CU_ASSERT_EQUAL(SCM_CLASS_CLASS, SCM_CLASS_OF(SCM_CLASS_CHAR));
  CU_ASSERT_EQUAL(SCM_CLASS_CLASS, SCM_CLASS_OF(SCM_CLASS_UNKNOWN));
}

void test_gauche_SCM_XTYPEP(void)
{
  CU_ASSERT_TRUE(SCM_XTYPEP(SCM_CLASS_CLASS, SCM_CLASS_TOP));
  CU_ASSERT_TRUE(SCM_XTYPEP(SCM_CLASS_BOOL, SCM_CLASS_CLASS));
  CU_ASSERT_TRUE(SCM_XTYPEP(SCM_CLASS_CHAR, SCM_CLASS_CLASS));
  CU_ASSERT_TRUE(SCM_XTYPEP(SCM_CLASS_UNKNOWN, SCM_CLASS_CLASS));
  CU_ASSERT_FALSE(SCM_CLASSP(SCM_CLASS_TOP));
  CU_ASSERT_FALSE(SCM_CLASSP(SCM_CLASS_CLASS));
  CU_ASSERT_TRUE(SCM_CLASSP(SCM_CLASS_BOOL));
  CU_ASSERT_TRUE(SCM_CLASSP(SCM_CLASS_CHAR));
  CU_ASSERT_TRUE(SCM_CLASSP(SCM_CLASS_UNKNOWN));
}

それにしても cunit って見にくい。わしの書き方が微妙なのかなぁ。あと微妙に疑問なのが、Scm_BoolClass とか Scm_CharClass とかなんですがどこで使われるんだろ。
現時点のソースツリーは

$ find
.
./gauche.h
./test
./test/main.c
./test/test-PRIMARY_TAG.c
./test/Makefile
./test/test-CHARACTERS.c
./test/test-FIXNUM.c
./test/schemeTest.h
./test/test-IMMEDIATES.c
./test/test-HEAP.c
./test/test-BOOLEAN.c
./Makefile
./gauche.h.ORG
./class.c
./main.c
$

みたいなカンジ。どっかの時点で再度ソースをサラす予定ですが ...
# gauche.h マワリが終わった時点でも良さげ

そろそろ手続きも書いていく必要あり。ってコトで eq? とか eqv? とか equal? とか書いてみる事に。とは言え現時点では

  • IMMEDIATE OBJECTS
  • CLASS

しかこの世界に存在しない。てーコトは簡単ってコトじゃん、と言いつつ試験から書くか。とゆーコトで書き始めてみたんですが、微妙。

void test_scheme_Scm_EqP(void)
{
  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')));

  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_TRUE, SCM_FALSE));
  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_TRUE, SCM_NIL));
  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_TRUE, SCM_EOF));
  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_TRUE, SCM_UNDEFINED));
  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_TRUE, SCM_UNBOUND));

  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)));
  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_OBJ(SCM_CLASS_BOOL), 
				     SCM_OBJ(SCM_CLASS_CHAR)));
  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_OBJ(SCM_CLASS_BOOL), 
				     SCM_OBJ(SCM_CLASS_CLASS)));
  CU_ASSERT_EQUAL(SCM_FALSE, Scm_EqP(SCM_OBJ(SCM_CLASS_BOOL), 
				     SCM_OBJ(SCM_CLASS_UNKNOWN)));
}

実装はまだ書いてないんですが、それ以前に上記の試験がもう少し何とかならないかと。微妙に嫌になり始めてたりする && 今日夜は勉強できん可能性が大きいので EoPL の練習問題方面にニゲるかも。てーか中身読めよ、って自分でも思うんですが ...