call/cc - Scheme VM のお勉強
(call/cc (lambda (c) 3)) =>(frame () (conti (argument (close (c) (constant 3 (return)) (apply)))))
call/cc を見ていく。
論文には call/cc は closure の特殊な場合だよと書いてあるが分からなかったので処理を追う。
frame は昨日書いた通り、current value rib を空にし、指定された next expression とその時点での env/rib/stack を stack に保存する。
conti では closure を作成する。
closure は (body e vars) のようなリスト構造なのだけど、conti では
- body => ('nuate stackレジスタ 'v)
- e => 空
- vars => (v)
のような closure 。
この後は簡単で accumulator にある、closure を引数に (lambda (c) 3) を apply するだけ。
仮にこの特殊な closure を continuation を apply したらどうなるだろうか?
nuate を見れば答えがある。
nuate は accumulator に v を lookup した結果をセットし、next expression を (return) にセットする。
さらに(ここが重要)nuate の中に保存しておいた stack レジスタで現在の stack レジスタを上書き。
次の VM ループで (return) が発行されて、stack レジスタに保存されている状態に復帰して処理を続ける。
要は conti で next expression などもろもろを closure の中の nuate に封じ込めて、nuate 実行時に復帰させて return する感じ。
この文面だけ見ると、タスクスイッチと変わらない印象を受けるかもしれないけど頭の中に浮かんでいる絵は全然違う。