R6RS Conditon をサポートする その2
psyntax で R6RS Conditions を動かす方法のまとめ。おそらく多くても数名の役にしか立たないと思うけど情報を残しておく。
前提
R6RS Records が実装され動いていること。
ただし psyntax が Syntactic layer 、つまり define-record-type をサポートしてくれるのでそれ以外が動いていればよい。
1.Condition 手続きを実装する
condition, ,simple-conditions, condition?, condition-accessor, condition-predicate を実装する。
condition は基本的に Record で構築できるが、合成コンディションがあるため accessor, predicate の実装を自前でやる必要がある。
condition? は &condition のサブタイプかどうかのチェックが必要なので動的に rtd 取り出しが必要なので注意。
2. mosh/condition.ss を用意する。
&non-continuable などがエラーになるのは謎。
(library (mosh condition) (export &condition condition simple-conditions condition? condition-predicate condition-accessor define-condition-type &message make-message-condition message-condition? condition-message &warning make-warning warning? &serious make-serious-condition serious-condition? &error make-error error? &violation make-violation violation? &assertion make-assertion-violation assertion-violation? &irritants make-irritants-condition irritants-condition? condition-irritants &who make-who-condition who-condition? condition-who ;; &non-continuable ;; make-non-continuable-violation ;; non-continuable-violation? ;; &implementation-restriction ;; make-implementation-restriction-violation ;; implementation-restriction-violation? &lexical make-lexical-violation lexical-violation? &syntax make-syntax-violation syntax-violation? syntax-violation-form syntax-violation-subform &undefined make-undefined-violation undefined-violation? ) (import (rnrs base) (rnrs records syntactic) (only (rnrs conditions) condition simple-conditions condition? condition-predicate condition-accessor define-condition-type)) (define-record-type &condition (nongenerative)) (define &condition-rtd (record-type-descriptor &condition)) (define &condition-rcd (record-constructor-descriptor &condition)) (define-condition-type &message &condition make-message-condition message-condition? (message condition-message)) (define-condition-type &warning &condition make-warning warning?) (define-condition-type &serious &condition make-serious-condition serious-condition?) (define-condition-type &error &serious make-error error?) (define-condition-type &violation &serious make-violation violation?) (define-condition-type &assertion &violation make-assertion-violation assertion-violation?) (define-condition-type &irritants &condition make-irritants-condition irritants-condition? (irritants condition-irritants)) (define-condition-type &who &condition make-who-condition who-condition? (who condition-who)) (define-condition-type &non-continuable &violation make-non-continuable-violation non-continuable-violation?) (define-condition-type &implementation-restriction &violation make-implementation-restriction-violation implementation-restriction-violation?) (define-condition-type &lexical &violation make-lexical-violation lexical-violation?) (define-condition-type &syntax &violation make-syntax-violation syntax-violation? (form syntax-violation-form) (subform syntax-violation-subform)) (define-condition-type &undefined &violation make-undefined-violation undefined-violation?) )
3.psyntax-buildscript-mosh.ss
buildscript に2カ所手を入れる。
(define scheme-library-files '("psyntax/compat.ss" "psyntax/internal.ss" "psyntax/config.ss" "psyntax/library-manager.ss" "psyntax/builders.ss" "psyntax/expander-mosh.ss" "../../r6rs-examples/mosh/condition.ss" ; 追加 "psyntax/main-mosh.ss"))
identifier->library-map に追加。
(&condition-rtd) (&condition-rcd) (&message-rtd) (&message-rcd) (&warning-rtd) (&warning-rcd) (&serious-rtd) (&serious-rcd) (&error-rtd) (&error-rcd) (&violation-rtd) (&violation-rcd) (&assertion-rtd) (&assertion-rcd) (&irritants-rtd) (&irritants-rcd) (&who-rtd) (&who-rcd) (&non-continuable-rtd) (&non-continuable-rcd) (&implementation-restriction-rtd) (&implementation-restriction-rcd) (&lexical-rtd) (&lexical-rcd) (&syntax-rtd) (&syntax-rcd) (&undefined-rtd) (&undefined-rcd) (&i/o-rtd) (&i/o-rcd) (&i/o-read-rtd) (&i/o-read-rcd) (&i/o-write-rtd) (&i/o-write-rcd) (&i/o-invalid-position-rtd) (&i/o-invalid-position-rcd) (&i/o-filename-rtd) (&i/o-filename-rcd) (&i/o-file-protection-rtd) (&i/o-file-protection-rcd) (&i/o-file-is-read-only-rtd) (&i/o-file-is-read-only-rcd) (&i/o-file-already-exists-rtd) (&i/o-file-already-exists-rcd) (&i/o-file-does-not-exist-rtd) (&i/o-file-does-not-exist-rcd) (&i/o-port-rtd) (&i/o-port-rcd) (&i/o-decoding-rtd) (&i/o-decoding-rcd) (&i/o-encoding-rtd) (&i/o-encoding-rcd) (&no-infinities-rtd) (&no-infinities-rcd) (&no-nans-rtd) (&no-nans-rcd)
4.expand
psyntax-buildscript を実行して psyntax.pp を新たに作る。
5. rtd/rcd を動的にセットする
make-record-type-descriptor で record-type-descriptor を作るときに parent rtd が &condition の場合に '名前-rtd => rtd というマッピングを登録する。
例えば &message が登録された場合は &message-rtd を登録する。
同じく make-record-constructor-descriptor では -rcd を登録する。
これは psyntax による要請。
これで動くよ。