データ構造について自分メモ (Scm_Error とか云々
ええと、Scm_PrintDefaultErrorHeading() に関する記述を検討する中で微妙な、というかアタマを痛めた部分を控え。
Scm_PrintDefaultErrorHeading() の最初らへんに以下の条件分岐がある
if (SCM_CONDITIONP(e)) {
基本的にこの関数に渡される e は Scm_Error() において Scm_MakeError() で生成されるオブジェクトになっているはず (もしかすると例外があるかも)。
で、SCM_CONDITIONP の定義を見てみるに以下
#define SCM_CONDITIONP(obj) SCM_ISA(obj, SCM_CLASS_CONDITION)
SCM_ISA って何か、というと
/* Check if classof(OBJ) is a subtype of an extended class KLASS */ #define SCM_ISA(obj, klass) (SCM_XTYPEP(obj,klass)||Scm_TypeP(SCM_OBJ(obj),klass))
となってて SCM_CLASS_CONDITION は
#define SCM_CLASS_CONDITION (&Scm_ConditionClass)
で Scm_ConditionClass は以下のマクロで定義されている模様
SCM_DEFINE_BASE_CLASS(Scm_ConditionClass, ScmInstance, NULL, NULL, NULL, Scm_ObjectAllocate, SCM_CLASS_DEFAULT_CPL);
マクロの定義は略しますが、領域のサイズとしては ScmInstance な模様。なんだこれは、と言いつつ一連のマクロ定義などの部分で以下の記述あり
typedef ScmInstance ScmCondition;
ScmInstance は以下のように定義されている
/* A common header for objects whose class is defined in Scheme */ typedef struct ScmInstanceRec { ScmByte *tag; /* private */ ScmObj *slots; /* private */ } ScmInstance;
どちらにしてもこれは ScmError ではない、ので SCM_XTYPEP は偽のはず。おかしいのぅ、と言いつつもう一つの述語な Scm_TypeP() を確認。
int Scm_SubtypeP(ScmClass *sub, ScmClass *type) { ScmClass **p; if (sub == type) return TRUE; p = sub->cpa; while (*p) { if (*p++ == type) return TRUE; } return FALSE; } int Scm_TypeP(ScmObj obj, ScmClass *type) { return Scm_SubtypeP(Scm_ClassOf(obj), type); }
絶対 TRUE が戻りそうにないぢゃん、と言いつつネバってみよう、と言いつつ ScmError 関連を掘ってみたら以下の定義を発見
typedef ScmMessageCondition ScmError; /* <message-condition> : condition with message. */ typedef struct ScmMessageConditionRec { ScmCondition common; ScmObj message; /* message */ } ScmMessageCondition; SCM_CLASS_DECL(Scm_MessageConditionClass); #define SCM_CLASS_MESSAGE_CONDITION (&Scm_MessageConditionClass) #define SCM_MESSAGE_CONDITION_P(obj) SCM_ISA(obj, SCM_CLASS_MESSAGE_CONDITION) #define SCM_MESSAGE_CONDITION(obj) ((ScmMessageCondition*)(obj))
若干冗長ですが、通常の SCM_OBJ の tag な部分に ScmCondition なオブジェクトな属性がある。ってコトは SCM_CONDITIONP マクロは真を戻してくれるはずなんですが、どうなんでしょうか。
追記
半分以上はカンで書いてますので内容の精度については無保証です。がしかし、一日ネカせて大丈夫そげだったら Reading Gauche 方面に投入予定。
error.c の Scm_MakeError() あたりをきちんと掘り下げてみた方が良さげ。