call/cc - Scheme VM を書く
call/cc を実装。
ヒープベース VM とはちと違う。
- conti で stack を丸ごと保存
- nuate で stack を戻す
- return で戻した stack から復帰
という流れ。
Scheme 版では以下のようなテストが通るようになった。
(test* "call/cc" 4 (evaluate '(call/cc (lambda (c) (c 4))))) (test* "call/cc" 3 (evaluate '((lambda (cont) (if (call/cc (lambda (c) (set! cont c))) (cont #f) 3)) '()))) (test* "call/cc jump" 102 (evaluate '((lambda (cont) (if (call/cc (lambda (c) (set! cont c))) ((lambda () ((lambda () (cont #f) )) )) 102)) '())))
C++ 版でもやることは同じ。
スタックマシンは native スタックではなくヒープに確保した仮想スタックを使うので bottom/top を知るのはとても簡単。
保存も復帰も楽。
Scheme で書く -> C++ に移植はロジックのバグはほぼ Scheme 側で解決されているので開発効率が良いな。