条件およびループ構造Flow-of-Control
LabTalk言語の構造はC言語のそれと似ています。LabTalkは以下の構造をサポートしています。
- 処理を繰り返し実行するループ構造
- 条件の真、偽に応じて処理の実行を制御する分岐構造
ループ構造
すべてのLabTalkのループは、引数としてスクリプトを取ります。 これらのスクリプトは、指定した条件下で繰り返し実行されます。LabTalkには次の4つのループコマンドがあります。
コマンド
|
構文
|
repeat
|
repeat value {script};
|
loop
|
loop (variable, startVal, endVal) {script};
|
doc -e
|
doc -e object {script};
|
for
|
for (expression1; expression2; expression3) {script};
|
LabTalkのforループは、他のプログラミング言語のforループと同じです。 repeat, loop, doc -eループは、他の言語では馴染みがないものですが、簡単に使うことができます。
Repeat
repeatループは一連の操作が変更無く繰り返されるときに使われます。
シンタックス : repeat value {script};
スクリプトscriptを、valueで指定した回数分、またはエラーが起こるまで、またはbreakコマンドが実行されるまで実行します。
例えば、次のスクリプトは、文字列を3回出力します。
repeat 3 { type "line of output"; };
Loop
loop ループは、各ループの処理が問題なく実行されると1つの変数が増加するようなときに使われます。
シンタックス : loop (variable, startVal, endVal) {script};
簡単なカウンタ変数を持つループ構造です。starValの値で変数variableを初期化し、スクリプトを実行します。scriptを実行します。variable を増加し、それがendValより大きいかどうかをチェックします。大きくない場合、script を実行し、ループを継続します。
例えば、次のスクリプトは1から4までの数を出力します。
loop (ii, 1, 4) {type "$(ii)";};
Note:loop コマンドは、for コマンドよりもスクリプトブロックの実行が高速となります。ループを停止ための条件を判定するためLabTalk式の解析を行う必要がないため、高速となります。
Doc -e
doc -eループは、スクリプトを実行してグラフウィンドウのような特定のオブジェクトに対して処理を行うときに使われます。 doc -e ループは、指定したオブジェクトの各インスタンスに対してスクリプトを実行するようにOriginに通知します。
シンタックス : doc -e object {script};
さまざまなオブジェクトタイプはドキュメントコマンドに一覧が載っています。
例えば、次のスクリプトはプロジェクト内のすべてのグラフウィンドウのウィンドウタイトルを出力します。
doc -e P {%H=}
For
forループは、上記以外のすべての状況で使われます。
シンタックス : for (expression1; expression2; expression3) {script};
for ステートメントの中で、expression1 が評価されます。これによって、ループの初期値が指定されます。 次にexpression2 が評価され、その結果が真(0でない)である場合、scriptが実行されます。そして、カウンターの増加を受けて expression3が実行されます。処理が2番目のステップを繰り返し行われます。expression2の結果が偽(0)になった時点でこのループは終了します。 他のexpressionは、カンマで区切られている複数の文から構成することができます。
例えば、次のスクリプトは1から4を出力します。
for(ii=1; ii<=4; ii++)
{
type "$(ii)";
}
Note:loop コマンドはスクリプトブロックの実行が高速となります。
分岐構造
分岐構造により、プログラムは状況に応じて異なるアクションセットを実行できます。 LabTalkは、3つの判断分岐構造を提供します。 if、if-else、switchです。
- ifコマンドは、指定した条件が成り立った場合、つまり、真(非ゼロ値)の場合に、指定したスクリプトを実行する場合に使用します。
- if-elseコマンドは、指定した条件が真(非ゼロ値)の場合、あるスクリプトを実行し、偽(ゼロ)の場合、別のスクリプトを実行する場合に使用します。
- switchコマンドは、2つ又はそれ以上の条件があって、条件を満たした指定スクリプトを実行をする場合に使用します。
If, If-Else
シンタックス :
- if (testCondition) sentence1; [else sentence2;]
- if (testCondition) {script1} [else {script2}]
TestConditionが真である場合、script1が実行されます。表現が条件演算子を含まない場合、その結果がゼロより大きければ真と評価されます。
オプションelseが付加されていて、testConditionが偽(ゼロ)である場合、script2が実行されます。このとき、elseの後にスペースを付けなくてはいけません。文字列は引用符で囲まれていなくてはいけません。文字列の比較には大文字と小文字の区別はされません。
一つの文からなるスクリプトの引数の終わりには、セミコロンを付けます。複数の文からなるスクリプトの引数は、大括弧{}で囲みます。この場合、各々のスクリプトはセミコロンで区切ります。スクリプトを囲む大括弧の後にセミコロンを付ける必要はありません。
例えば、下記のスクリプトは、「Yes!」を表示するメッセージボックスを開きます。
%M = test;
if (%M == "TEST") type -b "Yes!";
else type -b "No!";
下記のスクリプトは、列A内の-1.95以上である最初のポイントを見つけます。
newbook;
col(1)=data(-2,2,0.01);
val = -1.95;
get col(A) -e numpoints;
for(ii = 1 ; ii <= numpoints ; ii++)
{
// これは"真"の時にループを終了する
if (Col(A)[ii] > val) break;
}
if(ii > numpoints - 1)
ty -b No number exceeds $(val);
else
type -b The index number of first value > $(val) is $(ii)
The value is $(col(a)[ii]);
例えば、1つのifステートメントで複数の条件を確かめることができます。
if(a>1 && a<3) b+=1; // 真の場合、bの値を1つ増加させる
&& (論理和) 演算子は、LabTalkでサポートされているいくつかの論理演算子の1つです。
Switch
switchコマンドは、2つ又はそれ以上の条件があって、条件を満たした指定スクリプトを実行をする場合に使用します。例えば、次のスクリプトはbを返します。
ii=2;
switch (ii)
{
case 1:
type "a";
break;
case 2:
type "b";
break;
case 3:
type "c";
break;
default:
type "none";
break;
}
Breakとプログレスバー
LabTalkにはbreak コマンドがあります。 これを実行すると、ループから抜け、任意でスクリプトを終了します。これは、ループ内の分岐構造でよく利用されます。ループのテスト条件を無効にする条件から保護するために使われます。breakコマンドは、ループの処理を表示する現在の処理状況ダイアログボックス(プログレスバー)を表示するのに使うことができます。
Exit
exit コマンドは、予めフラグを強制的に終了するようセットしていれば、Originを終了する際のメッセージボックスが表示されます。
Continue
continue コマンドは、ループ内で使うことができます。これを実行すると、ループスクリプト内の残りの部分は無視され、インタプリタは次のループを実行します。これは、ループ内の分岐構造と一緒に使われ、ループスクリプトでの処理から不正な値を除外できます。
例えば、下記のforループにおいて、iiがゼロより小さい場合に、continue文はtype文を飛ばします。
for (ii = -10; ii <= 10; ii += 2)
{
if (ii < 0)
continue;
type "$(sqrt(ii))";
}
スクリプトファイル内のセクション
ラベルコントロールダイアログにスクリプトを入力するだけでなく、Originスクリプトファイル(OGS)として保存することもできます。Originスクリプトファイルは、ASCIIテキストファイルで、1行以上のLabTalkステートメントで構成されています。 複数ステートメントを複数セクションに分けることができます。セクション は、次のようにセクション名を角括弧で囲んで、この内容だけを宣言します。
[SectionName]
別のセクションの宣言が現れるまで、宣言したセクション内にあるスクリプトがそのセクションに属します。 セクションを持つスクリプトのフレームワークは、次のようなものです。
...
Scripts;
...
[Section 1]
...
Scripts;
...
[Section 2]
...
Scripts;
...
各スクリプトは、新しいセクションが現れるか、returnステートメントが実行されるか、エラーが発生するまで順番に実行されます。セクション内のスクリプトを実行するには、次のようなコマンドを使います。
run.section(FileName, SectionName)
command.FileName が含まれていないとき、現在実行されているスクリプトファイル内のセクションであると見なされます。
run.section( ,Init);
次のスクリプトは、OGSファイル内のセクションを呼び出す方法を示しています。
type "Hello, we will run section 2";
run.section(, section2);
[section1]
type "This is section 1, End the script.";
[section2]
type "This is section 2, run section 1.";
run.section(, section1);
スクリプトを実行するには、Originのユーザフォルダにtest.ogsと保存し、コマンドウィンドウに次のように入力します。
run.section(test);
セクション内のコードが意図せずセクションを終了させるようなエラーを引き起こす場合、テスト用の変数を使うことができます。
[Test]
SectionPassed = 0;
// 実行時にエラーとなるコード
...
SectionPassed = 1;
コードがエラーの場合、SectionPassedには0の値がセットされます。コードが問題ない場合、SectionPassedには1の値がセットされます。
|