3imp 4.7に書かれているトップレベル変数とプリミティブ関数を実装した.
トップレベル変数
実装方針が2つ挙げられていた.
-
一つ目は,今までの自由変数のようにクロージャ生成時にdisplay closureの中に 全部つっこんでしまう方法. 簡単らしいが,あんまり気が乗らないので却下. これをやっちゃうと,当然すべてのdisplay closureが膨らんでしまうし, いろんな場所から参照されてboxが…の話になってしまう.
-
二つ目は,トップレベル用を自由変数と別に管理する方法. トップレベル変数,自由変数,束縛変数を区別する. これならdisplay closureは小さいままだし,boxもいらない. こっちを採用した.
変更点は,以下のあたり.
-
find-free
- 式xの中に含まれている自由変数を検索する関数. トップレベルかどうかを判定を追加する.
-
compile-lookup
- 変数xと,(ローカル変数のリスト . 自由変数のリスト)を受け取り,変数xが3種類のうちどこに属するかを調べる関数(その後,適切な関数を呼ぶ). ローカル変数 -> 自由変数 -> トップレベルで検索する.
-
collect-free
- クロージャの生成時にdisplay closureにつっこむ自由変数の値を集める関数. display closureにつっこむべき値は,呼び出し元の束縛変数か自由変数のはず.
プリミティブ関数
プリミティブな関数も関数なので,トップレベルにそのクロージャオブジェクトを あらかじめおいておく. 呼び出す場合は,他のクロージャ同様,引数を渡してコールフレームを作ってー…と やっている. 1引数の場合でもわざわざスタックに積んでいるのでもったいない気はするが, 2引数のときに,一方はレジスタでもう一方はスタックでというのは分かりにくいので とりあえずこの方針でいく.
複文
ついでにlambda式で複文をかけるようにした.