OCamlのannotファイルの読み方
ocamlcやocamloptでnyan.mlを-annotオプションを付けてコンパイルするとnyan.annotファイルが生成される。
このファイルにはコンパイルするときに得られた識別子のスコープとか式の型とか関数呼び出しが末尾再帰かそうでないかとかの情報が含まれています。例えばテキストエディタが末尾再帰をハイライトする時にこのファイルを使えます。
annotファイルのフォーマットは中身を見れば大体分かるだろうけど、取り敢えず使いそうな事をメモしておきます。
この記事は雰囲気を感じ取って書いています。正式なフォーマットの解説とかあれば教えてください。
*
はdon’t careだと思ってください。
annotファイルがどうとか以前に僕はOCaml自体についても初心者なので変なこと書いてるかもです。指摘していただけるとありがたいです。
全体
情報はそれぞれの式や識別子に対して
"ファイル名1" * * 開始位置 "ファイル名2" * * 終了位置 情報名1 ( 情報の詳細 ) 情報名2 ( 情報の詳細 ) ...
という形式で記述されています。
“ファイル名1"の"開始位置"から"ファイル名2"の"終了位置"までがその式や識別子の書かれている場所です。普通は"ファイル名1"と"ファイル名2"は同じになると思います。
情報名1や情報名2は型とか識別子とかそういうのです。
例えば
"main.ml" * * 8 "main.ml" * * 11 type( int -> int )
って書いてあると先頭から8〜11の位置に書かれてあるものの型がintからintへの関数なんだなーって分かります。
識別子
識別子の宣言に対しては
ident( def 識別子 "ファイル名" * * 開始位置 "ファイル名" * * 終了位置 )
という情報がつきます。これは指している文字列は宣言された識別子であり、そのスコープは開始位置から終了位置であるということを示します。
また変数の使用については
ident( *_ref 名前 "ファイル名" * * 開始位置 "ファイル名" * * 終了位置 )
という情報がつきます。これは指している識別子が"名前"という名前の変数であり、その変数は開始位置から終了位置で宣言されていることを示します。
この"名前"はモジュール名込みの名前っぽいです。
関数呼び出し
関数呼び出しが末尾再帰であれば
call( tail )
非末尾再帰であれば
call( stack )
という情報がつきます。