Next: 6 マクロのコンパイル
Up: 5 スペシャルフォームのコンパイル
Previous: 5.3 ifのコード生成
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日