throw_cont_calculate_handlers() 手続き (2)

とか dynamic-wind とか。あるいは throw_cont_body() 手続きとか。
とりあえず handlers の扱いについてメモ。長いので引用してなかったみたいなんですが、R5RS によれば (dynamic-wind before thunk after) で以下に要約

  • thunk の中で補足した継続が起動された時点で thunk の呼び出しの動的範囲に入る
  • thunk 実行中にその範囲外で補足した継続が起動された時点で thunk の呼び出しの動的範囲を抜ける
  • dynamic-wind がネストしていた時に 2 つめの thunk の中でその範囲外で補足した継続が起動された場合、2 つめ (内側) の after が呼び出されて、1 つめ (外側) の after が呼び出される (はず)
  • ネストした dynamic-wind の 2 つめの thunk の中で補足した継続が起動された場合、1 つめ (外側) の before が呼び出された後に 2 つめ (内側) の before が呼び出される
  • 継続の起動によって before と after の両方が呼び出される形になった場合には after の呼び出しが優先される

要約がビンゴかダウトかは不明ですが、R5RS の dynamic-wind の項に記述されている事項は throw_cont_calculate_handlers() 手続きの記述にぴったりハマります。

  • before (ep->handlers) は reverse
  • まず after (vm->handlers) からリストに append される
    • SCM_APPEND1 は追加する cons を末端に置きます
  • after は内側から順にリストに置かれる
  • after の処理が終わった時点で before の処理
    • 順番的には after -> before の順で呼び出される

要約が要約になってないので

実例でナニ。まず thunk の中で他所で補足された継続が起動されるケース。

(dynamic-wind
  (before)
  ((lambda () (cont)))
  (after))

cont は上記の通り、外部で補足された継続 (別の dynamic-wind の thunk の中で補足されたものではない事にします)。この時点では vm->handlers に ((before . after)) なリストが格納されてます。ep->handlers は基本空リスト。
という事で throw_cont_calculate_handlers() のソースによれば戻されるリストは ((after)) になるのでしょうか。この場合は after が呼び出された後は継続が起動される。
逆に外部で補足された継続が起動される場合は ep->handlers は基本空リストで vm->handlers に ((before . after)) なナニ。

ネストするケース

例えば

(dynamic-wind
    (before1)
    (thunk1)        ;; cont に継続を格納
    (after1))

の thunk1 で補足された継続を

(dynamic-wind
    (before2)
    ((lambda () (dynamic-wind
		    (before3)
		    ((lambda () (cont)))
		    (after3))))
    (after2))

みたいなカンジだった場合、R5RS によれば

  • after3
  • after2
  • before1

して継続の実行開始なはず。このケースだと throw_cont_calculate_handlers() から戻るリストは

((after3 (before2 after2)) (after2) (before0))

になるのかなぁ。一応確認。

gosh> (define l '((after3 (before2 after2)) (after2) (before0)))
l
gosh> (caar l)
after3
gosh> (cdar l)
((before2 after2))
gosh> (cdr l)
((after2) (before0))
gosh> (caar (cdr l))
after2
gosh> (cdar (cdr l))
()
gosh> (caar (cdr (cdr l)))
before0
gosh> (cdar (cdr (cdr l)))
()
gosh> 

一応なんとかなってる模様。逆のケースとか before と after 混在なナニが確認したいんですが時間切れ。