#:g1: CMU AIレポジトリ探検: XREF

Posted 2013-01-21 16:14:00 GMT

XREFとは何か

 XREFとは、1990年あたりに、Mark Kantrowitz氏によって書かれた、コールグラフを表示するユーティリティです。当時、Kantrowitz氏は、CMUで、Portable Utilities for Common Lispという主に当時のフリーな処理系のユーティリティを充実させようというプロジェクトを立ち上げていて、XREFもそうしたツール群の一つです。

ソース:
http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/tools/xref/0.html

 例の如くASDF化してgithubに置いてみました

使ってみる


;;; ********************************
;;; Test Source Program ************
;;; ********************************

(defun top-level () 
  "Top level function with null lambda list."
  (let* ((input (read))
	 (key (car input)))
    (declare (special key))
    (case key
      (quit
       (return (values (frob (rest input)) 'quit)))
      (otherwise
       (cond ((member key '(foo bar baz))
	      (barf key (rest input)))
	     (t
	      (frowz (rest input) :key key)))))))

(defun frob (items) "Here we test mapcar." (mapcar #'frob-item items)) (defun frob-item (item) "Here we test apply." (apply #'append-frobs item)) (defun barf (key &optional items) "Optional args test." (cons key (frowz items))) (defun frowz (items &key key) "Keyword args test." (dolist (item items) (let ((frowz (if (eq key 'quit) (intern (format nil "FOO~A" (round (+ (length (process-keys items)) 10))) 'keyword) (snarf-item item)))) (when (string-equal frowz (process-key key)) (setf (node-position key) 12) (return frowz))))) (defun process-key (key) (funcall #'symbol-name-key key))

というソースコードのファイルfoo.lispがあったとします。
ファイルの読み込み:

(xref:xref-file (asdf:system-relative-pathname 
                 :ai.lang.lisp.code.tools.xref "test-source.lisp"))
;>>  Cross-referencing file /l/src/rw/ai.lang.lisp.code.tools.xref/test-source.lisp.
;>>  ......
;>>  6 forms processed.
;=>  <no values>
  
コールツリーの表示:

(xref:print-caller-trees)
;>>  Rooted calling trees:
;>>    TOP-LEVEL
;>>       FROB
;>>          FROB-ITEM
;>>             APPEND-FROBS
;>>       BARF
;>>          FROWZ
;>>             PROCESS-KEYS
;>>             SNARF-ITEM
;>>             PROCESS-KEY
;>>                SYMBOL-NAME-KEY
;>>             NODE-POSITION
;>>       FROWZ
;>>          PROCESS-KEYS
;>>          SNARF-ITEM
;>>          PROCESS-KEY
;>>             SYMBOL-NAME-KEY
;>>          NODE-POSITION
;=>  NIL
   
frowzを呼出しているもの一覧

(xref:list-callers 'frowz)
;=>  (BARF TOP-LEVEL)
;    T

itemという変数/関数を利用しているもの一覧

(xref:list-users 'items)
;=>  NIL
;    NIL
;    (FROWZ BARF FROB)

まとめ

 SLIMEのwho-callsでは、CLISPとABCLで、このXREFを利用しているらしく、よりポータブルに書き換えられたソースが同梱されているようです。ざっくり全体の呼び出しツリーを眺めたいこともたまにあるので、そういう場合に利用してみるのも良いのではないでしょうか。

comments powered by Disqus