memo
メモ。
どこかにバグのある継続。
実行ステップ: ################################################################ TEST> (test-secd-eval '(+ *1 ;; comp call/cc (:LDC 7 :+) code: (:LDC 100 :NIL :LDF (:LDCT (:LDC 7 :+) :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP . #1=(:RTN)) :AP :LDC 7 :+ . #1#) :AP :+ :STOP) == 0. 初期状態 == S: S0 E: E0 C: (:LDC 100 :NIL :LDF (:LDCT (:LDC 7 :+) :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) :AP :+ :STOP . C0) D: D0 == 1. :LDC 100 定数100 をスタックに積む。 == S: ( 100 . S0) E: E0 C: (:NIL :LDF (:LDCT (:LDC 7 :+) :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) :AP :+ :STOP . C0) D: D0 == 2. :NIL NIL をスタックに積む。== S: ( NIL 100 . S0) E: E0 C: (:LDF (:LDCT (:LDC 7 :+) :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) :AP :+ :STOP . C0) D: D0 == 3. :LDF クロージャを生成し、スタックに積む。== ここで、関数本体 fbody は (:LDCT (:LDC 7 :+) :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) である。 クロージャ(fbody . e0) の後ろの NIL は、2. で作られた NIL。要確認! S: ( ( :CLOS (:LDCT (:LDC 7 :+) :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) . E0) NIL 100 . S0) E: E0 C: (:AP :+ :STOP . C0) D: D0 == 4. :AP クロージャを適用する。 スタックからクロージャを取りだし、実行環境を作り、 DUMP スタックに 保存する。 ここで、 S の NIL は空の意。 S: NIL E: (NIL . E0) C: (:LDCT (:LDC 7 :+) :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) D: *2 . s) e c d ) ここで、 c' = (:LDC 7 :+)、 c = ( :LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) S: ( ( ( :CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0))) E: (NIL . E0) C: (:LDF (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) :AP :LDC 7 :+ :RTN) D: ( ( 100 . S0) E0 (:+ :STOP . C0) . D0) == 6. :LDF クロージャを生成し、スタックに積む ( s e (:LDF |c'| . c) d -> *3 NIL . E0) C: (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) D: (NIL (NIL . E0) (:LDC 7 :+ :RTN) (100 . S0) E0 (:+ :STOP . C0) . D0) == 8. S: ( NIL) E: ( ( (:CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0)) NIL . E0) C: (:LDC 10 :CONS :LD (1 . 1) :AP :RTN) D: (NIL (NIL . E0) (:LDC 7 :+ :RTN) (100 . S0) E0 (:+ :STOP . C0) . D0) == 9. S: (10 NIL) E: ( ( (:CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0)) NIL . E0) C: (:CONS :LD (1 . 1) :AP :RTN) D: (NIL (NIL . E0) (:LDC 7 :+ :RTN) (100 . S0) E0 (:+ :STOP . C0) . D0) == 10. S: ( ( 10 ) ) E: (((:CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0)) NIL . E0) C: (:LD (1 . 1) :AP :RTN) D: (NIL (NIL . E0) (:LDC 7 :+ :RTN) (100 . S0) E0 (:+ :STOP . C0) . D0) == 11. S: ( ( :CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0) (10)) E: (((:CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0)) NIL . E0) C: (:AP :RTN) D: (NIL (NIL . E0) (:LDC 7 :+ :RTN) (100 . S0) E0 (:+ :STOP . C0) . D0) == 12. S: ( 10) E: (NIL . E0) C: (:LDC 7 :+) D: ((100 . S0) E0 (:+ :STOP . C0) . D0) == 13. S: ( 7 10) E: (NIL . E0) C: (:+) D: ((100 . S0) E0 (:+ :STOP . C0) . D0) == 14. == S: (17) E: (NIL . E0) C: NIL D: ((100 . S0) E0 (:+ :STOP . C0) . D0) 17 TEST> ################################################################
*1:lambda () (+ 7 (call/cc (lambda (c) (c 10)))))) 100
*2:100 . S0) E0 (:+ :STOP . C0) . D0) == 5. :LDCT c' . c 継続。継続オブジェクト (:cont s e c' . d) を生成し、スタックに積む ( s e (:LDCT |c'| . c) d -> ( ( (:cont s e |c'| . d
*3::clos |c'| . e) . s) e c d ) ここで c' = (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN), c = (:AP :LDC 7 :+ :RTN) クロージャ = (:CLOS (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) NIL . E0) S: ( ( :CLOS (:NIL :LDC 10 :CONS :LD (1 . 1) :AP :RTN) NIL . E0) ((:CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0))) E: (NIL . E0) C: (:AP :LDC 7 :+ :RTN) D: ((100 . S0) E0 (:+ :STOP . C0) . D0) == 7. :AP クロージャを適用する。 S: NIL E: ( ( (:CONT NIL (NIL . E0) (:LDC 7 :+) (100 . S0) E0 (:+ :STOP . C0) . D0