eval-sv

[トップ][一覧][最近の更新]

現在ゆっくり製作中

現在のところ、eval/sv内にdynamic-windが設置された場合の挙動に、仕様レベルでの問題がある事が判明しています。 詳細については「問題点」の項目を確認してください。


概要

evalによる式の評価を、監視付きで実行します

必要要件

ライセンス

修正BSD風ライセンスです。 tarball同梱のCOPYINGに詳細(といっても、定型文のみですが)が書いてあります。

ダウンロード

パッケージ

リポジトリ

ChangeLog

インストール

gauche-package installに対応してます。

gauche-package install eval-sv-x.y.z.tgz

リポジトリから持ってきた場合は、インストール可能な権限で以下を実行。

./DIST gen
./configure
make all check
make install

が、別にインストールしなくても使えます。 その場合は、適当に、libディレクトリをモジュールロードpathに追加して下さい。

gauche.nightプレゼン

デモアプリ

S式バトラー

S式バトラーのソース(物凄い汚い注意)

理論と応用

使い方

eval-svモジュール

このモジュールは、ステップ監視付きの評価器(のジェネレータ)を提供する。

サンプルコード

(use eval-sv)

(define-values (eval/sv env)
  (make-eval/sv :isolate-port? #f))
;; eval/sv手続きと無名モジュールが返る

(define (sv type symbol expr args return except)
  (print `(apply ,expr ,args))
  ;; ここで必要に応じて処理を行うが、
  ;; 重要なのは以下を実行する事
  (apply expr args))

;; 実行してみる
(eval/sv '(+ 1 3) sv)
;; => printしてから4が返る

;; 別の監視手続きで実行してみる
(define (sv2 type symbol expr args return except)
  (except "raise error"))
(eval/sv '(+ 1 3) sv2)
;; => error例外

(import/sv env 'eval/sv eval/sv)
;; import/svで、外部の手続きを
;; (比較的)安全に持ち込める
;; ここではeval/sv自身を内部に持ち込んでみた
;; (勿論、ちゃんと動くように作ってます)

(eval/sv `(eval/sv '(+ 1 3) ,sv2) sv)
;; => 二回printしてからerror例外
;;    (監視手続きがmergeされた)

詳細

(use eval-sv)
;; eval/svを生成する
(define-values (eval/sv env)
  (make-eval/sv :default-sv-proc #f
                ;; ↑デフォルトの監視手続き。デフォルト値は#f。
                ;; ↑ここで設定せずに、eval/sv実行時に指定してもよい
                ;; ↑(その方が分かりやすい)
                :isolate-port? bool
                ;; ↑current-*-portをダミーに差し替えるフラグ。
                ;; デフォルト値は#t。
                ;; (current-*-portがブロックデバイスだった場合、
                ;;  ブロッキング停止が発生する可能性がある為、
                ;;  安全性を確保する為に、#tにしておいた方が良い。
                ;;  自前でcurrent-*-portでブロッキング停止が
                ;;  発生しない保証をしているなら、#fにしてもよい。)
                :parent-module 'module-name
                ;; ↑make-eval/svがextendする、
                ;; 無名モジュールの親モジュール名。
                ;; シンボルで指定する事(無名モジュール不可)。
                ;; 親モジュールは、規定の方法で初期化されている事。
                ;; eval-sv.templateによって、ある程度の種類の
                ;; 目的別テンプレートモジュールを用意してある。
                ;; それらを使う場合は
                ;; :parent-module [atmn 'r5rs+]
                ;; のような指定をすればよい。
                :bind-alist `((symbol ,expr) ...)
                ;; ↑追加束縛のalist。
                ;; 自動的に(import/sv env symbol expr)される。
                ))
;; 監視手続きを定義する
(define (sv-proc type symbol expr args return except)
  ... ; 値を監視し、必要な処理を行う事
  ... ; 重要なのは、以下のapplyを実行し、
  ... ; その返り値を返す必要があるという点
  (apply expr args))
;; 実際に式を評価する
(eval/sv expr sv-proc)
;; eval/svの環境内に、新しい束縛を後付け追加する
(import/sv env 'undefined undefined)
;; 内部で無限ループする可能性のある手続き等は、
;; 自前で何らかの対策を行い、
;; 無限ループしない事を保証する必要がある
(use util.list)
(import/sv env 'intersperse (lambda (item source-list)
                              (if (circular-list? source-list)
                                (error "this is circular-list")
                                (intersperse item source-list))))
(eval/sv '(undefined) sv-proc) ; => #<undef>
(eval/sv '(intersperse '+ '(1 2 3)) sv-proc) ; => (1 + 2 + 3)

eval-cu-liteモジュール

このモジュールは、実行カウント付き評価器(のジェネレータ)を提供する。

(use eval-cu-lite)
(define-values (eval/cu env)
  (make-eval/cu :isolate-port? bool ; eval/svと同じ
                :parent-module [atmn 'r5rs+] ; eval/svと同じ
                :bind-alist '() ; eval/svと同じ
                :default-threshold 200
                ;; この回数、手続きまたは
                ;; special formが実行されたら例外終了
                ;; (この値はeval/cuの第二引数省略時に
                ;;  fallback値として使われる)
                :macro-threshold 200
                ;; この回数マクロ展開されたら例外終了
                :loop-threshold 200
                ;; この回数ループ実行されたら例外終了
                ))
(guard (e ((<eval-cu-exceeded> e)
           (let ((type (ece->type e)) ; 'proc or 'macro or 'loop
                 (count (ece->count e)) ; その時点でのカウンタ値
                 (continue (ece->continue e))) ; 続行する為の継続
                 ;; ※continueを使って続行した場合も、カウンタ値は
                 ;;   続行され続ける事に注意
                 ;;   (次回に例外が呼び出されるのはthresholdの次の倍数)
             ;; 実際のオーバーカウント処理をここに書く
             ...))
          (else
            ;; その他のエラー処理をここに書く
            ...))
  ;; exprにはevalしたい式を、thresholdにはprocカウントの閾値を設定する
  ;; (macroカウントとloopカウントの閾値はmake-eval/cu時以外は変更不可)
  (eval/cu expr threshold))

(eval-cu-last-count)
;; これを実行する事で、最後に実行したeval/cuのカウント値が得られる。
;; (これは、eval/cuは正常に終了したが、
;;  カウントがどこまで進んだのか知りたい時に使える)
;; これはparameterなので、入れ子やthread動作等で不安がある場合は、
;; parameterizeしておけば安全に参照する事が出来る。

eval-sv.templateモジュール

faq

問題点

バグレポート

あとで。

内部情報

各値の扱いについて

手続き及びmethod

マクロ

special form

それ以外の値

モジュール構造と関係の説明

作った感想

一番最初に想像していた仕様 ( http://d.hatena.ne.jp/ranekov/20080127/1201369856 )

開発メモ

ここには、開発中の一時メモを書きます。 開発者以外が読む価値はありません多分。

残り作業

r5rs+で提供すべき手続き候補

思い付いたらどんどん書く事。厳密なチェックは最後にやる。

チェックリスト

その他のメモ


最終更新 : 2008/04/13 03:36:46 JST