SICP 読み (385) 5.5 翻訳系
問題 5.51
なんかグズグズです。ヤッてて微妙感満点だし。とりあえず現時点では eq? も eqv? も equal? も同じと見て pair 方面に進めてみる。
以下の方向で
- PairClass と NullClass を使う (ListClass はとりあえずスルー)
- Scm_Cons が実装できないとマクロの試験もへったくれも無い
- ScmPairRec 構造体の attributes って何だろ
多分、心理的に面倒クサイって思ってヤッてるから gdgd なんだろうな。(とほほ
とりあえず Scm_Cons から
ええと手順としては
- new = SCM_NEW(ScmPair) して
- SCM_SET_CAR(new, car) して
- SCM_SET_CDR(new, cdr) して
- new を戻せば OK??
てーコトは SCM_NEW とか SCM_SET_CAR とか SCM_SET_CDR の試験しねぇと駄目だな。一応 SCM_NEW は試験スルーとしても
void test-scheme-SET-CAR(void) { ScmObj obj = SCM_OBJ(SCM_NEW(ScmPair)); SCM_SET_CAR(obj, SCM_MAKE_INT(5)); CU_ASSERT_EQUAL(5, SCM_INT_VALUE(SCM_PAIR(obj)->car)); CU_ASSERT_EQUAL(5, SCM_INT_VALUE(SCM_CAR(obj))); }
みたいな試験はしといた上で Scm_Cons の試験をした方が良いのか。Scm_Cons() ができたら SCM_LIST マクロなんかも試験できそげ。
ちょっと今、集中して何かをヤる態勢になれてないので微妙ッス。こんな下書き書くなら作業ヤレよ、って自分でも思うんですがなんとなく (以下略
続
で、作ってみた。試験が以下 (test-PAIR.c)
#include <CUnit/CUnit.h> #include "gauche.h" void test_gauche_SET_CAR(void) { ScmObj obj = SCM_OBJ(SCM_NEW(ScmPair)); SCM_SET_CAR(obj, SCM_MAKE_INT(5)); CU_ASSERT_EQUAL(5, SCM_INT_VALUE(SCM_PAIR(obj)->car)); CU_ASSERT_EQUAL(5, SCM_INT_VALUE(SCM_CAR(obj))); } void test_gauche_SET_CDR(void) { ScmObj obj = SCM_OBJ(SCM_NEW(ScmPair)); SCM_SET_CDR(obj, SCM_MAKE_INT(5)); CU_ASSERT_EQUAL(5, SCM_INT_VALUE(SCM_PAIR(obj)->cdr)); CU_ASSERT_EQUAL(5, SCM_INT_VALUE(SCM_CDR(obj))); } void test_scheme_Scm_Cons(void) { ScmObj obj = Scm_Cons(SCM_MAKE_INT(1), SCM_MAKE_INT(2)); CU_ASSERT_EQUAL(1, SCM_INT_VALUE(SCM_CAR(obj))); CU_ASSERT_EQUAL(2, SCM_INT_VALUE(SCM_CDR(obj))); }
Scm_Cons() の定義が書いてある pair.c が以下なカンジ
#include "gauche.h" SCM_DEFCLASS(Scm_PairClass, "Pair", NULL, NULL); ScmObj Scm_Cons(ScmObj car, ScmObj cdr) { ScmObj obj = SCM_OBJ(SCM_NEW(ScmPair)); SCM_SET_CAR(obj, car); SCM_SET_CDR(obj, cdr); SCM_PAIR_ATTR(obj) = NULL; return obj; }
cons が動いてるのが確認できたら色々やる事は沢山ありそげ。
- SCM_PAIRP マクロの試験
- SCM_CAAR, SCM_CADR, SCM_CDAR, SCM_CDDR マクロの試験
- SCM_LISTP マクロ (これは一体何なのか、を未だ理解できてません
- SCM_FOR_EACH マクロの試験
- SCM_APPEND1 マクロの試験
- SCM_APPEND マクロの試験
- SCM_LIST の関係者な方々の試験
- Scm_List() 関数の定義と試験
- Scm_PairP() 関数の定義と試験
- car/cdr 関連な関数の定義と試験
- Scm_Length(), Scm_Append(), Scm_ListTail(), Scm_ListRef() 関数の定義と試験
- memq/assq 関連
- Scm_NullP(), Scm_ListP() 関連
帰宅後
Scm_Cons() の試験の修正含め、いくつか試験を書いてみた。
void test_scheme_Scm_Cons(void) { ScmObj obj = Scm_Cons(SCM_MAKE_INT(1), SCM_MAKE_INT(2)); CU_ASSERT_EQUAL(1, SCM_INT_VALUE(SCM_CAR(obj))); CU_ASSERT_EQUAL(2, SCM_INT_VALUE(SCM_CDR(obj))); CU_ASSERT_EQUAL(NULL, SCM_PAIR_ATTR(obj)); } void test_gauche_SCM_PAIRP(void) { ScmObj obj = Scm_Cons(SCM_MAKE_INT(1), SCM_MAKE_INT(2)); CU_ASSERT_TRUE(SCM_PAIRP(obj)); } void test_gauche_SCM_CAAR(void) { ScmObj obj1 = Scm_Cons(SCM_MAKE_INT(1), SCM_MAKE_INT(2)); ScmObj obj2 = Scm_Cons(SCM_MAKE_INT(3), SCM_MAKE_INT(4)); ScmObj obj3 = Scm_Cons(obj1, obj2); CU_ASSERT_EQUAL(1, SCM_INT_VALUE(SCM_CAAR(obj3))); } void test_gauche_SCM_CDAR(void) { ScmObj obj1 = Scm_Cons(SCM_MAKE_INT(1), SCM_MAKE_INT(2)); ScmObj obj2 = Scm_Cons(SCM_MAKE_INT(3), SCM_MAKE_INT(4)); ScmObj obj3 = Scm_Cons(obj1, obj2); CU_ASSERT_EQUAL(2, SCM_INT_VALUE(SCM_CDAR(obj3))); } void test_gauche_SCM_CADR(void) { ScmObj obj1 = Scm_Cons(SCM_MAKE_INT(1), SCM_MAKE_INT(2)); ScmObj obj2 = Scm_Cons(SCM_MAKE_INT(3), SCM_MAKE_INT(4)); ScmObj obj3 = Scm_Cons(obj1, obj2); CU_ASSERT_EQUAL(3, SCM_INT_VALUE(SCM_CADR(obj3))); } void test_gauche_SCM_CDDR(void) { ScmObj obj1 = Scm_Cons(SCM_MAKE_INT(1), SCM_MAKE_INT(2)); ScmObj obj2 = Scm_Cons(SCM_MAKE_INT(3), SCM_MAKE_INT(4)); ScmObj obj3 = Scm_Cons(obj1, obj2); CU_ASSERT_EQUAL(4, SCM_INT_VALUE(SCM_CDDR(obj3))); } void test_gauche_SCM_FOR_EACH(void) { int i = 0; ScmObj tmp; ScmObj obj1 = Scm_Cons(SCM_MAKE_INT(2), SCM_NIL); ScmObj obj2 = Scm_Cons(SCM_MAKE_INT(1), obj1); ScmObj obj3 = Scm_Cons(SCM_MAKE_INT(0), obj2); SCM_FOR_EACH(tmp, obj3) { CU_ASSERT_EQUAL(i, SCM_INT_VALUE(SCM_CAR(tmp))); i++; } }
あと、Scm_Cons() でクラス設定なソレを忘れてた。
ScmObj Scm_Cons(ScmObj car, ScmObj cdr) { ScmObj obj = SCM_OBJ(SCM_NEW(ScmPair)); SCM_SET_CLASS(obj, SCM_CLASS_PAIR); SCM_SET_CAR(obj, car); SCM_SET_CDR(obj, cdr); SCM_PAIR_ATTR(obj) = NULL; return obj; }
やはり若干 Makefile が微妙らしいんですが、箇所が特定できとりません。