3imp 読んでみる (19)
微妙なソレはスルーで継続を、と言いつつ進みが悪い。
こんなカンジの試験も追加。
(test-section "call/cc") (test* "(compile '((lambda (x) x) (call/cc (lambda (x) x))) '(halt))" '(frame (halt) (frame (argument (close (x) (refer x (return)) (apply))) (conti (argument (close (x) (refer x (return)) (apply)))))) (compile '((lambda (x) x) (call/cc (lambda (x) x))) '(halt))) (test* "(VM '() (compile '((lambda (x) x) (call/cc (lambda (x) x))) '(halt)) '() '() '())" '((nuate ((argument (close (x) (refer x (return)) (apply))) () () ((halt) () () ())) v) () (v)) (VM '() (compile '((lambda (x) x) (call/cc (lambda (x) x))) '(halt)) '() '() '())) (test-end)
とりあえず (lambda (x) x) な手続きに call/cc なソレを渡すと gauche ではどうなるか、というと
gosh> ((lambda (x) x) (call/cc (lambda (x) x))) #<subr continuation> gosh>
それは良いとして conti なインストラクションが何を戻すか、という事ですが
(compile '((lambda (x) x) (call/cc (lambda (x) x))) '(halt))
が戻すのは以下のリスト
'(frame (halt) (frame (argument (close (x) (refer x (return)) (apply))) (conti (argument (close (x) (refer x (return)) (apply))))))
これを VM に渡すとどうなるか、というと
- frame なインストラクションは ((halt) () () ()) という call-frame を stack に格納しつつ next expression に第二引数を置く
- 再び frame なインストラクションなので stack が以下??
((argument (close (x) (refer x (return)) (apply))) () () ((halt) () () ()))
- あと next expression は
(conti (argument (close (x) (refer x (return)) (apply))))
- conti では next expression が
(argument (close (x) (refer x (return)) (apply)))
- accumulator が
((nuate ((argument (close (x) (refer x (return)) (apply))) () () ((halt) () () ())) v) '() (v))
- argument で accumulator が rib に置かれる
- close で accumulator が
((refer x (return)) () (x))
- next expression は apply
- apply でどうなるか、というと
(record (body e vars) ((refer x (return)) () (x)) (VM a body (extend e vars r) '() s))
てーコトは x に束縛されている
((nuate ((argument (close (x) (refer x (return)) (apply))) () () ((halt) () () ())) v) '() (v))
が戻る、と。これを何かに束縛して VM に渡してみないとその後は分からんな。ってか上記のナニは微妙に違うカンジ。何かが微妙にオチてないんですがもう寝ます。