3imp 読んでみる (14)
なんも考えずに
[apply () (if (primitive? a) (VM (apply (cadr a) r) '(return) e r s) (record (body e vars) a (VM a body (extend e vars r) '() s)))]
を
[apply () (if (primitive? a) (VM (apply (cadr a) r) x e r s) (record (body e vars) a (VM a body (extend e vars r) '() s)))]
ってやってみると以下の試験にパスしない。
(test-section "primitive") (test* "(VM '() (compile '(if (= 1 1) 0 1) '(halt)) (init-env) '() '())" 0 (VM '() (compile '(if (= 1 1) 0 1) '(halt)) (init-env) '() '()))
意味不明。戻ってきているのは以下のエラー
#<error "improper list not allowed: #t">
improper list は行儀の悪いリスト、との事。具体的に何が原因でドコでエラーが発生するのか、まで追っかけきれていません。
原因解析
コンパイルの戻りは以下 (整形してます
gosh> (compile '(if (= 1 1) 0 1) '(halt)) (frame (test (constant 0 #0=(halt)) (constant 1 #0#)) (constant 1 (argument (constant 1 (argument (refer = (apply))))))) gosh>
VM な手続きをトレイスしてみる事に。
- 最初は x に上記の compile の戻りがセットされて VM 手続き起動
- frame な処理
- test で始まるリストが s に ((test (constant ry)) () () ()) な形
- constant 1 で始まるリストが x に
- VM 手続き呼び出し
- constant な処理
- 1 と 1 を順に current rib に cons
- refer
- = を current environment から解決 (primitive #
) が a に - (apply) が x に
- = を current environment から解決 (primitive #
- apply
- a は primitive 認定なんで a に (apply (cadr a) r) を置いて VM 呼び出し
x は変わってないからエラーのケースだと a に #t とかが入ってて primitive ではない認定された挙句に
(record (body e vars) a (VM a body (extend e vars r) '() s))
で死亡、がおおよそのストーリーですか。
よく考えたら x は (return) 限定で良さげな気がしてきた。いや
(compile (+ 1 1) '(halt))
の場合どうか、というと
(constant 1 (argument (constant 1 (argument (refer + (apply))))))
になるか、と思ったらアタマに frame が付く
(frame (halt) (constant 1 (argument (constant 1 (argument (refer + (apply)))))))
これなら return キメ打ちでも問題ないのかな。