Special Operator TAGBODY
tagbody {tag | statement}* => nil
tag - goのタグ、評価されません。
statement - compound-form、下記の説明通り評価されます。
tagによってラベル付けされた場所へ制御を移す機能を提供するための レキシカル環境下において、0個か複数のstatementを実行します。
tagbodyのstatementは、左から右の順番で評価され、 それらの値は捨てられます。 もしどんなときでも、残りのstatementがない場合は、 tagbodyはnilを返却します。 しかし、もし(go tag)が評価されたときは、 制御がtagでラベル付けされたボディ部の部分にジャンプします (タグはeqlによって比較されます)。
tagbodyで確立したtagは、レキシカルスコープと動的エクステントを持ちます。 いったんtagbodyを終えると、 そのボディのtagに対するgoはもはや有効ではありません。 goのジャンプは、 そのgoが含まれるもっとも内側のtagbody以外への ものも許されます。 tagbodyのtagの確立は、 ただ同じ名前の他のタグをシャドウします。
ボディのどの要素がtagでどの要素がstatementであるかの判断は、 その要素のマクロ展開の前に行われます。 もしstatementがマクロフォームで、 そのマクロ展開がアトムである場合、 そのアトムはtagではなくstatementとして扱われます。
Examples:
(let (val)
(tagbody
(setq val 1)
(go point-a)
(incf val 16)
point-c
(incf val 04)
(go point-b)
(incf val 32)
point-a
(incf val 02)
(go point-c)
(incf val 64)
point-b
(incf val 08))
val)
=> 15
(defun f1 (flag)
(let ((n 1))
(tagbody
(setq n (f2 flag #'(lambda () (go out))))
out
(prin1 n))))
=> F1
(defun f2 (flag escape)
(if flag (funcall escape) 2))
=> F2
(f1 nil)
>> 2
=> NIL
(f1 t)
>> 1
=> NILなし。
なし。
次の図のマクロは、暗黙のtagbodyを持ちます。
do |
do-external-symbols |
dotimes |
do* |
do-symbols |
prog |
do-all-symbols |
dolist |
prog* |
Figure 5-10. 暗黙のtagbodyをもつマクロ