条件式の構成

要約:
Curl® 言語には、if, if-non-null, unless, switch および type-switch の 5 つの条件式があります。
この章では Curl 言語における条件式について説明します。Curl® 実行環境 (RTE) が条件式を検出すると、ブール式を評価して、条件が満たされる場合は中のコードを評価します。Curl 言語には次の条件式があります。

if

要約:
  • 条件が真の場合、1 つまたは複数の式を評価します。
  • オプションとして、条件が真でない場合に評価する式を指定します。
if 式を使用して、条件が true の場合にコードを実行するように Curl RTE に指示します。さらに if 式では、条件が false に評価された場合に実行するコードを指定する句も指定できます。if 式には 3 つのフォームがあります。

if

if 式の最もシンプルなフォームでは、ブール式が true の場合にコードが実行されます。この if 式のフォームの構文を次に示します。
構文:{if condition then
    code-block
}
説明:
conditionブール式です。
code-block1 つまたは複数の Curl 言語式で構成されています。
Curl RTE がこのような if 式を検出すると、condition を評価します。conditiontrue の場合、RTE は code-block を実行します。それ以外の場合は、code-block を実行せずに if 式の終わりに移動します。
注意: この if 式のフォーム (else 句を伴わないフォーム) では値が生成されません。戻り値が必要な状況で else 句のない if 式を使用すると、構文エラーが発生します。

例: if
{value
    || Declares two integers "x" and "y".
    || Initializes "x" to 1 and "y" to 2.
    || Define a variable "message" to be a vertical box.
    || In this example, "message" is used to store a
    || string that will later be displayed.
    let x:int=1
    let y:int=2
    let message:VBox={VBox}

    || If "x" is greater than or equal to "y" then
    || place an appropriate string in message.
    || Note that "add" is a method of VBox.
    {if x >= y then
        {message.add "x is greater than or equal to y!"}
    }

    || If "x" is less than "y" then
    || place a different string in "message".
    {if x < y then
        {message.add "x is less than y!"}
    }

    || Display the contents of "message".
    message
}
       

if ... else

このフォームの if 式では、ブール式が true の場合に特定のコードが実行され、false の場合には別のコードが実行されます。if ... then ... else ... フォームの構文を次に示します。
構文:{if condition then
    code-block-1
 else
    code-block-2
}
説明:
conditionブール式です。
code-block-1 および code-block-2それぞれ 1 つまたは複数の Curl 言語式で構成されています。
RTE がこのような if 式を検出すると、condition を評価します。conditiontrue の場合、RTE は code-block-1 を実行してから if 式の終わりに移動します (code-block-2 をスキップします)。conditionfalse の場合、code-block-1 をスキップして code-block-2 を実行し、if 式の終わりに移動します。

例: else 句を持つ if
{value
    || Define and initialize two integer variables: x=1,
    || y=2.  Define a vertical box variable "message" to
    || store and display a string.
    let x:int=1
    let y:int=2
    let message:VBox={VBox}

    || If "x" is greater than or equal to "y" then place
    || an appropriate string in "message" otherwise,
    || place a different string in "message".
    {if x >= y then
        {message.add "x is greater than or equal to y!"}
     else
        {message.add "x is less than y!"}
    }

    || Display the contents of "message".
    message
}
if 式の分岐がそれぞれ値を生成する場合、if 式はそれ全体として値を生成することになります。具体的には、if 式で実行される分岐の値が生成されます。

例: 値を生成する if
{value
    || Define and initialize two integer variables: x=1,
    || y=2.
    let x:int=1
    let y:int=2

    || Define a vertical box variable "message" to store
    || and display a string.  If "x" is greater than or
    || equal to "y" then assign an appropriate VBox to
    || "message" otherwise, assign a different VBox to
    || "message".
    let message:VBox = {if x >= y then
                           {VBox "x is greater than or equal to y!"}
                        else
                           {VBox "x is less than y!"}
                       }

    || Display the contents of "message".
    message
}

if ... elseif

if 式の内部に、else 句の本体としてもう 1 つの if 式を挿入することができます。分かりやすく記述するために、Curl 言語では次の特別な構文を用意しています。
構文:{if condition-1 then
    code-block-1
 elseif condition-2 then
    code-block-2
 elseif condition-3 then
    code-block-3
 ...
 elseif condition-n then
    code-block-n
 [else
    code-block-n+1]
}
説明:
condition-1condition-2 ...ブール式です。
code-block-1code-block-2 ...それぞれ 1 つまたは複数の Curl 言語式で構成されています。
RTE がこのような if 式を検出すると、condition-1 を評価します。condition-1true の場合、RTE は code-block-1 を実行してから if 式の終わりに移動します (他の句をスキップします)。condition-1false の場合、condition-2 を評価します。condition-2true の場合、RTE は code-block-2 を実行してから if 式の終わりに移動します。condition-2false の場合、condition-3 を評価します。condition-3true の場合、RTE は code-block-3 を実行してから if 式の終わりに移動します。条件の 1 つが true に評価されるか、または RTE がオプションの else 句に到達するまでこれが続きます。else 句が存在し、条件のいずれも true に評価されずにその句に到達した場合、RTE は code-block-n+1 を実行します。

例: elseif 句を持つ if
{value
    || Define and initialize two integer variables: x=1,
    || y=2.  Define a vertical box variable "message" to
    || store and display a string.
    let x:int=1
    let y:int=2
    let message:VBox={VBox}

    || If "x" is equal to "y" then
    || place an appropriate string in "message"
    || otherwise, if "x" is greater than "y"
    || place an appropriate string in "message"
    || otherwise
    || place a different string in "message"
    {if x == y then
        {message.add "x is equal to y!"}
     elseif x > y then
        {message.add "x is greater than y!"}
     else
        {message.add "x is less than y!"}
    }

    || Display the contents of "message"
    message
}

if-non-null

if-non-null のコンストラクトにより、テスト式を非 NULL 値にキャストして {if {non-null expr} then if-body} のような条件式を組み合わせることができます。
この式は「if-non-null」のセクションで詳細に説明されています。

unless

要約:
  • 条件が true でない場合、1 つまたは複数の式を評価します。
unless 式により提供される機能は、if 式により提供される機能に似ています。両方の式は、条件が満たされたときにコードを実行する方法を提供します。ただし unless の場合は、ブール式が false に評価されたときにコードが実行されます。言い換えると、unless 式は if (not ...) then ... に似ています。また if 式と異なり、unless 式では条件が満たされないときに別のコードを指定する方法がありません。unless 式の構文を次に示します。
構文:{unless condition do
    code-block
}
説明:
conditionブール式です。
code-block1 つまたは複数の Curl 言語式で構成されています。
RTE が unless 式を検出すると、condition を評価します。conditionfalse の場合、RTE は code-block を実行します。それ以外の場合は code-block を実行せずに unless 式の終わりに移動します。
注意: unless 式は値を返しません。RTE は条件を評価し、適切であれば中のコード ブロックのステートメントや式を評価します。ただし unless 式そのものは値を返しません。

例: unless
{value
    || Define and initialize two integer variables: x=1,
    || y=2.  Define a vertical box variable "message" to
    || store and display a string.
    let x:int=1
    let y:int=2
    let message:VBox={VBox}

    || Place a string of explanatory text in "message".
    {message.add "If the condition is false, a message appears..."}

    || Place an appropriate string in message if "x" is
    || NOT greater than or equal to "y".
    {unless x >= y do
        {message.add "x is less than y!"}
    }

    || Display the contents of "message".
    message
}
unless コンストラクトは全般的に if コンストラクトほど役に立つものではなく、2 つの式の違いが原因でコードが紛らわしくなる場合もあります。したがって、unless を避けて if のみを使用することを推奨します。

switch

要約:
  • 一連の値と式を比較して、一致する値のコードを実行します。
  • 既定では等価比較演算子 (==) を使用します。
  • 既定の比較演算子をオーバーライドできます。
switch 式では、与えられた式を一連の値と比較することができます。値にはそれぞれ関連付けられたコードがあります。RTE は、与えられた式に一致する最初の値に対応するコードを実行します。値はコードで表示されている順序で比較されます。switch 式では、一致する値がない場合に実行するコードも指定できます。
switch 式の構文を次に示します。
構文:{switch compare-expr [complete] [using compare-operator]
  case value-1 do
    code-block-1
  case value-2, value-3 do
    code-block-2
  ...
  case value-n do
    code-block-n
  [else code-block-n+1]
}
説明:
compare-expr, value-1, value-2, ...Curl 言語式です。これらの式では、intfloatcharboolString、列挙型およびユーザ定義のクラスなど、任意の Curl 言語のデータ型を評価することができます。
compare-operatorCurl 言語が compare-exprvalue-1value-2 などと比較するのに使用する演算子です。既定では、switch 式は同等比較演算子 (==) を使用します。他の比較演算子には、!=>>=<<= および isa などがあります。
code-block-1, code-block-2, ...1 つまたは複数の Curl 言語式で構成されています。
既定では、switch 式は、同等比較演算子 == を比較に使用します。using キーワードで、異なる比較演算子を指定することが出来ます。例えば、 大なり記号演算子 > や 型比較演算子 isa を使うことが出来ます。
value列挙型 だけである場合、complete キーワードを使うことができます。これは、case 句にありうる値が省略されていた場合にエラーを発生させます。using 句と else 句は共にオプションです。
RTEが switch 式を検出すると、compare-expr の値を各 value-1value-2 等々の値と比較します。RTEが、true 値を返す最初の比較を検出すると、対応するコード (値に伴う do 句) を実行して、switch 式の終わりに移動します。どの比較も true 値を返さず、else 句がある場合、RTE は、else 句に続くコードを実行します。else 句がない場合は、switch 式のすぐ後に続く式に移動します。
if 式と同様に、switch 式が else句を含み、switch 式の全ての分岐が値を生成する時、switch は、評価した最後の式の値を返します。そうでない場合には、1つの例外を除いて値を返しません。その例外は、compare-expr のコンパイル時の型が、列挙型でかつ、その列挙型の要素の全てが、case 句に含まれている場合、else は決して呼び出されることがないことが分かっているので省略することが出来ます。
以下のサンプルは、switch 式を示しています。ループの実行のそれぞれは、変数 y の異なる値をさまざまな値と比較しています。 switch 式は、y の各値と関連したコードを実行します。

例: switch
{value
    let message:VBox={VBox}
    {for y:int = 0 to 3 do
        {switch y
         case 0 do
            {message.add "y is equal to 0!"}
         case 1 do
            {message.add "y is equal to 1!"}
         case 2 do
            {message.add "y is equal to 2!"}
         else
            {message.add "y is greater than 2!"}
        }
    }
    message
}
二つ以上の値に対して、同じコードを実行したい時には、同じ case 句に値をおいてカンマで区切ります。以下のサンプルでは、y をひとつの case 句で0 と 1 と比較し、おなじメッセージを返します。

例: 2 つ以上の値に対して同じコードを実行
{value
    let message:VBox = {VBox}
    {for y:int = 0 to 3 do
        {switch y
         case 0, 1 do
            {message.add "y is less than 2!"}
         case 2 do
            {message.add "y is equal to 2!"}
         else
            {message.add "y is greater than 2!"}
        }
    }
    message
}
以下のサンプルでは、using キーワードで、switch がどのように比較を行うのか記述しています。isa 演算子を使って、変数 y の型を case 句で指定された型と比較します。

例: 比較演算子を指定したオプションの using
{value
    let y:int
    let message:Frame = {Frame}
    {switch y using isa
     case bool do
        {message.add "y is a Boolean!"}
     case char do
        {message.add "y is a character!"}
     case int8, int16, int32, int64, int, uint8, uint16 do
        {message.add "y is an integer!"}
     case float, double do
        {message.add "y is a floating-point number!"}
     else
        {message.add "y is not a simple primitive value!"}
    }
    message
}
complete キーワードの説明を含む詳細は、switchを参照してください。

type-switch

type-switch 式は値のデータ型を使用して、実行するコードブロックを決定します。この式は「データ型の操作:type-switch 式」で説明されています。platform-switch 式は、現在のプラットフォームに基づいた条件付コンパイルをサポートします。 platform-switch の利用に関する詳細の情報は、クロス プラットフォーム アプレットの記述 を参照してください。