リテラル式とか quote とか
うーん。なんか凄く基本的な部分の理解が微妙な事が判明。
quote
例えば ev-compile-and-run を以下のようにした場合
ev-compile-and-run (assign val (op procedure-parameters) (reg exp)) ; (assign val (op compile->assemble) (reg val)) ; (goto (reg val)) (goto (label print-result))
何が出力される (val に格納されている) かというと以下
;;; EC-Eval input: (compile-and-run '(define (muln n) (lambda (m) (* m n)))) (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: '(define (muln n) (lambda (m) (* m n))) ;;; EC-Eval input:
quote されてるじゃねぇか、と言いつつ
ev-compile-and-run (assign val (op procedure-parameters) (reg exp)) (assign val (op compile->assemble) (reg val)) ; (goto (reg val)) (goto (label print-result))
としてみると出力は略しますが、まともに翻訳されている模様。これ、どう違うんだよ、と言いつつもう少し確認。
gosh> (define test (read)) (x '(define (addn n) (lambda (m) (+ m n)))) test gosh> test (x '(define (addn n) (lambda (m) (+ m n)))) gosh> (compile (cadr test) 'val 'return) ((continue) (val) ((assign val (const (define (addn n) (lambda (m) (+ m n))))) (goto (reg continue)))) gosh> (define test2 '(define (addn n) (lambda (m) (+ m n)))) test2 gosh> test2 (define (addn n) (lambda (m) (+ m n))) gosh> (define test2 (cadr test)) test2 gosh> test2 '(define (addn n) (lambda (m) (+ m n))) gosh> (compile test2 'val 'return) ((continue) (val) ((assign val (const (define (addn n) (lambda (m) (+ m n))))) (goto (reg continue)))) gosh> (compile '(define (addn n) (lambda (m) (+ m n))) 'val 'return) ((env continue) (val) ((assign val (op make-compiled-procedure) (label entry49) (reg env)) (goto (label after-lambda50)) ;; 略 gosh>
この結果もなんとなく問題 5.48 の解と整合してないような気がするなぁ。
- ev-compile-and-run では (compile-and-run '(define x 1)) なリストを全部渡して cadr を compile->assemble に渡したらその中でリテラル式と判断された
- ev-compile-and-run において exp の cadr を compile-assemble に渡したらその中ではリテラル式とは判断されなかった
- test に read で読み込んだ (x '(define (addn n) (lambda (m) (+ m n)))) をセットして (cadr test) を compile に渡したら評価する式はリテラルと判断された
- define 式で test2 に '(define (addn n) (lambda (m) (+ m n))) という式を束縛したら test2 の束縛は (define (addn n) (lambda (m) (+ m n))) になった (リテラル式ではない)
- test2 に (cadr test) をセットして compile に渡したら test2 はリテラル式として評価された
- compile に '(define (addn n) (lambda (m) (+ m n))) を渡したらリストとして評価された
とゆー事は
- 手続きにリストを渡す場合、リテラル式になっていたら引数自体は評価されず、手続きの中ではリストとして評価される
- 手続きにリテラル式を含んだリストを渡す場合、そのリテラル式な要素はリテラルのまま評価される
と考えれば良いのでしょうか。でも test2 に (cadr test) をセットした時の挙動は整合してないなぁ。
む
なんか果てしの無い話だなぁ、と思いつつ以下の例を思いつく。
gosh> (cons '1 '2) (1 . 2) gosh> (cons '(1 2 3) '(4)) ((1 2 3) 4) gosh>
えーと、quote された式が手続きの引数になってる場合は手続きに渡された時点で quote でなくなるのかな。でも上記の箇条書きの例にそうではないソレがある。
むむむ、とウナりつつ以下
gosh> test2 '(define (addn n) (lambda (m) (+ m n))) gosh> (quoted? test2) #t gosh> (tagged-list? test2 'quote) #t gosh> (car test2) quote gosh> test2 '(define (addn n) (lambda (m) (+ m n))) gosh> (cadr test2) (define (addn n) (lambda (m) (+ m n))) gosh>
あらまー。quote ってこうなってるんだ。びっくり。って R5RS 見ながら作業してるんですが ' がこうなってるとは (何
でも test2 が quote と判断されてるとゆー事は
gosh> (cons test2 '()) ('(define (addn n) (lambda (m) (+ m n)))) gosh>
うーん。駄目ぢゃん。上記のリストの car を見てみたら以下
gosh> (car (cons test2 '())) '(define (addn n) (lambda (m) (+ m n))) gosh>
むむ。どうなっているのか。と思ったら
gosh> (car (car (cons test2 '()))) quote gosh>
となってて安心。む。てーコトは
gosh> test (x '(define (addn n) (lambda (m) (+ m n)))) gosh> test2 '(define (addn n) (lambda (m) (+ m n))) gosh> (compile (cadr test2) 'val 'return) ((env continue) (val) ((assign val (op make-compiled-procedure) (label entry57) (reg env)) (goto (label after-lambda58)) ;; 略 gosh> (compile (cadr (cadr test)) 'val 'return) ((env continue) (val) ((assign val (op make-compiled-procedure) (label entry65) (reg env)) (goto (label after-lambda66)) ;; gosh>
を。できた。なんか分かってないのを丸出しにしてるカンジがしてイヤだなぁ。でも
ev-compile-and-run (assign val (op procedure-parameters) (reg exp)) (assign val (op compile->assemble) (reg val)) (goto (reg val))
で正常動作する根拠にはなってないように思えるんですが。
# とりあえず一旦スルーする方向で (を