#:g1: compiler:style-checkerの紹介

Posted 2014-08-06 23:30:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の219日目です。

compiler:style-checkerとはなにか

 compiler:style-checkerは、Symbolics Generaが提供するコンパイル時にスタイルチェックをかけるための仕組みです。

パッケージ情報

パッケージ名compiler:style-checker
参考サイトSymbolics Genera 8: Program Development Utilities (PDF)

探ってみる

 Symbolicsのスタイルチェッカーは、大体Genera 5(1982年)位から提供されているようで、探してみたらTI Explorerにもありました。
大まかな仕組みとしては、チェックしたい関数にスタイルチェッカーを登録(複数登録可)しておくと、コンパイル時に順にフォームをチェックしていくというものです。

(defun calfo (number &rest other-args)
  )

こんな関数があったとして、第一引数はnumber型であることを期待しているとすれば、

(defun (compiler:style-checker first-arg-must-be-numeric 
                               calfo) 
       (form)
  (destructuring-bind (ignore number &rest ignore) form
    (when (and (compiler:constant-form-p number)
               (not (numberp 
                     (compiler:constant-evaluator number))))
      (warn "The first argument ~S to ~S is not a number." 
            number 'calfo))))

こんな感じでスタイルチェッカーを登録すると、コンパイル時にフォームに対して検査を実行します。defunに

(compiler:style-checker first-arg-must-be-numeric calfo)

なんていう名前が指定されているのがCommon Lispからすると目新しいですが、compiler:style-checkerに登録するための形式です。
Genera 6以前は、関数名のシンボルのcompiler:style-checkerプロパティに登録しておくという方式だったようで、この場合は、

(defun (:property calfo compiler:style-checker) 
       (form)
  (destructuring-bind (ignore number &rest ignore) form
    (when (and (compiler:constant-form-p number)
               (not (numberp 
                     (compiler:constant-evaluator number))))
      (warn "The first argument ~S to ~S is not a number." 
            number 'calfo))))

みたいになるのかと思います(実行環境がないので想像)。
これだと複数登録できないので後の方式に拡張されたのか、シンボルのplistは使いたくなかったのかは良く分かりません。

 TI Explorerだと、シンボルのプロパティに登録していきますが、compiler:add-style-checkerというのを使うようです。

(defun first-arg-must-be-numeric (form)
  (destructuring-bind (ignore number &rest ignore) form
    (when (and (compiler:constant-form-p number)
               (not (numberp 
                     (compiler:constant-evaluator number))))
      (warn "The first argument ~S to ~S is not a number." 
            number 'calfo))))

(compiler:add-style-checker calfo first-arg-must-be-numeric)

とりあえず、こんな感じで登録すると、コンパイル時に

(defun foo ()
  (calfo 'foo))
;w> The first argument FOO to CALFO is not a number.

のようなチェックを実行することができます。

make-obsolete

スタイルチェッカーと同様の仕組みを利用したものに make-obsolete というのがあります。

(make-obsolete latumofis "obsolete: use badial")

のようにすると、非推奨の関数を利用した場合に出す警告をユーザーが追加することができたりします。

関連

まとめ

 今回は、compiler:style-checkerを紹介してみました。
以前SBCLの処理系を拡張してスタイルチェッカーを追加してみようと思ったことがありましたが、スタイルチェッカーを付けるためにフックできるような統一的な場所がないようでした。処理系がスタイル警告を出している場所も処理対象のフォームに固有なことが多く散らばっているようです。
言語処理系と開発環境がごっちゃになったCommon Lispのような言語では、スタイルチェッカーのようなものもユーザーがカスタマイズできると嬉しい気がしますが、Lispマシン上の処理系以外で提供しているものはどうもないようです。

comments powered by Disqus