tagged pointer など

vector 周りのバグを修正。tagged pointer を理解したと思っていたのに実装するときには間違っていた、というか忘れていた。しかも、 vector-ref と vector-set! の両方で間違えていたので何とか動いてしまっていて、気付くのが遅れた。恥ずかしい。改めて頭の整理のためにメモ。以下まだ嘘が混じっているかもしれないので注意。

  • 自作コンパイラもどきではデータは32bit であらわし、32bit の下位 3bit をタグとして用いる。32bit のデータを渡されると、コンパイラはタグの値からそのデータの種類が分かる(ように作る)。
Fixnum: 30-bit fixnum 00
Pair: 29-bit address 001
Vector: 29-bit address 010
Closure: 29-bit address 110
Symbol: 29-bit address 101
String: 29-bit address 011
  • pair に対する car の実装を考えると、まず 1)タグをチェックして pair であることを確認し、2) タグの分を引いて実際に car 部が格納されているアドレス値になおし、3) そのアドレスのデータをロードする。逆に、car 部が格納されているアドレス値の下位3bitは常に0になるようにしなくてはならない。コンスセルは car と cdr だけで作られているので常に可能。
  • vector の場合は、vector-length を自体を保存しておく必要があるので、vector-length + 1の領域が必要になる。ただし、vector-length が偶数のばあい、無駄にはなるが 1word分余計に領域を確保してやらないと、タグがちゃんと機能しない。その際 bit 演算を行うが自信がないので logand とかで書いてちゃんと確認する。
  • closure も vector と似ている。関数ポインタを格納する。今は何でもクロージャにするという手抜き。この場合唯の関数呼び出しでも確保したデータから関数ポインタとりだしてから呼び出す。真面目な処理系は当然このような無駄は行わないようになっている。
  • まだ string, symbol は未実装。string は早めに欲しい。#\n #\e #\w #\l #\i #\n #\e (#\newline の印字)とか一文字ずつ書くのはかっこわるい。