制御構造

条件分岐 if

AutoLISP関数
(if test_expr then_expr [else_expr])
test_expr,then_expr,else_expr : 式
条件に応じて式を評価します。
戻り値 : 評価された then_expr あるいは else_expr の値、または nil

if 関数は、条件が nil でないか nil かに応じて評価する式を切り替えます。戻り値は条件に応じて評価された式の値です。

具体的には、test_expr 式が評価され、それが nil 以外なら then_expr 式が、nil ならelse_expr 式が実行されます。なお、if 関数も特殊形式の関数です。test_expr 式が評価されるのと同時に、then_expr 式や else_expr 式があらかじめ評価されることはありません。

(initget 1 "Yes No")             ;キーワードの設定
(setq s (getkword "¥n 選択してください(Yes/No)"))
(if (= s "Yes")
    (princ "YES が選択されました")
    (princ "NO が選択されました")
)

上記の実行結果はコマンドラインでは次のように表示されます。

選択してください(Yes/No)y⏎
YES が選択されました

then_expr 式や else_expr 式は一つの式を表すので、複数の式を並べたい場合は progn 関数を用います。この progn はよく忘れるので、最初から書くのを習慣にしておいて、コードが完成してから削除する方が良いでしょう。他でみられるような「暗黙の progn」は働きません。

else_expr 式が省略されていて test_expr 式が nil となった場合は、if 関数は nil を返します。これは、他の手続き型言語で手続きの経路が変わるのに対して、関数型言語の特徴を表しています。

_$ (if nil T)⏎
nil

上の例は test_expr 式は必ず nil ですが、else_expr 式がありません。その場合は nil が返ってきています。

多条件分岐 cond

AutoLISP関数
(cond [(test result ...) ...])
test, result : 式
多分岐条件関数としての機能を果たします。
戻り値 : 最後に評価された result の値、または nil

多くの選択肢がある場合は if 関数よりcond 関数を使用した方がわかりやすく記述できます。test 式で表された条件が順に評価され nil 以外になった場合に result 式が実行されます。条件にマッチした場合は、以降のケースは無視されます。また、いずれの選択肢にも該当しなかった場合 の処理を書きたい場合は、test 式の部分を Tとした分岐を最後に加えておきます。この記述が無く、該当する選択枝が無かった場合は、cond 関数は nil を返します。

(initget 1 "Yes No Cancel Help")         ;キーワードの設定
(setq s (getkword "¥n 選択してください(Yes/No/Cancel/Help)"))
(cond
    ((= s "Yes") (princ "YES が選択されました"))
    ((= s "No") (princ "NO が選択されました"))
    ((= s "Cancel") (princ "CANCEL が選択されました"))
    ( T (princ "HELP が選択されました"))
)

上記の実行例はコマンドラインでは次のように表示されます。

選択してください(Yes/No/Cancel/Help)c⏎
CANCEL が選択されました

(test result ...) のカッコ内であれば、「暗黙の progn」が働き、progn を用いることなく result 式を複数並べることができます。

誤差

if 関数や cond 関数といった条件分岐に実数を使う場合は、誤差によってプログラムが思い通りの動作をしない場合があるので注意してください。

例えば、ある値(実数)が、「0.0 より大きいとき」「0.0 のとき」「0.0 より小さいとき」といった場合分けを行うことはよくあります。実際の計算誤差はもっと小さいですが、誤差が±0.1あるとします。その場合、0.1という値を評価しようとするとき、正しく 0.1 なのか、 0.0 が計算誤差によって 0.1 になったものなのか判別が出来ません。実数を扱っている場合は、常に評価の順番と誤差を念頭においてください。

定数回繰り返し repeat

AutoLISP関数
(repeat int [expr...])
int : 整数
expr : 式
指定された回数だけexpr 式を評価し、最後の式の値を返します。
戻り値 : 最後に評価された expr の値、または nil

repeat 関数は、int 引数で指定した回数、expr 式の評価を繰り返します。他の手続き型言語で for 文に似ていますが、インデックス用の変数はありません。

repeat 関数の戻り値は、最後に評価された expr 式の値を返します。

(setq i 0)
(repeat 5
    (princ (strcat "¥ni = " (itoa i))) (setq i (1+ i))
)

上記の実行結果はコマンドラインでは次のように表示されます。

i = 0
i = 1
i = 2
i = 3
i = 4

(repeat int [expr...]) のカッコ内であれば、「暗黙の progn」が働き、progn を用いることなく expr の式を複数並べることができます。

ループ while

AutoLISP関数
(while test_expr [expr...])
test_expr , expr : 式
test_expr 式を評価して nil でなければ、expr 式を評価します。 test_exp 式の評価が nil になるまでこの処理を繰り返します。
戻り値 : 最後に評価された expr の値

while 関数は、test_expr 式が nil になるまで expr 式の実行を繰り返します。

while 関数の戻り値は、最後に評価された expr 式の値を返します。while 関数の中で、最後に実行されたのは nil となった test_expr ではないかと思う方もおられるでしょうが、戻り値は最後の expr 式です。

(princ "¥n 数字当てゲーム")
(setq answer 54
      input  -1
)
(initget 7) ;キーワードの設定(null と 0 と負数は不可)
(while (/= answer input)
    (setq input
            (getint "¥n 私は何?(数字の1 から100 の整数を選んでください)")
    )
    (cond ((> input 100)
           (princ "範囲が大きすぎます")
          )
          ((< answer input)
           (princ "もっと小さいです")
          )
          ((> answer input)
           (princ "もっと大きいです")
          )
          ((= answer input)
           (princ "正解!")
          )
    )
)

上記の実行結果はコマンドラインでは次のように表示されます。

数字当てゲーム
私は何?(数字の1 から100 の整数を選んでください)25
もっと大きいです
私は何?(数字の1 から100 の整数を選んでください)75
もっと小さいです
私は何?(数字の1 から100 の整数を選んでください)150
範囲が大きすぎます
私は何?(数字の1 から100 の整数を選んでください)54
正解!

(while testexpr [expr...]) のカッコ内であれば、「暗黙の progn」が働き、progn を用 いることなく expr の式を複数並べることができます。

他の手続き型言語で repeat until 文にあたる関数は AutoLISP にはありません。また、リスト をイテレータで処理を繰り返す場合は foreach 関数を参照してください。

終了

AutoLISP関数
(exit)
(quit)
エラーを発生させて、現在の実行を強制的に終了します。
戻り値 : なし

exit 関数または quit 関数を呼び出すと、「quit/exit による中止」というエラーが発生し、プログラムの実行を終了します。エラーが発生した場合は*error* 関数を適切に設定しておくことで事後処理を行った上で、プログラムを終了させることができます。

exit 関数とquit 関数に差はありません。