next up previous
Next: 1.3 通常の手続き(関数)の処理 Up: 1 Schemeインタプリタの実現 Previous: 1.1 シンボルとアトムの処理

1.2 スペシャルフォームの処理

スペシャルフォームには,つぎの5つがあります.通常の手続きは,関数名の 部分と引数をすべて評価しますが,スペシャルフォームでは,関数名も評価せ ずに,引数の評価の仕方も特別扱いされます.
  1. quoteの処理 lispと同じように,その引数をそのまま返します.つまり,引数を 評価しないというものです.
  2. beginの処理 lispのprognと同じ働きを持つものです.引数を順に評価し,最後の 評価の結果を返します.引数の個数が任意個になります.
  3. set!の処理 lispのsetqと同じ働きを持つものです.第1引数を評価せずに, 2番目の引数を評価します.第1引数が変数名で第2がその変数の ための値を意味します. 変数名が評価環境の中にあれば,その評価環境中の変数の値を 設定します.なければ大域変数の値を設定します.
  4. ifの処理 lispのifと同じ働きを持つものです.最初の引数を評価し, その結果に応じて,2番目の引数を評価するか,3番目の引数を評価するかを 決めます.
  5. lambdaの処理 関数クロージャを作ることを行ないます.第1引数が関数クロージャへのパラ メタで,第3引数以降が本体です.本体における処理がいくつもあって良いよ うに,beginを付けて処理します. ここで,Scheme言語のクロージャを定義する必要があるのですが, ひとまず,CommonLispのクロージャをそのまま使っておきます.

(defun interp-specialform (name params env)
  (case
   name
   (quote (car params))
   (begin (if (null params) nil
            (car (last
                  (mapcar
                   #'(lambda (v) (interp v env))
                   params)))))
   (set! (set-var! (car params)
                   (interp (cadr params) env)
                   env))
   (if  (if (interp (car params) env)
            (interp (cadr params) env)
          (interp (caddr params) env)))
   (lambda
     (let* ((vars (car params))
            (code (cons 'begin (cdr params))))
       #'(lambda (&rest args)
           (interp
            code
            (nconc (make-bindings vars args) env)))))))

(defun make-bindings (vars values)
  (mapcar #'list vars values))


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