3imp 読んでみる (10)

とりあえず lookup は試験しといた方が良さげ。
って簡単な試験を書いてみたら Compile Error って...
これはおそらく define-syntax が悪いな。ちょっと apply とか return のあたりが微妙なんで整理してみると

(record-case x
  [apply ()
    (record a (body e vars) (VM a body (extend e vars r) '() s))]

みたいな形になっている。body って何だよ、という話もあるんですが ...
とりあえず現時点での定義では上記の式は

(if (eq? (car x) 'apply)
    (record () () (record a (body e vars) (VM a body (extend e vars r) '() s))))

で then なブロックは

(apply (lambda () 
	 (record a (body e vars) (VM a body (extend e vars r) '() s)))
       ())

一枚カワを剥いで record 置き換え、って accumulator に束縛されてるソレは何だっけ??

整理

直前エントリな記述では

(compile '(p 1 2) '(halt))

(frame (halt) (constant 2 (argument (constant 1 (argument (refer p (apply)))))))

を出力。evaluate な手続き定義によれば next expression のみセットされて VM 呼び出しなので追い掛ける事はできるかな。

  • 最初は frame なブロックで
    • ((halt) () () ()) が current stack に
    • next expression に (constant 2 ( ... が置かれて VM 呼び出し
  • 次は constant なブロックで 2 が accumulator に置かれて
  • 次の argument なブロックで rib に accumulator を cons して (2) になる
  • 次の constant なブロックで 1 が accumulator に置かれて
  • 次の argument なブロックで rib に accumulator を cons して (1 2) になる
  • 次の refer で p の束縛を accumulator に置いて
  • apply

という事は apply では accumulator に手続きオブジェクトがあって渡す引数は rib にある、という事になる (??)
ちょっと record の定義 (27p) に戻って確認が必要かなぁ。あと、_手続きオブジェクト_って簡単に書いてるけど、lambda なソレの方が良さげ? SICP な評価機式の primitive なソレはどうヤレば良いのかなぁ。

手動展開

(compile ((lambda (x y) (+ x y)) 1 2) '(halt))

が吐き出すリストは

(frame (halt) 
       (constant 
	2 
	(argument 
	 (constant 
	  1 
	  (argument 
	   (close (x y) 
		  (refer 
		   y 
		   (refer 
		    x 
		    (argument (refer + (return)))))
		  (return)))))))

あら、apply が無い。これは間違いだな。最後のソレが apply か。

(frame (halt) 
       (constant 
	2 
	(argument 
	 (constant 
	  1 
	  (argument 
	   (close (x y) 
		  (refer 
		   y 
		   (refer 
		    x 
		    (argument (refer + (return)))))
		  (apply)))))))

この形になっているとしたら、apply なブロックに入る時点の accumulator は

((refer y (argument (refer x (argument (refer + (return))))))
 e  ;; ry
 (x y))

に、なるのが前提なソレなのか。
# 間違いに気がつきましたがスルーで修正してます
てーコトは

[apply ()
  (record (body e vars) a
    (VM a body (extend e vars r) '() s))]

なんじゃないかなぁ。違うかなぁ。でもこれだと apply する手続きオブジェクトは close 限定とゆーコトでこれはこれで微妙だなぁ。

続き

VM の本体を修正してもエラーは変わらず。では、という事で record の試験を追加してみた。

(let ([a '(1 2 3)])
  (test* "(record (body e vars) a (list body e vars))"
	 '(1 2 3)
	 (record (body e vars) a (list body e vars)))
  )

うーん。通るな。で、gosh で色々ヤッてたら return も修正が必要だった。Compile Error は解決。現時点で以下の lookup な試験はパスしてます。

(test-section "lookup")
(let ([e '(((d e f) . (3 4 5)) ((c) . (2)) ((a b) . (0 1)))])
  (test* "find 1st element" 4 (car (lookup 'e e)))
  (test* "find 2nd element" 2 (car (lookup 'c e)))
  (test* "find 3rd element" 1 (car (lookup 'b e)))
;; cannot test nonexist
  )

で、何から試験すれば良いのだろうか。とりあえず primitive なソレが微妙なんでどうしたものか、なんですが ...