Next: 仕様でのバックトレース, Previous: マクロ呼び出しのインストルメント, Up: Edebugとマクロ [Contents][Index]
あるマクロ呼び出しにおいて、いくつかの引数は評価されても、それ以外の引数は評価されないような場合には、Edebug仕様のために仕様リスト(specification
list)が必要となります。仕様リスト内のいくつかの要素は1つ以上の引数にマッチしますが、それ以外の要素は以降に続くすべての引数の処理を変更します。後者は仕様キーワード(specification
keywords)と呼ばれ、(&optional
のように)‘&’で始まるシンボルです。
仕様リストはそれ自身がリストであるような引数にマッチする部分リスト(sublist)、あるいはグループ化に使用されるベクターを含むかもしれません。したがって部分式とグループは仕様リストをレベル階層に細分化します。仕様キーワードは部分式やグループを含むものの残りに適用されます。
仕様リストに選択肢や繰り返しが含まれる場合は、実際のマクロの呼び出しのマッチでバックトラックが要求されるかもしれません。詳細は仕様でのバックトレースを参照してください。
Edebug仕様はバランスのとれたカッコで括られた部分式へのマッチ、フォームの再帰処理、インダイレクト仕様を通じた再帰等の、正規表現によるマッチングとコンテキストに依存しない文法構成を提供します。
以下は仕様リストに使用できる要素と、その意味についてのテーブルです(使用例は仕様の例を参照):
sexp
評価されない単一のLispオブジェクト。インストルメントされない。
form
評価される単一の式。インストルメントされる。評価前にマクロが式のをlambda
でラップしていれば、かわりにdef-form
を使用すること(以下のdef-form
を参照)。
place
汎変数(generalized variable)。ジェネリック変数を参照のこと。
body
&rest
form
の短縮形(以下の&rest
を参照)。評価前にマクロが式のをlambda
でラップしていれば、かわりにdef-form
を使用すること(以下のdef-form
を参照)。
lambda-expr
クォートされないラムダ式。
&optional
仕様リスト内の後続の要素はオプション。マッチしない要素が出現するとEdebugはこのレベルのマッチングを停止する。
後続が非オプションの要素であるような数個の要素をオプションにするだけなら、[&optional
specs…]
を使用する。複数の要素すべてのマッチや非マッチを指定するには、&optional
[specs…]
を使用する。defun
の例を参照のこと。
&rest
仕様リスト内の後続のすべての要素は0回以上繰り返される。しかし最後の繰り返しでは、仕様リスト内のすべての要素にたいするマッチングの前に式が終了しても問題はない。
数個の要素を繰り返すには[&rest
specs…]
を使用する。各繰り返しにおいてすべてマッチしなければならない複数要素を指定するには、&rest
[specs…]
を使用する。
&or
仕様リスト内の後続の各要素は選択肢である。選択肢の1つがマッチしなければならず、マッチしなければ&or
仕様は失敗する。
&or
に続く各リスト要素は単一の選択肢である。複数のリスト要素を単一の選択肢にグループ化するには、それらを[…]
で括る。
¬
後続の各要素は&or
が使用されたときのように選択肢にマッチするが、要素がマッチしたら失敗となる。マッチする要素がなければ何もマッチされないが¬
仕様は成功となる。
&define
フォームを定義する仕様であることを示す。フォームを定義するEdebugの定義は、後刻(フォーム定義の実行後に)保存および実行される1つ以上のコードを含んだフォーム。
フォーム定義自体はインストルメントされない(つまりEdebugはフォーム定義の前後でストップしない)が、フォーム内部は通常はインストルメントされるであろう。&define
キーワードはリスト仕様の最初の要素であること。
nil
カレント引数レベルでマッチさせる引数が存在しなければ成功し、それ以外は失敗する。部分リスト仕様とバッククォートの例を参照のこと。
gate
¶引数はマッチされないがgateを通じたバックトラックは、このレベルの仕様の残りをマッチングする間は無効にされる。これは主に特定の構文エラーメッセージを一般化するために使用される。詳細は仕様でのバックトレース、およびlet
の例も参照のこと。
&error
&error
の後にはedebug仕様のエラーメッセージ(文字列)が続くこと。これはインストルメントをabortして、メッセージをミニバッファーに表示する。
&interpose
残りのコードのパースを関数に制御させる。これは&interpose spec fun
args...
のような形式をとり、Edebugがコードにたいして最初にspecをマッチして、それからspec
にマッチしたコードとともにfun、パース関数pf、最後にargs...を呼び出すことを意味する。パース関数は、残りのコードのパースに使用するための仕様リストを単一の引数として期待する。これは正確に1回呼び出されて、funがリターンすることを期待されるインストルメント済みコードをリターンすること。たとえば(&interpose
symbolp
pcase--match-pat-args)
は最初の要素がシンボルであるようなsexpにマッチしてから、pcase--match-pat-args
はpcase--match-pat-args
に照らしてheadとなるシンボルに対応するspecを照合、その後にそれらを引数として受け取るpfに渡す。
other-symbol
¶仕様リスト内のその他の要素は、述語(predicate)かインダイレクト仕様(indirect specification)である。
シンボルがEdebug仕様をもつなら、インダイレクト仕様(indirect
specification)はシンボル位置に使用されるリスト仕様か、引数を処理するための関数のいずれかである。この仕様はdef-edebug-spec
で定義できる。
シンボルelementの箇所で使用するspecificationを定義する。specificationはリストでなければ鳴らす。
それ以外ならシンボルは述語(predicate)である。述語は引数とともに呼び出されてnil
をリターンしたら、その仕様は失敗して引数はインストルメントされない。
適切な述語としてはsymbolp
、integerp
、stringp
、vectorp
、atom
が含まれる。
[elements…]
¶要素のベクターは要素を単一のグループ仕様(group specification)にグループ化する。このグループ仕様はベクター自体には何も行わない。
"string"
引数はstringという名前のシンボルである。この仕様はsymbolの名前がstringであるようなクォートされたシンボル'symbol
と等価だが、文字列形式のほうが好ましい。
(vector elements…)
引数は要素が仕様内のelementsにマッチするようなベクターである。バッククォートの例を参照のこと。
(elements…)
他のリストは部分リスト仕様(sublist specification)であり、引数は要素が仕様のelementsにマッチするリストでなければならない。
部分リスト仕様はドットリスト(dotted
list)かもしれず、その場合対応するリスト引数はドットリストである。かわりにドットリスト仕様の最後のCDRが、(グループ化やインダイレクト仕様による)他の部分リスト仕様かもしれない(たとえば要素が非ドットリストにマッチする(spec
. [(more
specs…)])
))。これはバッククォートの例のような再帰仕様に有用。このような再帰を終了させるには上述のnil
仕様も参照のこと。
(specs . nil)
のように記述された部分リスト仕様は(specs)
、(specs .
(sublist-elements…))
は(specs
sublist-elements…)
と等価であることに注意。
以下は&define
の後だけに出現する追加仕様のリストです。defun
の例を参照してください。
&name
コードからカレントで定義しているフォーム名を抽出する。これは&name [prestring] spec
[poststring] fun
args...
という形式をとり、Edebugがコードにたいしてspecをマッチしてから結合したカレント名、args...、prestring、spec
にマッチしたコード、poststringとともにfunを呼び出すことを意味する。funが未指定なら、、デフォルトは引数を(前の名前と新しい名前の間に@
を置いて)結合する関数。
name
引数(シンボル)は定義フォームの名前。[&name symbolp]
の省略形。
定義フォームは名前フィールドをもつ必要はなく、複数の名前フィールドをもつかもしれない。
arg
引数(シンボル)は定義フォームの引数の名前である。しかしlambda-listキーワード(‘&’で始まるシンボル)は許されない。
lambda-list
¶これはラムダリスト(ラムダ式の引数リスト)にマッチする。
def-body
引数は定義内のコードのbodyである。これは上述のbody
と似ているが、定義のbodyはその定義に関連する情報を照会する別のEdebug呼び出しでインストルメントされていなければならない。定義内のより高位レベルのフォームリストにはdef-body
を使用する。
def-form
引数は定義内のもっとも高位レベルの単一フォームである。これはdef-body
と似ているが、フォームリストではなく単一フォームのマッチに使用される。特別なケースとしてdef-form
はフォームが実行されるときトレース情報を出力しないことも意味する。interactive
の例を参照のこと。