grass.el(0.1.8) > defun grass-eval-machine

概要

  • grass VM

引数

  • CODE 処理を待っているgrassのコード
  • ENV 現時点の環境リスト 値のスタック
  • DUMP 現時点の中断して再開を待っている計算 リターン先を覚えておくスタック

実装

(defun grass-eval-machine (code env dump)
 (cond
  ((eq (caar code) 'app)
  • CODEの先頭要素の1番目の要素が 'app 関数適用だったら
  • 以下ルールを適用する
  • (App(m, n) :: C, E, D) → (Cm, (Cn, En) :: Em, (C, E) :: D) where E = (C1, E1) :: (C2, E2) :: … :: (Ci, Ei) :: E' (i = m, n)

   (let ((m (cadr (car code)))
         (n (nth 2 (car code)))
         (c (cdr code)))
    • App(m, n) :: C
      • 適用する関数の "関数定義の位置を示す部分" を ローカル変数 m に束縛
      • 適用する関数の "引数の位置を示す部分" を ローカル変数 n に束縛
      • CODEの2番目以降を ローカル変数 c に束縛

     (if (grass-primitive-p (nth (1- m) env))
    • 環境ENVの m 番目の要素(適用する関数)が primitive関数である場合
    • grass.el(0.1.8)/defsubst grass-primitive-p
      • (nth (1- m) ⇒ nth は 先頭を 0 で数えるので、何番目かという表現を offset 位置に変換して環境ENVから関数を取得

         ;; Em is a primitive
         (list c
               (cons (funcall
                      (grass-primitive-func (nth (1- m) env)) (nth (1- n) env))
                     env)
               dump)
    • 適用する関数が primitive関数 である場合
    • (
    • CODEの2番目以降
    • ( "関数 m を 引数 n で適用した結果" . 環境ENV)
    • 実行待ちDUMP
    • ) というリストを作る(戻り値になる)
    • 関数 m のさらに関数部分を取得するために grass.el(0.1.8)/defsubst grass-primitive-func を使っている

       ;; Em is a list
       (list (car (nth (1- m) env))
             (cons (nth (1- n) env) (cdr (nth (1- m) env)))
             (cons (cons c env) dump)))))
    • 適用する関数が primitive関数 ではない場合
    • (
    • 環境ENVの m 番目の要素の "関数定義の位置を示す部分"
    • ( 環境ENVの n 番目の要素 . 環境ENVの m 番目の "引数の位置を示す部分" )
    • ( CODEリストの2番目以降 . 環境ENV )
    • ) というリストを作る(戻り値になる)

  ((eq (caar code) 'abs)
  • 先頭のリストの1番目の要素が 'abs 関数定義だったら

   (let ((n (cadr (car code)))
         (cc (nth 2 (car code)))
         (c (cdr code)))
    • 関数定義の "引数" を ローカル変数 n に束縛
    • 関数定義の "本体" を ローカル変数 cc に束縛
    • CODEの2番目以降を ローカル変数 c に束縛

     (if (eq n 1)
    • 引数 n が 1 だったら
    • 以下ルールを適用する
    • (Abs(n, C') :: C, E, D) → (C, (C', E) :: E, D) if n = 1

         (list c
               (cons (cons cc env) env)
               dump)
    • (
    • CODEの2番目以降
    • ( ( 関数本体 cc . 環境ENV) . 環境ENV)
    • 実行待ちDUMP
    • ) というリストを作る(戻り値になる)

    • 引数 n が 1 より大きかったら
    • 以下ルールを適用する
    • (Abs(n, C') :: C, E, D) → (C, (Abs(n - 1, C')::・, E) :: E, D) if n > 1

       (list c
             (cons (cons (list (list 'abs (1- n) cc)) env) env)
             dump))))
    • (
    • CODEの2番目以降
    • ((( 'abs "引数 n - 1" "関数本体 cc" ) . 環境ENV) . 環境ENV)
    • 実行待ちDUMP
    • ) というリストを作る(戻り値になる)

  ((null code)
  • 引数 code が空だったら

   ;; (・, f :: E, (C', E') :: D) → (C', f :: E', D)
   (and dump
        (list (caar dump)
              (cons (car env) (cdar dump))
              (cdr dump))))
    • (
    • 実行待ちの計算DUMPの先頭リストの先頭要素
    • ( 環境の先頭要素 . 実行待ちDUMPの先頭要素の第二要素 )
    • 実行待ちDUMPの第2要素
    • ) とういうリストを作る(戻り値になる)

  (t
   (error "grass-eval: runtime error"))))

呼出元

コメント:


履歴

  • 作者:kobapan
  • 日付:2009/01/03
  • 対象:
更新日 更新者 更新内容

コメント


名前:
コメント:
最終更新:2009年01月16日 07:59