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 なソレが微妙なんでどうしたものか、なんですが ...