データ型の表現
Perlのリスト(配列)の表現とか標準関数の実装が気になったので、ちょっとPerlのコードを読むことにしました。
まず処理系で使われる基本的なデータ構造を把握する必要があると思ったので、ext以下の標準ライブラリを見る。
なんか、AV *hogheogeとかSV *とかGV*とかHV*とかがあって、多分 ArrayValueとかScalarValueとかGlobValueとかHashValueのことかなあと思って定義を探すと(etags便利!!)、perl.hに
typedef struct av AV;
というのがあって、struct av は sv.hに定義がある
struct av { XPVAV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ };
他にもstruct ?vというのが沢山あって、XPVAVのところが別のものになっている。
たぶんsv.hにあるということは、スカラ値を表すものだと思われるので、struct av ってのは Arrayへのリファレンス?なのか?
そうするとXPVAVがArrayの実体で、refcntはリファレンスカウンタで、flagsは型を表すフラグだろう。(AVかHVか、ということがflagsに入れてある……のかな)
コメントによると、SvTYPEマクロで型を見てねということなので、その辺りを見ると、flagsにはけっこういろんな情報が入っているみたい。
// これsv.hの中 #define SVTYPEMASK 0xff #define SvTYPE(sv) ((sv)->sv_flags & SVTYPEMASK) #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= mt || sv_upgrade(sv, mt)) #define SVs_PADBUSY 0x00000100 /* reserved for tmp or my already */ #define SVs_PADTMP 0x00000200 /* in use as tmp */ #define SVs_PADMY 0x00000400 /* in use a "my" variable */ #define SVs_TEMP 0x00000800 /* string is stealable? */ #define SVs_OBJECT 0x00001000 /* is "blessed" */ #define SVs_GMG 0x00002000 /* has magical get method */ #define SVs_SMG 0x00004000 /* has magical set method */ #define SVs_RMG 0x00008000 /* has random magical methods */ #define SVf_IOK 0x00010000 /* has valid public integer value */ #define SVf_NOK 0x00020000 /* has valid public numeric value */ #define SVf_POK 0x00040000 /* has valid public pointer value */ #define SVf_ROK 0x00080000 /* has a valid reference pointer */ #define SVf_FAKE 0x00100000 /* glob or lexical is just a copy */ #define SVf_OOK 0x00200000 /* has valid offset value */ #define SVf_BREAK 0x00400000 /* refcnt is artificially low - used * by SV's in final arena cleanup */ #define SVf_READONLY 0x00800000 /* may not be modified */ #define SVp_IOK 0x01000000 /* has valid non-public integer value */ #define SVp_NOK 0x02000000 /* has valid non-public numeric value */ #define SVp_POK 0x04000000 /* has valid non-public pointer value */ #define SVp_SCREAM 0x08000000 /* has been studied? */ #define SVf_UTF8 0x20000000 /* SvPV is UTF-8 encoded */ #define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE) #define SVf_OK (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \ SVp_IOK|SVp_NOK|SVp_POK) #define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */ #define PRIVSHIFT 8 /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */ /* Some private flags. */ /* SVpad_OUR may be set on SVt_PV{NV,MG,GV} types */ #define SVpad_OUR 0x80000000 /* pad name is "our" instead of "my" */ #define SVpad_TYPED 0x40000000 /* Typed Lexical */ #define SVf_IVisUV 0x80000000 /* use XPVUV instead of XPVIV */ #define SVpfm_COMPILED 0x80000000 /* FORMLINE is compiled */ #define SVpbm_VALID 0x80000000 #define SVpbm_TAIL 0x40000000 #define SVrepl_EVAL 0x40000000 /* Replacement part of s///e */ #define SVphv_CLONEABLE 0x08000000 /* for stashes: clone its objects */ #define SVphv_REHASH 0x10000000 /* HV is recalculating hash values */ #define SVphv_SHAREKEYS 0x20000000 /* keys live on shared string table */ #define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ #define SVphv_HASKFLAGS 0x80000000 /* keys have flag byte after hash */ #define SVprv_WEAKREF 0x80000000 /* Weak reference */
SVの後のp,s,fの文字が何を表しているのか謎だけど、今は気にしないことにする。
ふと思いたって grep grep *.c すると、grepの定義らしきものがop.cに見つかった
OP * Perl_ck_grep(pTHX_ OP *o) { LOGOP *gwop; OP *kid; const OPCODE type = o->op_type == OP_GREPSTART ? OP_GREPWHILE : OP_MAPWHILE; /* よくわからないので略 */ return (OP*)gwop; }
OPが謎なので意味がわからない。抽象構文木みたいなもの? list とか scalar という関数があったけどこれもOPを操作する関数だった。
何もまとまってないけどとりあえずここまで。