Next: 5.4 lambdaのコード生成
Up: 5 スペシャルフォームのコンパイル
Previous: 5.2 set!のコード生成
ifは条件分岐を行う基本スペシャルフォームですが,条件分岐文でのコード生
成の際には,飛び先ラベルを生成し,FJUMP, JUMPを挿入したコードを生成し
ます.
(defun comp-if (pred then else env)
(let ((l1 (gen-label))
(l2 (gen-label)))
(seq
(comp pred env) (gen 'FJUMP l1)
(comp then env) (gen 'JUMP l2)
(list l1) (comp else env)
(list l2))))
(defun gen-label (&optional (label 'L))
(intern (string (gensym (format nil "~A" label)))))
ラベルを生成するgen-labelは
gensymを使います.string
<cl> (format nil "~A" 'L)
"L"
<cl> (gensym "L")
#:L1031
<cl> (string #:L1031)
*** - EVAL: variable #:L1031 has no value
1. Break [36]> :uw
<cl> (string '#:L1031)
"L1031"
<cl> (intern "L1031")
L1031 ;
NIL
gensymは,Lisp処理系のシステムが
内部で同じシンボルが作られないように
管理しています.
<cl> (comp-show '(if a b))
ARGS 0
GVAR A
FJUMP L369
GVAR B
JUMP L370
L369: GVAR NIL
L370: RETURN
NIL
<cl> (comp-show '(if a))
ARGS 0
GVAR A
FJUMP L401
GVAR NIL
JUMP L402
L401: GVAR NIL
L402: RETURN
NIL
<cl> (comp-show '(if a b c))
ARGS 0
GVAR A
FJUMP L433
GVAR B
JUMP L434
L433: GVAR C
L434: RETURN
NIL
<cl> (comp-show '(if (a) (b) (c)))
ARGS 0
GVAR A
CALL 0
FJUMP L465
GVAR B
CALL 0
JUMP L466
L465: GVAR C
CALL 0
L466: RETURN
NIL
<cl> (comp-show
'(if (= x y) (f (g x)) (h x y (h 1 2))))
ARGS 0
GVAR X
GVAR Y
GVAR =
CALL 2
FJUMP L497
GVAR X
GVAR G
CALL 1
GVAR F
CALL 1
JUMP L498
L497: GVAR X
GVAR Y
CONST 1
CONST 2
GVAR H
CALL 2
GVAR H
CALL 3
L498: RETURN
NIL
generated through LaTeX2HTML. M.Inaba 平成18年5月6日