% Special-Operator TAGBODY
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
をもつマクロ