SICP 読み (336) 5.5 翻訳系

問題 5.39

昨晩のエントリで試験なソレをサラしておりますが、いっちゃんケツに

(test-end)

って入ってないなぁ。それは良いとして lexical-address-lookup の本体をナニしないと試験もクソも無い。えーと手続きとしては

(define (lexical-address-lookup add env)
  )

みたいな感じですが、これって n 回リストを手繰ってそれを戻す手続きがあれば使い回せそうな感じ。
ってデフォルトで用意されとるのではなかろうか、と思いつつも作る。

(define (list-ref n l)
  (if (= n 0)
      (car l)
      (list-ref (- n 1) (cdr l))))

む。これって微妙な前提の元に、なナニだな。一応保険かけとくか。

(define (list-ref n l)
  (if (= n 0)
      (car l)
      (if (null? (cdr l))
	  (error "end of list")
	  (list-ref (- n 1) (cdr l)))))

本当は試験書くべきなんでしょうが gosh で試験

gosh> (define l '(((a b) . (1 2)) ((c d e) . (3 4 5)) ((f g h i) . (6 7 8 9))))
gosh> (list-ref 2 l)
((f g h i) 6 7 8 9)
gosh> (list-ref 0 (cdr (list-ref 2 l)))
6
gosh> 

で、R5RS 見てみたら list-ref という手続きがある。わははは、と笑いつつ手続きは以下

(define (lexical-address-lookup add env)
  (list-ref (cadr add) (cdr (list-ref (car add) env))))

ちなみに上記の list-ref はステ。って逆だし。正しくは以下か。

(define (lexical-address-lookup add env)
  (list-ref (cdr (list-ref env (car add))) (cadr add)))

試験

なんかさくっとパス。環境としては

$ ls
5.39.scm  
Makefile  
ch5-compiler.scm         
ch5-eceval-compiler.scm  
ch5-eceval-support.scm  
ch5-regsim.scm          
ch5-syntax.scm            
load-eceval-compiler.scm
test-5.39.scm
$ make
Testing 5.39 ...                                                 passed.
$

ソースは以下ですが、まず試験を再掲

(use gauche.test)

(add-load-path ".")
(load "5.39.scm")

(test-start "5.39")

(test-section "example")
(let ((env (extend-environment 
	    '(y z) 
	    '(1 2)
	    (extend-environment
	     '(a b c d e)
	     '(3 4 5 6 7)
	     (extend-environment
	      '(x y)
	      '(8 9)
	      '())))))
  (test* "x is 8 (2 0)" 8 (lexical-address-lookup '(2 0) env))
  (test* "y is 1 (0 0)" 1 (lexical-address-lookup '(0 0) env))
  (test* "c is 5 (1 2)" 5 (lexical-address-lookup '(1 2) env)))
(test-end)

次は 5.39.scm

(load "load-eceval-compiler")
(load "ch5-compiler")
(define true #t)
(define false #f)

(define (lexical-address-lookup add env)
  (list-ref (cdr (list-ref env (car add))) (cadr add)))

で試験ログが以下

Testing 5.39 ==================================================================
<example>----------------------------------------------------------------------
test x is 8 (2 0), expects 8 ==> ok
test y is 1 (0 0), expects 1 ==> ok
test c is 5 (1 2), expects 5 ==> ok
passed.

次の問題まで手が回るだろうか。

追記

む。良く見りゃこれで終わりではないな。

  • *unassigned* ならエラー
  • lexical-addresss-set! の実装

が残ってたりなんかします。しかもこれらをどう使うのか、がまだ見えてない。