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 による要請。

これで動くよ。