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