3imp 読んでみる (11)

ちょっとこつこつ試験を書いて理解を深める必要あり。あと、試験書きながらドキュメント確認も並行。

VM の試験

へろへろだ。とりあえず現時点で以下

(test-section "constant")
(test* "(VM '() (compile 1 '(halt)) '() '() '())"
       1
       (VM '() (compile 1 '(halt)) '() '() '()))

(test-section "evaluate")
(test* "(evaluate 1)"
       1
       (evaluate 1))

(test-section "quote")
(test* "(evaluate '(quote x))"
       'x
       (evaluate '(quote x)))

テキストにも書いてありますが、halt は accumulator の値を戻す。constant は引数を accumulator に格納して next expression に次をセット。ので上記の試験的にはそのまんまな値が戻ってくればセイフなんですが、lambda 式が戻すのは何なんだろう。

  • (compile (lambda (x) x) (halt)
  • (close (x) (compile x (return)) (halt))
  • (close (x) (refer x (return)) (halt))

でこれが next expression にセットされて VM 起動

  • (VM (closure (refer x (return)) e (x)) (halt) () () ())
  • (VM ((refer x (return)) () (x)) (halt) () () ())

halt なブロックで accumulator が戻るんで戻るのは ((refer x (return)) () (x)) なのかなぁ。確認してみます。試験は以下

(test-section "lambda")
(test* "(evaluate '(lambda (x) x))"
       '((refer x (return)) () (x))
       (evaluate '(lambda (x) x)))

OK でした。

if の試験

compile では以下

		 [if (test then else)
		     (let ([thenc (compile then next)]
			   [elsec (compile else next)])
		       (compile test (list 'test thenc elsec)))]

で、test なインストラクションは以下

	       [test (then else)
		     (VM a (if a then else) e r s)]

accumulator の値が #f 以外だと then に next expression が、なのかなぁ。実はこのあたりはこれを基に作り込みが必要な世界に見える。あら、テキストによれば accumulator が nonnull だった云々って書いてあるな。
R5RS によれば_#f のみが条件式で偽扱い_って書いてあるんですが accumulator に #f がナニなソレは無さげに見える。
で、こんな試験

(test-section "if")
(test* "(evaluate '(if #t 1 2))"
       1
       (evaluate '(if #t 1 2)))

(test* "(evaluate '(if #f 1 2))"
       2
       (evaluate '(if #f 1 2)))

パスしてるな。あくまでも勉強ネタなのか。しかも set! は単体で試験不可能。どうしたものか。