« Xilinx ISE、EDIF、そしてLisp! | Main | SICP 4.1.2 Representing Expressins その2 »

2007.09.05

SICP 4.1.2 Representing Expressins

Exercise 4.2

a.スペシャルフォームかどうかを先に評価しないと駄目。SICPの最初の方でifはなんでスペシャルフォームなのかと同じ理由。(define x 3)の場合、defineがapplicationだと見なされ、引数を先に評価しようとして、xがlookupできずエラーになる。

b.とりあえず動いた。evalはeval-oに、apllyもapply-oに変更してあります。-oは俺様のo。エラーメッセージも、写経だと処理系のエラーメッセージと区別がつきにくいので、最後にnyoの署名を入れてあります。nyoはニョガーンのnyo。

教科書のevalはこう変更。

(define (eval-o exp env)
 (cond ((self-evaluating? exp) exp)
  ((variable? exp) (lookup-variable-value exp env))
  ((quoted? exp) (text-of-quotation exp))
  ((call? exp) (apply-o (eval-o (call-operator exp) env)  ;追加
             (list-of-values (call-operand exp) env)))
  ((assignment? exp) (eval-assignment exp env))
  ((definition? exp) (eval-definition exp env))
  ((if? exp) (eval-if exp env))
  ((lambda? exp)
   (make-procedure (lambda-parameters exp)
            (lambda-body exp)
            env))
  ((begin? exp)
   (eval-sequence (begin-actions exp) env))
  ((cond? exp) (eval (cond->if exp) env))
  ((application? exp)
   (apply-o (eval-o (operator exp) env)
        (list-of-values (operands exp) env)))
  (else
   (error "Unknown expression type nyo -- EVAL" exp))))

callが呼ばれたら、一個ずらしてそのままapply-oへ。エラーチェック無し。
((call? exp) (apply-o (eval-o (call-operator exp) env)  ;追加
           (list-of-values (call-operand exp) env)))

call周りで作った手続きはこれ。
(define (call? exp) (tagged-list? exp 'call))
(define (remove-call exp) (cdr exp))
(define (call-operator exp)
 (operator (remove-call exp)))
(define (call-operand exp)
 (operands (remove-call exp)))

driver-loopが使いにくいので、直接俺様evalを呼び出してテスト

(define the-grobal-environment (setup-environment))
(eval-o '(define echo (lambda (x) x)) the-grobal-environment)

(trace application?)
(trace apply-o)
(trace call?)

普通の呼び出しだとこう。
(eval-o '(echo 'abc) the-grobal-environment)

gosh> CALL call? (echo (quote abc))
RETN call? #f
CALL application? (echo (quote abc))
RETN application? #t
CALL apply-o (pr...re (...) (...) ((...))) (abc)
RETN apply-o abc
abc

call?が#fを返し、application?が#tなので、apply-oに展開されたechoが渡される。

次にcallを使った呼び出しはこう。
(eval-o '(call echo 'abc) the-grobal-environment)

gosh> CALL call? (call echo (quote abc))
RETN call? #t
CALL apply-o (pr...re (...) (...) ((...))) (abc)
RETN apply-o abc
abc

call?が#tを返すので、追加した部分が評価され、apply-oに上のapplication?が#tを返したときと同じパラメータを渡している。

((call? exp) (apply-o (eval-o (call-operator exp) env)  ;追加
           (list-of-values (call-operand exp) env)))

結果は同じ。
問題は解けたけど、効率的になったかどうかは不明。

ここまでは動くファイルはここ

|

« Xilinx ISE、EDIF、そしてLisp! | Main | SICP 4.1.2 Representing Expressins その2 »

Comments

Post a comment



(Not displayed with comment.)




TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/18154/16351532

Listed below are links to weblogs that reference SICP 4.1.2 Representing Expressins :

« Xilinx ISE、EDIF、そしてLisp! | Main | SICP 4.1.2 Representing Expressins その2 »