仕組みはいたって簡単で、総称関数
unbound-variable
を追加して、VMが未定義シンボルを検出したらそれを呼び出すだけ。デフォルトでは普通に&undefined
を投げるんだけど、たとえばこんなメソッドを追加してやるとCLっぽく動くようになる。(import (rnrs) (sagittarius debug) (sagittarius vm) (clos user)) (define-method unbound-variable ((name <symbol>) lib) (format (current-error-port) "**** unbound variable ~s~%" name) (format (current-error-port) "use-value :r1 Input a value to be used instead of ~s~%" name) (format (current-error-port) "store-value :r2 Input a new value for ~s~%" name) (format (current-error-port) "abort :r3 Abort (raise unbound variable error)~%") (let loop () (format (current-error-port) "break >") (case (read) ((:r1) (format (current-error-port) "Use instead of ~a:" name) (read)) ((:r2) (format (current-error-port) "New ~a:" name) (let ((e (read))) (%insert-binding lib name e) e)) ((:r3) (call-next-method)) (else (newline (current-error-port)) (loop))))) (print test) (print test) (print test)正直、これがうれしいかといわれると、微妙なところではあるが。使いどころは無いんだけど、REPL上でデバッグするときに便利だろうか?(ただ、あんまり何も考えてないので、この中で例外投げたらどうなるとか全く気にしてなかったりする・・・HEADにあるけど消すかも・・・)
No comments:
Post a Comment