仕組みはいたって簡単で、総称関数
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