next up previous
Next: 6 マクロのコンパイル Up: 5 スペシャルフォームのコンパイル Previous: 5.3 ifのコード生成

5.4 lambdaのコード生成

lambdaではじまるフォームのコンパイルは,lambda内部のコードをコンパイル して,そのコンパイルコードをもったクロージャを引数とするコードFNを生成 することを行います.クロージャを表現するために,fnという構造体を用いま す.クロージャ内部に蓄えられる環境は,コンパイル時の環境になります.ク ロージャ内部に蓄えられる変数は,lambdaフォームの引数になります.クロー ジャをあらわす構造体fnには,名前フィールドnameがありますが,defineで大 域変数にこのクロージャを代入した時には,このnameにその大域変数名が入り ます. lambda内部のコードのコンパイル時の環境には,それまでの環境にこのlambda フォームの引数を追加した環境とします.lambdaフォームのコンパイルコード は,実引数がすでにスタックにあるとして,仮引数の変数の個数だけ,スタッ クから変数を取り出すという命令ARGSとlambda内部のコードを順にコード生成 して,最後にRETURNコードを付けたコードとなります.

(defstruct fn code env name args)

(defun comp-lambda (args body env)
  (make-fn
   :env env :args args
   :code (seq (gen 'ARGS (length args))
              (comp-begin body (cons args env))
              (gen 'RETURN))))
<cl> (comp-show '(lambda ()))
      ARGS  0     
      FN    
            ARGS  0     
            CONST NIL   
            RETURN
      RETURN

<cl> (scheme-compile '(lambda () ))

#S(FN :CODE
      ((ARGS 0)
       (FN
        #S(FN :CODE ((ARGS 0) (CONST NIL) (RETURN))
              :ENV (NIL) :NAME NIL :ARGS NIL))
       (RETURN))
      :ENV NIL :NAME NIL :ARGS NIL)

<cl> (comp-show '(lambda (a)))
      ARGS  0     
      FN    
            ARGS  1     
            CONST NIL   
            RETURN
      RETURN

<cl> (scheme-compile '(lambda (a)))

#S(FN :CODE
      ((ARGS 0)
       (FN
        #S(FN :CODE ((ARGS 1) (CONST NIL) (RETURN))
              :ENV (NIL) :NAME NIL :ARGS (A)))
       (RETURN))
      :ENV NIL :NAME NIL :ARGS NIL)

<cl> (comp-show '(lambda (a) a))
      ARGS  0     
      FN    
            ARGS  1     
            LVAR  0     0     ;     A     
            RETURN
      RETURN

<cl> (scheme-compile '(lambda (a) a))

#S(FN :CODE
      ((ARGS 0)
       (FN
        #S(FN :CODE ((ARGS 1)
               (LVAR 0 0 ";" A) (RETURN))
              :ENV (NIL) :NAME NIL :ARGS (A)))
       (RETURN))
      :ENV NIL :NAME NIL :ARGS NIL)

<cl> (comp-show '(lambda (x) (test x)))

      ARGS  0     
      FN    
            ARGS  1     
            LVAR  0     0     ;     X     
            GVAR  TEST  
            CALL  1     
            RETURN
      RETURN

<cl> (scheme-compile '(lambda (x) (test x)))
#S(FN :CODE
      #((ARGS 0)
        (FN
         #S(FN :CODE
               #((ARGS 1)
                 (LVAR 0 0 ";" X)
                 (GVAR TEST)
                 (CALL 1)
                 (RETURN))
               :ENV (NIL) :NAME NIL :ARGS (X)))
        (RETURN))
      :ENV NIL
      :NAME NIL
      :ARGS NIL)

<cl> (comp-show '((lambda (a) (list a)) 3))
      ARGS  0     
      CONST 3     
      FN    
            ARGS  1     
            LVAR  0     0     ;     A     
            GVAR  LIST  
            CALL  1     
            RETURN
      CALL  1     
      RETURN

<cl> (scheme-compile '((lambda (a) (list a)) 3))

#S(FN :CODE
      #((ARGS 0) (CONST 3)
        (FN
         #S(FN :CODE
               #((ARGS 1)
                 (LVAR 0 0 ";" A)
                 (GVAR LIST)
                 (CALL 1)
                 (RETURN))
               :ENV (NIL) :NAME NIL :ARGS (A)))
        (CALL 1)
        (RETURN))
      :ENV NIL
      :NAME NIL
      :ARGS NIL)

<cl> (comp-show
     '((lambda (x)
        ((lambda (y z) (f x y z)) 3 x))
         4))

      ARGS  0     
      CONST 4     
      FN    
            ARGS  1     
            CONST 3     
            LVAR  0     0     ;     X     
            FN    
                  ARGS  2     
                  LVAR  1     0     ;     X     
                  LVAR  0     0     ;     Y     
                  LVAR  0     1     ;     Z     
                  GVAR  F     
                  CALL  3     
                  RETURN
            CALL  2     
            RETURN
      CALL  1     
      RETURN

<cl> (scheme-compile '((lambda (x)
        ((lambda (y z) (f x y z)) 3 x))
         4))

#S(FN :CODE
      #((ARGS 0)
        (CONST 4)
        (FN
         #S(FN :CODE
               #((ARGS 1)
                 (CONST 3)
                 (LVAR 0 0 ";" X)
                 (FN
                  #S(FN :CODE
                        #((ARGS 2)
                          (LVAR 1 0 ";" X)
                          (LVAR 0 0 ";" Y)
                          (LVAR 0 1 ";" Z)
                          (GVAR F)
                          (CALL 3)
                          (RETURN))
                        :ENV ((X) NIL)
                        :NAME NIL
                        :ARGS (Y Z)))
                 (CALL 2)
                 (RETURN))
               :ENV (NIL)
               :NAME NIL
               :ARGS (X)))
        (CALL 1)
        (RETURN))
      :ENV NIL :NAME NIL :ARGS NIL)


generated through LaTeX2HTML. M.Inaba 平成18年5月6日