むむ

微妙な英語力で guile のドキュメント読んでたりします。面白かったのでいくつかメモを。今目を通し中なのは Appendix A Data Representation in Guile なんですが、ここに Ruby のオブジェクトの表現なソレに良く似たソレがあるのを発見しとります。
A.1.3 Cheaper Pairs の節からコードを引用。

     enum type { string, vector, ... };
     
     typedef struct value *SCM;
     
     struct value {
       enum type type;
       union {
         struct { int length; char *elts; } string;
         struct { int length; SCM  *elts; } vector;
         ...
       } value;
     };
     
     struct pair {
       SCM car, cdr;
     };
     
     #define POINTER_P(x) (((int) (x) & 3) == 0)
     
     #define INTEGER_P(x)  (((int) (x) & 3) == 1)
     #define GET_INTEGER(x)  ((int) (x) >> 2)
     #define MAKE_INTEGER(x) ((SCM) (((x) << 2) | 1))
     
     #define PAIR_P(x) (((int) (x) & 3) == 2)
     #define GET_PAIR(x) ((struct pair *) ((int) (x) & ~3))

境界整列なソレを逆手に取って、下位 2 ビットの状態で型の区分けとその値をナニ。特にペアのソレが格好良い。
このあたりをきちんと理解してソース読むと良さげ。なので微妙な英語力でもう少し読み進めてみる予定。色々な意味での微妙さ加減からなかなか進捗しません。(とほほほ

追記

なんかカゼひいたカンジ。このエントリも体調不良からか、いくつかメモをと書きつつソース貼ってるだけだし。頑張って述語なマクロだけでもメモっておこう。

  • 末尾 2 ビットが 00 の場合はポインタと見做す (POINTER_P が述語なマクロ)
  • 末尾 2 ビットが 01 の場合は Int と見做す (INTEGER_P が述語なマクロ)
  • 末尾 2 ビットが 10 の場合はペアを差すポインタと見做す (PAIR_P が述語なマクロ)

int の場合は右に 2 ビットシフトしてやれば良いし、ペアの場合は末尾 2 ビットを 00 にしてやれば良い、という事になっている模様。たしか Ruby では右にシフトするナニをもう少し丁寧にやっていた記憶あり。