「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 番目の要素の2番目以降のリスト )
-- ( CODEリストの2番目以降 . 環境ENV )
-- ) というリストを作る(戻り値になる)
((eq (caar code) 'abs)
- 先頭のリストの1番目の要素→が'abs 関数定義だったら
(let ((n (cadr (car code)))
(cc (nth 2 (car code)))
(c (cdr code)))
-- 関数の引数を ローカル変数 n に束縛
-- 関数の本体を ローカル変数 cc に束縛
-- 後続のリスト全体を ローカル変数 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)
-- (後続のリスト ( ( 関数の本体 . 環境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))))
-- (後続のリスト ( ( 関数本体 . 環境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"))))
*呼出元
- [[grass.el(0.1.8)/defun grass-eval-code-internal]] (2009-01-03 21:17:14)
#comment(noname)
*履歴
-作者:[[kobapan>http://www20.atwiki.jp/kobapan/]]
-日付:2009/01/03
-対象:
|更新日|更新者|更新内容|
||||
*コメント
#comment
*概要
- 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 番目の要素の2番目以降のリスト )
-- ( CODEリストの2番目以降 . 環境ENV )
-- ) というリストを作る(戻り値になる)
((eq (caar code) 'abs)
- 先頭のリストの1番目の要素→が'abs 関数定義だったら
(let ((n (cadr (car code)))
(cc (nth 2 (car code)))
(c (cdr code)))
-- 関数の引数を ローカル変数 n に束縛
-- 関数の本体を ローカル変数 cc に束縛
-- 後続のリスト全体を ローカル変数 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)
-- (後続のリスト ( ( 関数の本体 . 環境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))))
-- (後続のリスト ( ( 関数本体 . 環境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"))))
*呼出元
- [[grass.el(0.1.8)/defun grass-eval-code-internal]] (2009-01-03 21:17:14)
#comment(noname)
*履歴
-作者:[[kobapan>http://www20.atwiki.jp/kobapan/]]
-日付:2009/01/03
-対象:
|更新日|更新者|更新内容|
||||
*コメント
#comment