next up previous
Next: 5.4 lambdaのコード生成 Up: 5 スペシャルフォームのコンパイル Previous: 5.2 set!のコード生成

5.3 ifのコード生成

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日