SICP 問題 5.44
基本手続きの名前を含む式の正しいコードを翻訳するため,翻訳時環境を調べるようにする.
(cond ((self-evaluating? exp)
(compile-self-evaluating exp target linkage))
((variable? exp)
(compile-variable exp target linkage ct-env))
((quoted? exp) (compile-quoted exp target linkage))
((assignment? exp)
(compile-assignment exp target linkage ct-env))
((definition? exp)
(compile-definition exp target linkage ct-env))
((if? exp) (compile-if exp target linkage ct-env))
((lambda? exp)
(compile-lambda exp target linkage ct-env))
((let? exp)
(compile (let->combination exp) target linkage ct-env))
((begin? exp)
(compile-sequence (begin-actions exp)
target linkage ct-env))
((cond? exp) (compile (cond->if exp) target linkage ct-env))
((open-code? exp ct-env) ;ct-envも渡して翻訳時環境に上書きされていないか調べる
(compile-open-code exp target linkage ct-env))
((application? exp)
(compile-application exp target linkage ct-env))
(else
(error "Unknown expression type -- COMPILE" exp))))
(define (not-overwrite? op ct-env)
(let ((address (find-variable op ct-env )))
(eq? address 'not-found)))
(define (open-code? exp ct-env)
(and (memq (car exp) '(= * - +))
(not-overwrite? (car exp) ct-env)))
test
((env) (val) ((assign val (op make-compiled-procedure) (label entry14) (reg env)) (goto (label after-lambda15)) entry14 (assign env (op compiled-procedure-env) (reg proc)) (assign env (op extend-environment) (const (+ * a b x y)) (reg argl) (reg env)) (assign proc (op lexical-address-lookup) (const (0 0)) (const ((+ * a b x y)))) ;;ここで+を探すのにct-envの中身から探しているので成功.open-codeになっていない. (save continue) (save proc) (assign proc (op lexical-address-lookup) (const (0 1)) (const ((+ * a b x y)))) (assign val (op lexical-address-lookup) (const (0 5)) (const ((+ * a b x y)))) (assign argl (op list) (reg val)) (assign val (op lexical-address-lookup) (const (0 3)) (const ((+ * a b x y)))) (assign argl (op cons) (reg val) (reg argl)) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch19)) compiled-branch20 (assign continue (label after-call21)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch19 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call21 (assign argl (op list) (reg val)) (save argl) (assign proc (op lexical-address-lookup) (const (0 1)) (const ((+ * a b x y)))) (assign val (op lexical-address-lookup) (const (0 4)) (const ((+ * a b x y)))) (assign argl (op list) (reg val)) (assign val (op lexical-address-lookup) (const (0 2)) (const ((+ * a b x y)))) (assign argl (op cons) (reg val) (reg argl)) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch16)) compiled-branch17 (assign continue (label after-call18)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch16 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call18 (restore argl) (assign argl (op cons) (reg val) (reg argl)) (restore proc) (restore continue) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch22)) compiled-branch23 (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch22 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) (goto (reg continue)) after-call24 after-lambda15 ))