エラー処理を改善中
psyntax がロードされるまでは R6RS の種々の機能が使えない。その場合の assertion-violation や raise の挙動を決めて実装する。
R6RS ではないときは who, message, irritants を format で文字列にして raise を呼び出すことにする。ユーザーが見るエラー表示を出来るだけ R6RS 時と同じにするため。
次に R6RS 時のデフォルトのハンドラを定義する。これは psyntax の main でやれば良い。
だんだん R6RS らしくなってきた。コンリリースの目標である「遅いけど安定して動く」も少しずつ達成されている。
(let ([args (command-line)] [port (current-error-port)]) (with-exception-handler (lambda (c) (display " Condition components:\n" port) (for-each-with-index (lambda (i x) (cond [(who-condition? x) (format port " ~d. &who: ~a\n" i (condition-who x))] [(message-condition? x) (format port " ~d. &message: ~s\n" i (condition-message x))] [(violation? x) (format port " ~d. ~a\n" i (record-type-name (record-rtd x)))] [(irritants-condition? x) (format port " ~d. &irritants: ~s\n" i (condition-irritants x))] [else (format port " ~d. ~a\n" i (record-type-name (record-rtd x)))])) (simple-conditions c))) (lambda () (load-r6rs-top-level (car args)))))
続いて raise で exception-handler が存在しなかったり、return した場合に処理系を呼び出す throw 手続きを実装。
エラー処理周りがどんどんシンプルになっていくのがうれしい。言語処理系が自分自身に実装された機能を足がかりにまたニョキニョキと成長する感覚ってのは他ではなかなか味わえない。
assertion-violation は raise に依存するが、raise が定義される前に発生するエラーにも対応しないと。危ない危ない。
そして処理系内部のエラー処理を assertion-violation で置き換えつつそのテストを追加する。地味な作業だがここで手を抜くわけにはいかない。