Next: Backtracking, Previous: Instrumenting Macro Calls, Up: Instrumenting Macro Calls
マクロ呼び出しの引数のあるものは評価し別のものは評価しない場合には、
edebug用仕様に仕様リスト(specification list)が必要になります。
複数の引数に一致する仕様リストの要素もありますが、
後続の要素の処理を修飾する要素もあります。
後者は仕様キーワード(specification keyword)と呼ばれ、
(&optional
のように)‘&’で始まるシンボルです。
仕様リストには、それ自体がリストである引数に一致する部分リストや グループ化に使うベクトルを含んでもかまいません。 部分リストやグループは仕様リストを階層に分けます。 仕様キーワードはそれらを含む部分リストやグループの残りに適用されます。
仕様リストに選択肢や繰り返しが含まれる場合、 実際のマクロ呼び出しに一致させるにはバックトラックが必要な場合もあります。 詳しくはSee Backtracking。
edebug用仕様では、正規表現による一致と文脈自由文法の構文を使えます。 対応した括弧に囲まれた部分リスト、フォームの再帰的処理、 間接仕様による再帰です。
仕様リストの要素に指定できるものとそれらの意味を以下に示します。
sexp
form
place
setf
構文のように値を格納する場所。
body
&rest form
の省略形。
以下の&rest
を参照。
function-form
function
ではなくquote
でクォートされるときに有用である。
というのは、ラムダ式の本体をいずれかの方法で処置するからである。
lambda-expr
&optional
数個の省略可能な要素に省略不可な要素を続けるには、
[&optional
specs...]
を使う。
数個の要素がすべて一致するかまったく一致しないことを指定するには、
&optional [
specs...]
を使う。
以下のdefun
の例を参照。
&rest
数個の要素のみを繰り返すには[&rest
specs...]
を使う。
各繰り返しですべてが一致するような数個の要素を指定するには、
&rest [
specs...]
を使う。
&or
&or
は失敗。
&or
に続く各要素は1つの選択肢を表す。
複数の要素を1つの選択肢としてグループにまとめるには、
それらを[...]
で囲む。
¬
&or
を使ったかように後続の要素を選択肢として一致させるが、
どれかが一致すると仕様は失敗。
どれにも一致しなければ、仕様¬
は成功。
&define
&define
はリスト仕様の最初の要素である必要がある。
nil
gate
let
を参照。
シンボルにedebug用仕様があれば、
この間接仕様は、シンボルのかわりに使われる仕様リストであるか、
引数を処理するために呼び出される関数であること。
仕様は、マクロ向けにdef-edebug-spec
で定義した仕様であってもよい。
以下のdefun
の例を参照。
さもなければ、シンボルは述語であること。
述語は引数で呼び出され、述語がnil
を返すと仕様は失敗する。
いずれの場合でも、当該引数は処置されない。
適当な述語には、symbolp
、integerp
、
stringp
、vectorp
、atom
がある。
[
elements...]
"
string"
'
symbolと等価であるが、
文字列のほうが望ましい。
(vector
elements...)
(
elements...)
部分リスト仕様はドット対リストでもよく、その場合、
対応するリスト引数はドット対リストである。
あるいは、ドット対リスト仕様の最後のcdrは
((spec . [(more specs...)])
などの
グループや間接仕様を介した)
別の部分リスト仕様であってもよいが、
それらの要素はドット対ではないリスト引数に一致する。
これは、以下のバッククォートの例のような再帰仕様に有用である。
このような再帰を終らせるうえの仕様nil
も参照。
(specs . nil)
や
(specs . (sublist-elements...))
のような部分リスト仕様は
(specs sublist-elements...)
と等価であることに注意。
&define
のうしろに追加できる仕様の一覧を以下に示します。
以下のdefun
の例を参照してください。
name
定義フォームには単一の名前フィールドがある必要はなく、
複数の名前フィールドを持っていてもよい。
:name
:name
に続く要素はシンボルであること。
定義に対する追加の名前要素として使う。
定義の名前に一意で静的な要素を追加するために使う。
複数あってもよい。
arg
lambda-list
def-body
body
に似ているが、
定義本体は定義に関連した情報を調べる異なるedebug呼び出しで処置する必要がある。
定義内のフォームの最上位レベルのリストにはdef-body
を使う。
def-form
def-body
に似ているが、
フォームのリストではなく単一のフォームに一致するものに使う。
特別な場合として、def-form
は
フォームを実行したときにトレース情報を出力しないことを意味する。
以下のinteractive
の例を参照。