SICP 読み (177) 4.1.7 構文解析を実行から分離する
問題 4.24 がボリューム大きスギ。その前にスルーしている問題 4.22 を検討。とりあえず、以前の問題でヒネリ出した書き換えな手続きが以下。
(define (let->combination exp) (if (symbol? (cadr exp)) (list 'begin (list 'define (cadr exp) (make-lambda (map car (caddr exp)) (cdddr exp))) (append (list (cadr exp)) (map cadr (caddr exp)))) (append (list (make-lambda (map car (cadr exp)) (cddr exp))) (map cadr (cadr exp)))))
試験で確認してみる。
("4.22" ("let->combination (to lambda)" (let ((l '(let ((a 1) (b 2)) (+ a b))) (r '((lambda (a b) (+ a b)) 1 2))) (assert-equal r (let->combination l)) ) ) ("let->combination (to define)" (let ((l '(let f ((a '()) (b '(1 2 3 4))) (if (null? b) a (f (cons (car b) a) (cdr b))))) (r '(begin (define f (lambda (a b) (if (null? b) a (f (cons (car b) a) (cdr b))))) (f '() '(1 2 3 4))))) (assert-equal r (let->combination l)) ) ) )
この導出された式を analyze すれば良いはずなんですが ...
という事で、analyze に以下を追加。
((let? exp) (analyze (let->combination exp)))
以下の試験に一応パス。
("eval (1)" (let ((env (extend-environment '(tmp) '(0) the-global-environment))) (let ((l '(let f ((a '()) (b '(1 2 3 4))) (if (null? b) a (f (cons (car b) a) (cdr b)))))) (assert-equal '(4 3 2 1) (eval l env)) ) ) ) ("eval (2)" (let ((env (extend-environment '(tmp) '(0) the-global-environment))) (let ((l '(let ((a 1) (b 2)) (+ a b)))) (assert-equal 3 (eval l env)) ) ) )
一応ヨシと見て良いのだろうか。てーか、今ごろ気がついたんですが、analyze ってコンパイルなのか。(違
問題 4.24 は time とかでは微妙なのかなぁ。