= ステートメントと制御構造

プログラムは、ステートメントの集まりです。
一般的に「文」と訳されますが、Konoha ではオペレータと同じくステートメントと呼んでいます。
ただし、if ステートメントと呼ぶのは冗長な気がするので、
何の統一感もなく、広く慣習的に用いられている「if文」と呼んでいます。

Konoha のステートメントと基本的な制御構造についてみていきましょう。

== ステートメント

ステートメントとは、プログラミング言語における文のことです。
正しいスタイルのステートメントは、CやC++, Java と同様に、セミコロン(;)で終わります。

{{{
a = 3;
b = 4;

}}}

次のように、１行に複数のステートメントを書くこともできます。

{{{
a = 3; b = 4;

}}}

何ごとも正しいスタイルでプログラミングをするように心がけましょう。

=== セミコロンの省略

さて、セミコロンをステートメントの最後につけることは、
スクリプティング言語の流儀からするとやや助長です。
ということで、JavaScript と同じく、セミコロンを強制していません。

ステートメントの途中に改行がくると、セミコロン(;)を忘れたものと拡大解釈してくれます。
つまり、次の例でも、同様に、２つのステートメントになります。

{{{
a = 3
b = 4
}}}

こうすると、あちらを立てればこちらが立たずという問題が発生します。

Cプログラマは、
１行(80文字)に収まりきらないステートメントを改行して読みやすくする習慣があったりして、
このケースではステートメントが勝手に分割されてしまうことになりかねません。

{{{
print a + b  // 終了？　続いている?
-c;

}}}

そこで、もしステートメントの途中で改行を入れたときは、
２行目以降は字下げしてステートメントが続いていることを明示的に示すことにしました。
少々面倒な気もしますが、多くのCプログラマは読みやすくするため、
習慣的に字下げを行っているため、比較的影響が少ないと思われる妥協点です。

{{{
print a + b
	- c;　　// 続いている
	
}}}

== コメント

Konoha は、C/C++, Java スタイルのコメントを採用しています。
// は、行コメントの始まりであり、改行までのテキストがコメントとして無視されます。

{{{
a = b;            // 行コメント

}}}

また、C/C++ や Java と同様に、/* */ で囲むことでコメント化できます。
Konohaは、C言語と異なり、コメントのネストも可能です。

{{{
/* まとめてコメントアウト
a = 1;
b = 2;  /* コメントの入れ子もOK */
*/

}}}

== ステートメントと式

もっとも簡単なステートメントは、プログラムの状態を変更する式(expression)です。
代入オペレータは、もっともよく使われるステートメントです。

{{{
s = "Hello " + name
i *= 3;

}}}

インクリメント演算式(++)、デクリメント演算式(--)は、
代入オペレーションの一種ですが、ステートメントとして利用することができます。

{{{
>>> n = 1
>>> n++

}}}

関数/メソッドのコールも、もうひとつの代表的な式によるステートメントです。

{{{
>>> System.out.println("hello,world");
"hello,world"
>>> Math.sin(0.5);

}}}

上記以外の任意の式もステートメントとして用いることができます。
しかし、プログラムの状態を変更しない式は、コンパイラによって無視されて実行されません。

{{{
if(a == 1) print a;
a + 1;                      // 無視される
return a;
}}}

対話モードにおいて、式をステートメントとして入力するときは、
セミコロン(;) をつけなくても構いません。（警告もいわれません。）

== (ステートメント)ブロック

ブロックは、0個以上のステートメントまとめてひとつのステートメントとして扱えるようにします。
これは、任意のプログラムを中括弧 { }で囲むことで作ることができます。
ブロックの終端には、C時代からの慣習的でセミコロン(;)は必要はありません。
また、ブロック内では、読みやすさのためインデントするようにしましょう。

{{{
{
   x = Math.PI;
   a = Math.cos(x);
   print a;
}
}}}

注意：Konoha では、メソッド(関数)内同一スコープであるため、変数のスコープには注意が必要です。

=== 空ステートメント

空ステートメントは、何もしないステートメントです。ブロックを用いて空ステートメントを表すことができます。

{{{
{}
}}}

== if/else文, switch文

if 文は、もっとも基本的な制御ステートメントです。
ご想像のとおり、与えられた条件式に応じて実行するステートメントを切り替えるときに用います。

{{{
>>> n = 4
>>> if (n mod 2 == 0) {
...    print "even";
... }
even

}}}

もちろん、ブロックの中が単文の場合は、ブロックを使う必要はありません。

{{{
>>> if (n mod 2 == 0) print "even";

}}}

else 節は、if文の条件が false だったときに実行されるステートメントを記述します。

{{{
>>> n = 3
>>> if (n mod 2 == 0) {
...    print "even";
... } else {
...    print "odd";
... }
odd

}}}

更に、if/else文を組み合わせ、あたかも　else if文のように用いると、3つ以上の条件分岐をすっきりと書くことができます。

{{{
if(n == 1) {
  // n が1のとき
}
else if(n == 2) {
  // n が2のとき
}
else if(n == 3) {
  // n が3のとき
}
else {
   // それ以外のとき
}
}}}

switch 文は、多重条件分岐をすっきりと書くための専用のステートメントです。
基本的な文法や原理は、break文が必要な点も含め、C/C++ や Java と大きく変わりません。

次は、else ifの例の switchバージョンです。
各case節は、条件分岐の始まりを表すに過ぎず、
break文によって明示的に分岐の終端を表す必要があります。

{{{
switch(n) {
  case 1 : 
    // n が 1のとき
  break;
  case 2 : 
    // n が 2のとき
  break;
  case 3 : 
    // n が 3のとき
  break;
  default:
   // それ以外のとき
}

}}}

Konoha は、case節で与えられる条件に関して強化されています。
C言語は、コンパイラ最適化のため、整数リテラルのみ条件にかけましたが、
Konoha では任意のリテラルを与えることができます。

{{{
switch(lang) {
  case "perl" : 
  case "python" : 
    // 
  break;
  case "cpp" : 
    // 
  break;
  default:
   // それ以外のとき
}

}}}

将来的には、match を導入し、パターンマッチをより強化する予定です。

== ループの構造 while文、do/while文、for文、foreach文

while文は、与えられた条件式が真の間、
続くステートメントを繰り返し実行させるループ構造のステートメントです。

次の例では、変数 a が 0 より大きい間、繰り返し実行されます。

{{{
>>> a = 1;
>>> while(a > 0) {
...   a = Int.random(10);           // 乱数生成
...   print a;
...}
a=1
a=7
a=0

}}}

while文の条件式に定数としてtrueを与えれば、
ループが無限に繰り返されることになります。

{{{
>>> c = 0;
while(ture) {  // 無限ループ: 試さない方がいい
　　print c;
   c++;
}
c=0
c=1
...Ctrl-C

}}}

注意：無限ループは、break文を用いるか、throw文による大域ジャンプによって抜け出すことができます。
これらの手法を組み合わせない限り、無限ループを作るのはやめましょう。

do/while文は、条件判定の順序が異なるwhile文のバリエーションです。
while文とdo/while文の違いは、
while文が条件に次第では一度もステートメントを実行されないことがあるのに対し、
do/while文の方は必ず１回はループが実行される点にあります。

{{{
>>> do {
...   a = Int.random(10);   // 乱数生成
...   print a;
... } while(a > 0);
a=8
a=4
a=2
a=0

}}}

for文は、n回の繰り返しなどを書くときに便利なwhile文の置き換えです。

{{{
>>> for(i = 0; i < 10; i++) {   // for 版
...   print i;
... }
i=0
i=1
...
i=9

}}}

実際、上のfor文は、while文は全く同じですが、
for文の方がwhile文よりもコンパクトにかけて、
しかも読みやすいでしょう。

{{{
>>> i = 0; 
>>> while(i < 10) { // // while 版
...   print i;
...   i++;
... }
i=0
i=1
...
i=9

}}}

for文は、C/C++やJava で広く使われているため、Konoha でも採用されています。
ただし、モダンなプログラミングでは、for文よりも、イテレーションパターンを扱う foreach文（後述）の方が好まれています。

{{{
>>> foreach(n in (0 to 9)) {
...   print n;
... }
n=0
n=1
...
n=9
}}}

Konohaでは、foreach文に様々な拡張を加えています。
詳しくは、「[kbook.iterator foreachとイテレーション]」を参考にしてください。

== break文とcontinue文

break文とcontinue文は、ループ制御のステートメントをもっています。

break文を使うと、現在繰り返しているループ構造のブロックから抜け出すことができます。

{{{
>>> while(true) {
...   dice  = Int.random(6) + 1;
...   dice2 = Int.random(6) + 1;
...   print dice, dice2;
...   if(dice == dice2) break;    // ぞろ目になったらおしまい
... }

}}}

continue　文を使うと、現在繰り返しているループ構造のブロックの残りのパートをスキップします。

{{{
>>> for(i = 0; i < 10; i++) {
...   if(i mod 2 == 0) continue;    // ループの先頭へ
...   print i;
... }
i=0
i=2
i=4
....

}}}

ループ構造では、while文やfor/foreach文を組み合わせて、多重ループを作ることができます。
多重ループでは、break文やcontinue文を用いても、どのループを対象として制御したいのか曖昧になります。

Konoha では、ループにラベルをつけることで、どのループからのbreak/continue制御なのか、
明示的に示すことができます。
ラベルを省略すれば、今まで通り、暗示的に最も内側のループが対象となります。

{{{
>>> OUTER: for(y = 0; y < 8; y++) {
...   INNER: for(x = 0; x < 8; x++) {
...      print x, y;
...      if (x == y) continue OUTER; /* 外側 */
...      if (x < y) break; /* 内側 */
...   }
... }

}}}

注意： switch 文のラベルと組み合わせることも可能です。

== 例外処理 try/catch/finally

Konohaは、Java風のtry/catch/finallyによる例外処理をサポートし、
throw された例外を大域ジャンプとしてキャッチすることができます。

{{{
try {
   file = new InputStream("file.txt");
   line = file.readLine();
}
catch(IO!! ex) {
   print ex;
}
catch(Security!! ex) {
   print ex;
}
finally {
   file.close();
}
}}}

例外処理機構に関しては、
後述の「[kbook.exception 例外処理]」において、
詳しく説明します。

[[include(KbookIndex)]]
[[include(KbookFooter)]]
