制御命令
プログラムの流れ
分岐や繰り返しといった、プログラムの流れの制御について解説します。繰り返しを行なうのにはいくつかの方法があります。リスト処理で繰り返しに相当する操作をすることもできます。
リスト処理の基本も参照してください。
条件判断: if(<bool>,<expr>)
解説: <bool> が真であれば、<expr> が評価(実行)されます。この場合、<expr> の値が返されます。そうでなければ、
___
が返されます。
if
が使われるのは次のような場合です。
例:
if(x<0,println("x は負です"))
このコードでは、x が負の値であれば、"x は負です"が印字(表示)され、その文字列がそのまま戻り値として返されます。負の値でなければ、何も印字されず、
___
が返されます。
条件分岐: if(<bool>,<expr1>,<expr2>)
解説: 条件 <bool> が真であれば <expr1> が評価され、そうでなければ <expr2>が評価されます。それぞれ、評価された値が返されます。したがって、この
if
文は、if/then/else に相当します。 この条件分岐の典型的な使用法は2つあります。まず、条件によって場合分けをするときに使います。.
例:
if(x<0,
println("x は負です"),
if (x>0,
println("x は正です"),
println("x は零です")
)
)
このコードでは、
x
の値が正か、負か、ゼロかを表示します。
第2の使い方は、 <bool> の条件により特定の値を返したいときです。これは関数の定義としてよく使います。
例:
このコードは、xの絶対値を返す関数
f(x)
を定義します。
例:
A.color=if(A.x>0,(1,0,0),(0,0,1))
このコードでは、点
A
の色を、そのx座標の正負により、赤か青に設定します。
トリガー: trigger(<bool>,<expr>)
解説: trigger
は
if
とよく似ています。
if
とは対照的に、
trigger
は動的意味合いを持ちます。 <expr> は、条件 <bool> が
false
から
true
に変わったときに評価されます。たとえば、何かの要素をドラッグしているとき、<bool>が
false
から
true
に変化したことを察知して <expr> を評価(実行)します。 この演算子の目的は、要素をドラッグしているときに何らかのイベントが起きたかどうかを判断することです。 次のコードはそのような例です。
例:
trigger(A.x<0,println("A はxが負の半平面に入りました"))
trigger(A.x>0,println("A はxが正の半平面に入りました"))
このコードでは、点
A
が
y軸を横切るとメッセージを出します。
while ループ: while(<bool>,<expr>)
解説: while
演算子は <bool>が真である間、<expr> を評価します。最後の評価値が関数の値として返されます。
例:
x=0;
sum=0;
erg=while(x<4,
x=x+1;
sum=sum+x;
println(x+" --> "+sum);
sum
);
println(erg);
このコードは次の結果を出します。
1 --> 1
2 --> 3
3 --> 6
4 --> 10
10
実行の結果、
erg
の値は
10
になります。
繰り返し: repeat(<number>,<expr>)
解説: この演算子は CindyScript のなかで最も簡単な繰り返しの演算子です。 <expr>- は <number> 回繰り返され、最後の評価結果が戻ります。 <expr> が評価されている間、実行変数
#
は繰り返しの回数を数えます。
例:
repeat(100,
println(#+" の平方は "+#^2)
)
このコードでは、最初の100個の整数を、その平方とともにリストアップします。
修飾子: repeat
ループにはいろいろな修飾子があります。修飾子として、開始値、終了値、ステップ値が使えます。 修飾子
start
は、ループの開始の値を設定します。修飾子
stop
は、ループの終了の値を設定します。修飾子
step
は、ステップの値を設定します。修飾子は任意に組み合わせることができます。3つの修飾子がひとつもなければ、 <number> 回だけ繰り返します。 修飾子には実数のみが使えます。次の表は、いくつかの修飾子の使い方を示します。
スクリプト: | 出力:
|
repeat(6, println(#+" "))
| 1 2 3 4 5 6
|
repeat(6, start->4, println(#+" "))
| 4 5 6 7 8 9
|
repeat(6, stop->2, println(#+" "))
| -3 -2 -1 0 1 2
|
repeat(6, step->3, println(#+" "))
| 1 4 7 10 13 16
|
repeat(6, stop->12,step->4, println(#+" "))
| -8 -4 0 4 8 12
|
repeat(6, start->3,step->2, println(#+" "))
| 3 5 7 9 11 13
|
repeat(6, start->3,stop->4, println(#+" "))
| 3 3.2 3.4 3.6 3.8 4
|
repeat(6, start->0,stop->-3, println(#+" "))
| 0 -0.6 -1.2 -1.8 -2.4 -3
|
repeat(6, start->3,stop->4,step->0.4, println(#+" "))
| 3 3.4 3.8
|
繰り返し: repeat(<number>,<var>,<expr>)
解説: この演算子は、実行変数が<var>に割り当てられるという1点を除いては、
repeat(<number>,<expr>)
と同じです。これは、異なる実行変数を使って、ループを入れ子にすることを考慮しています。
例:
repeat(10,i,
repeat(10,j,
draw((i,j))
)
)
このコードは、 10 × 10 の点列を描きます。
全走査ループ: forall(<list>,<expr>)
解説: この演算子の第1引数 <list> はリストです。 <expr> がリストのそれぞれの要素に対して評価されます。 実行変数
#
はリストのそれぞれの要素になります。
例:
a=["this","is","a","list"];
forall(a,println(#))
このコードは次の結果を出力します。
全走査ループ: forall(<list>,<var>,<expr>)
解説: これは、実行変数が <var> であること以外は
forall(<list>,<expr>)
と同じです。
強制的評価: eval(<expr>,<modif1>,<modif2>,…)
解説: この演算子では、<expr>の内容を強制的に評価します。<expr>内の変数は modifier のリストにある変数で置き換えられます。置き換える変数は局所変数です。実行後はもとの値に書き戻されます。
例:
このコードは、評価値を
7
とします。
変数の管理
局所変数の作り方と削除のしかたを説明します。CindyScriptでは型を明示しなくても自動的に変数が作られ、それは大域的変数です。
再帰的な関数や、関数ライブラリを作るときには、局所変数が必要になることがあります。
変数の作成: createvar(<varname>)
および
変数の削除: removevar(<varname>)
解説: これらの演算子は、局所変数の生成について手動で管理するのを助けます。
createvar(x)
は新しい変数
x
を作り、前の値はスタックに入れられます。
removevar(x)
は局所変数を削除して、スタックの値を書き戻します。通常、変数は明示的に作られる必要はないと思ってください。それらは、最初に使われるときに自動的に作られます。
createvar
と
removevar
は、コードの特定の部分に、ある名前で変数を予約したいときだけ使われます。
例:
x=10;
println("x is now "+x);
createvar(x);
x=5;
println("x is now "+x);
removevar(x);
println("x is now "+x);
このコードの実行結果は次の通りです。
x is now 10
x is now 5
x is now 10
関数内で局所変数を使う: regional(name1,name2,...)
解説: この関数は、ユーザーが定義する関数の最初に使います。引数にある複数の変数を局所変数として定義します。local 関数とほとんど同じですが、local関数とは違って、関数内での処理が終わると自動的に消滅します。したがって、releaseなどで消去する手続きは不要です。local関数より便利に使えます。
CindyScript で、変数は一種の持続性を持ちます。ある変数の値が計算で設定されると、それが変更されるまでそのまま残ります。次の演算子を使うと明示的に変数をクリアできます。プログラムの最初の部分で
clear()
文を置くのがしばしば有効になります。
すべての変数をクリアする: clear()
解説: すべての変数をクリアします
特定の変数をクリアする: clear(<var>)
解説: 変数 <var>をクリアします。
オブジェクトのキー変数へのハンドル: keys(<var>)
解説: <key>=<something> で宣言した <object>のキー変数のリストを得る。
例: オブジェクトのキー変数を割り当てることができます。次のようなコードで割当をします。
A:"age"=34;
A:"haircolor"="brown";
割当をした結果はつぎのような構文で利用できます。
println(A:"age");
println(A:"haircolor");
keys
関数は、オブジェクトに割り当てられた変数のリストを取得します。したがって、次のコードでは
リスト
["age","haircolor"]
が表示されます。