Shibuya.lisp Hackathon#1
Shibuya.lisp Hackathon #1 : ATNDに行ってきました。
swank-gaucheの機能追加を行なおうと思ったのですが、思う様には行きませんでした。
ユニットテストを書こうとか、プレゼンテーションストリームを実装しようとかいろいろ迷いましたが、手続きの定義箇所にジャンプする機能(slime-edit-definition)を実装してみることにしました。
slime-edit-definitionの実装をするには、swank側では、find-definitions-for-emacsという手続を定義すればよさそうです。この関数はシンボルが定義されたファイル名とoffsetを返します。
そこで、gaucheが持っている情報にアクセスする方法を調査しました。
エラー発生時には、ファイル名と行番号が表示されるのでそのあたりから見ていきます。
Scm_ShowStackTrace()でスタックトレースを表示しています。スタックトレースでは、スタックに積まれている手続きのファイル名と行番号を表示しています。
Scm_ShowStackTrace()を見ると、ファイル名と行番号の情報をとるの、Scm_PairAttrGet()の模様。
これが、swank-gaucheから使えれば、定義位置の特定ができそうです。
ソースを調べたところ、似た名前の手続き(pair-attribute-get)がgauche.internalで定義されていました。
このpair-attribute-getで情報がとれるか実験します。
gauche.internal> (pair-attribute-get '(1 2 3) 'source-info) ("(input string port)" 1) gauche.internal> (pair-attribute-get (cons 1 2) 'source-info) *** ERROR: No value associated with key source-info in pair attributes of (1 . 2) Stack Trace: _______________________________________ 0 (with-ports in out out fun) At line 373 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" 1 (with-ports in out out fun) At line 373 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" 2 (cdr sexp) At line 397 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" 3 (write-return `(:ok ,(apply (swank-gauche: (car sexp)) (cdr sexp)) ... At line 396 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" 4 (write-abort "Not Impremented: ~s" (car sexp)) At line 387 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" 5 (dispatch-event event) At line 142 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" 6 (do ((event (event-dequeue!) (event-dequeue!))) ((not event)) (dis ... At line 140 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" 7 (do ((packet (read-packet) (read-packet))) ((eof-object? packet) ( ... At line 136 of "/home/takayuki/scm/swank-gauche/swank-gauche.scm" ; Evaluation aborted on eval (swank:listener-eval (pair-attribute-get (cons 1 2) 'source-info) ). gauche.internal>
取れそうです。
consで作ったpairには当然ながらsource-infoは付いていません。
gauche.internalをuseしようとしましたが、gauche.internalはuseできない様です。
そこで、select-moduleした後にimportして使用することにしました。が、importしてみたけど、exportされていないシンボルの様子。
gauche.internal> (module-exports (find-module 'gauche.internal)) () gauche.internal>
というか、gauche.internalは何もexportしていません・・・。あたりまえといえばあたりまえですが。
global-variable-refを使って、pair-attribute-getの値を参照することにします。
あとは、手続きから、元となったpairを取得する方法が分かれば、ジャンプの機能を実装できそうです。
ちなみに、source-infoはread_list()かread_quoted()で付けられていました。
とここで時間切れで終了です。