3.6. 文

文には以下のものがある.

3.6.1. 空文

;

文字通り空の文で,文の区切り文字“;”のみからなっている.

QScriptではなにもない入力やなにもない複文は許されないので, 一つ以上空文を入れる必要がある.

while ($i-- >= 0) {;}

上の例と同じつもりで,

while ($i-->=0) {}

と書くと文法エラーになるので注意. 一方で,

while ($i-->=0) ;

はOK.

3.6.2. 式のみからなる文

;

文字通り式のみからなる文である. 式が評価された結果は捨てられる. 式の末尾には区切り文字“;”が必要.

3.6.3. 複文

{  [...] }

大括弧“{}”で複数の文を囲んで 一つの文として扱うことができる. 複文の副作用として,スコープが作成される(スコープ参照). ちなみに,括弧の中が完全に空なのは許されないので, 何もしない複文を作成するには1つ以上の空文を入れる必要がある (空文参照).

3.6.4. local文

local 変数名 [,変数名...];
local 変数名= [,変数名=];

一つめの形式では,local文があるスコープ内において, 指定した変数が定義される. 変数には初期値としてnullオブジェクトが代入される. 二つめの形式では,式が評価されて変数に代入される. 文の末尾には区切り文字“;”が必要である. カンマで区切り,複数の変数定義を記述可能である. この場合,初期化を含む形式とそうでない形式を混ぜることも可能.

3.6.5. if文

if () 
if () 文1 else 文2

括弧内の式を評価した結果が, trueboolean型) の場合は後続の文が実行される. 二つめの形式ではさらに, 式の結果がfalseの場合に二つめの文2が実行される.

暗黙の型変換が起こらないので, 括弧内がboolean型以外になると例外が発生する. 「文」はif文を含め任意の文を記述可能である.

if ($a<0)
 $a = -$a;
else if ($a==0)
 $a = -1;
else
 $a = -2;

以上の例では,1つめのif文の文2に相当する文が 2つめのif文になっている. (elsifやelifという記法がないのところがPerlよりCやjavaに近い.)

3.6.6. for文

for ([式1];
     [式2];
     [式3]) 

C言語等のfor文と同じ. すなわち,まず始めに初期化式(式1)が評価される. 次に式2が評価され, その結果がfalseになるまで文が繰り返し実行される. その際,更新式(式3)が繰り返しごとに評価される.

for ($i=0; $i<$a.size(); ++$i) { sys.println($a[$i]); }

式1, 式2, 式3いずれも空にすることができる. 特に式2が空の場合は 常にtrueとして扱われ,無限ループとなる.

for ( ;; ) { sys.println("a"); }

if文等と同様,暗黙の型変換が起こらないので, 式2がboolean型以外になると例外が発生することに注意.

3.6.7. while文

while () 

C言語のwhile文と同じ. 式が評価された結果,trueの間は文が繰り返し実行される. 暗黙の型変換が起こらないので,式2boolean型以外になると例外が発生することに注意. さらに,for文と異なり,を省略することはできない.

3.6.8. foreach文

foreach 変数名 () 

Perlのforeach文と同じ. (リスト)の各要素について,文が実行される. よって,が評価された結果は, listオブジェクトになる必要がある.

リストの要素は変数名で示される変数に代入され, からアクセス可能である. この変数は,foreach文があるスコープ (すなわち,文が複文の場合はその外側のスコープ)で新たに定義される.

3.6.9. break文

break;

C言語のbreak文と同様に,for文,while文,foreach文のループを中断し, ループを抜けるために使用する. 文の末尾には区切り文字“;”が必要である.

[Caution] Caution

1.0.0.54の実装では,繰り返し文の外側にbreak文があっても文法エラーにならない. 繰り返し文の外側にあるbreak文が実行されると,拿捕できない実行時例外になる.

breakでスコープから抜けた場合に,そのスコープが破棄されずに残ってしまう. これはbreak以外の例外などのケースでも起こってしまう.

3.6.10. continue文

continue;

C言語のcontinue文と同様に,for文,while文, foreach文のループの残りの部分をスキップするのに使用する. for文の場合は,更新の3番目の式が実行された上で次の繰り返しに移行する点に注意. 文の末尾には区切り文字“;”が必要である.

[Caution] Caution

1.0.0.54の実装では,繰り返し文の外側にcontinue文があっても文法エラーにならない. 繰り返し文の外側にあるcontinue文が実行されると,拿捕できない実行時例外になる.

3.6.11. 関数定義文(def文)

def 関数名 ([仮引数リスト]) 

関数を現在のコンテキストに定義する. 仮引数リストは変数名をカンマで区切ったリストであり, 引数を取らない場合は省略する. は任意の文を使用できるが, 通常は複文を用いることが多いだろう.

def func($a, $b) {
  if ($a>$b)
    system.println("a=$a");
  else
    system.println("b=$b");
}

関数が呼び出された場合,(関数本体が複文でない場合でも)自動的にスコープが作成される. 次に関数に渡された引数は,仮引数で指定された変数にそれぞれ代入され [13] 関数の本体から参照することができる.

関数は,実行が

  1. 関数の最後まで到達した場合

  2. return文を実行した場合

に関数の呼び出し元に戻る.

前者の場合は,nullオブジェクトが 関数呼び出しの結果として返される. 後者の場合は,return文に指定したオブジェクトが返される(return文参照). 但し,return文に何も指定しなかった場合には nullオブジェクトが返される.

3.6.12. return文

return [];

return文は関数の中において,実行を中断して呼び出し元に戻るために使用する. また,呼び出し元に値を返すために使用する. が評価され,その結果が呼び出し元に返却値として返される. を省略した書式では, nullオブジェクトが返される.

[Caution] Caution

return文を関数の外(グローバル・コンテキスト)で使用すると, 拿捕できない例外が発生してインタープリターの実行が停止する. (これは本来コンパイル時の文法エラーになるべき)

3.6.13. yield文

yield 識別子([, ,...]);

関数オブジェクトを引数に取る関数で, その関数オブジェクトに対して引数を指定して関数呼び出しを実行する. 識別子は, 関数オブジェクトを保持している変数の変数名から ダラー文字“$”を除いたものを指定する.

def iterfunc($nn, $b) {
  while ($nn>0) {
    yield b($nn);
    --$nn;
  }
}

上記の例では, 引数として$bに受け取った関数オブジェクトを while文の中で引数$nnを指定して呼び出している. このinterfunc()関数は以下のようにして呼び出す.

  iterfunc(10) ($xx) {
    sys.println("ext: $xx");
  };

この例では,10から1のそれぞれの整数値に対して(計10回) 渡した関数ブロックが呼び出されることになる.

3.6.14. throw文

throw [];

例外を発生させ,現在の実行を中断して例外処理文のcatch節(例外処理文を参照)に実行を移す. には発生させる例外に関するメッセージを文字列で与える. よって,は評価された結果が stringオブジェクトになければならない. は省略可能であり, 省略した場合は何のメッセージも持たない例外が発生する.

発生した例外は,複数の関数(コンテキスト)にまたがっている・いないに関わらず, 最も内側の例外処理文のcatch節で拿捕される(例外処理文を参照). もし現在の関数(コンテキスト)内に例外処理文がなかった場合は, return文が実行された場合と同様にコンテキストが破棄されて関数から呼び出し元に戻り, catch節の探索が行われる. グローバル・コンテキストに達してもcatch節がなかった場合 (i.e. 例外が拿捕されなかった場合)は,デフォルトの例外ハンドラーが呼び出され, インタープリターの実行が終了する. 概念:例外処理も参照のこと.

3.6.15. 例外処理文

try 文1 catch [(変数名)] 文2 finally 文3
try 文1 catch [(変数名)] 文2
try 文1 finally 文3

try節(文1)を実行し, その結果発生する可能性のある例外をcatch節(文2)で拿捕する. finally節(文3)は例外が発生したかどうかに関わらず, 必ず,文1(あるいは文2) の実行後に実行される. catch節あるいはfinally節のどちらかは省略可能である(両方を省略することはできない).

catch節には括弧で囲って例外を受け取る引数を指定することができる. 変数を指定して例外を拿捕した場合は, その変数にはerrorオブジェクトが代入されており, errorクラスのメソッドを使用して発生した例外の情報を取り出すことができる (errorクラス参照). また,catch節で受け取った例外をさらにthrowすることも可能である(この場合は, さらに外側の例外処理文で例外が拿捕されることになる).

3.6.16. retry文

retry;

例外処理文のcatch節で使用して,try節を再実行する場合に使用する. 例外が起こった原因となる要素を解決してから使用しないと無限にretryしつづけてしまうので, 使用には注意を要する.

[Caution] Caution

例外が起こった場所から再実行されるのではなく, try節全体が再実行される点に注意.

あと,catch節以外で使用すると拿捕できない例外が発生する. (本来はコンパイル時エラーになるべき.)



[13] この引数が代入されている変数は, 自動的に作られたスコープで定義される.