演算子

要約:
  • 演算子式は演算を実行して結果を返します。
  • 演算子および 1 つまたは 2 つのオペランドで構成されています。
  • 演算子がオペランドの間に表示される、infix 構文を使用します。
演算子は加算や比較などの演算を実行し、その結果を返します。Curl® 言語では一般的な演算の演算子を提供しています。具体的には、次の演算子がサポートされています。
演算子式は、演算子および 1 つまたは 2 つのオペランドで構成されています。オペランドとは演算を実行する対象の値です。たとえば、34 に加算する場合、演算子は加算 (+) 、オペランドは 3 および 4 になります。
演算式では、よく知られている infix 構文 を使用します。Infix 構文では演算子がオペランドの間に表示されます。演算式を囲む curl ブラケット ({}) はありません。たとえば、34 に加算する場合に必要な演算式は次のとおりです。
3 + 4
ほとんどの演算子は2 項演算子です。2 項演算子は 2 つのオペランドを取ります。その他に、単項演算子が 3 つあります。単項演算子は 1 つのオペランドのみ取ります。単項演算子には、NULL 許容演算子 (#)、単項否定 (-) および論理否定 (not) があります。(単項否定は数値を否定する演算子です。)
ほとんどの演算式では、演算子の前後の空白はオプションです。したがって、次の式はすべて有効です。
ただし、次の場合では演算子の前後に空白が必要になります。
Curl 言語には数学関数のライブラリがあり、一般的ではない演算にも対応しています。数学ライブラリには、比較、ビット演算、三角法、科学計算、操作および強制変換などの演算に関する関数が含まれています。詳細については、「数学ライブラリ」を参照してください。

演算子の優先順位

要約:
  • 優先順位の高い演算子は低い演算子より先に評価されます。
  • 演算子の優先順位が同じである場合、演算子は左から右に評価されます。
  • かっこを使用して、演算子の優先順位のルールをオーバーライドすることができます。
演算子式は Curl ブラケットで囲みません。 演算子式が他の演算子式のオペランドになる場合、各演算子の優先順位に基づいて式の評価方法が決まります。 たとえば、次の式では最初に乗法演算、次に加算演算が評価されます (結果は 35 ではなく 23 になります)。
3 + 4 * 5
各演算子は、優先順位の最も高いものから低いものの順に評価されます。つまり、優先順位の高い演算子は低い演算子より先に評価されます。優先順位が同一の演算子は左から右に評価されます。
次の表は各 Curl 言語の演算子の優先順位を示します。0 番目の演算子が最高の優先順位、9 番目の演算子が最低の優先順位になります。
優先順位演算子説明
0 番#NULL を許容



1 番目-単項否定



2 番目asa強制



3 番目*乗法
3 番目/浮動小数点の除法
3 番目div切り捨て除法
3 番目modモジューロ
3 番目rem剰余



4 番目+加算
4 番目-減算



5 番目&文字列連結



6 番目==同等
6 番目!=不等
6 番目<小なり
6 番目>大なり
6 番目<=小なりまたは等しい
6 番目>=大なりまたは等しい
6 番目isaデータ型の確認



7 番目not論理否定



8 番目and論理積



9 番目or論理和
かっこを使用して演算子の優先順位のルールをオーバーライドすることができます。複数の演算子が式に含まれていて、通常の優先順位では意図する順序で演算子が評価されない場合、かっこを使用して演算子をグループ化します。かっこで囲まれた式が検出されると、かっこ式を評価してからその結果を周囲の式に返します。たとえば、53 + 4 の合計で掛ける場合に次のコードを書くとします。
3 + 4 * 5
この場合、演算子の優先順位のルールにより加算演算の前に乗算演算が実行されます。結果は 4 * 5 の積を 3 に加算することになり、意図した結果が得られません。34 に加算するには、次のようにかっこを使用して加算演算を囲みます。
(3 + 4) * 5
これで、最初に 3 + 4 が評価され、その結果が囲んでいる式に返されます。次にこの実例を示します。

例: 演算子の優先順位
{text
    3 + 4 * 5 = {value 3 + 4 * 5}

    (3 + 4) * 5 = {value (3 + 4) * 5}
}
注意: 上の例では、3 + 4 * 5 の演算子式が value 式で囲まれています。テキスト書式内では、囲まれたコードがテキストではなく式として処理されるように value 式を使用する必要があります。

四則演算子

要約:
  • float を含み、double を含まない演算の結果は float になります。
  • それ以外の場合で、double を含む演算の結果は double になります。
  • それ以外の場合で、int64 を含む演算の結果は int64 になります。
  • それ以外の場合、結果は int になります。
  • 1.5f(m) などの 32 ビットの数量値は float と同じように処理され、1m などの 64 ビット数量値は double と同じように処理されます。
次の表に Curl 言語の四則演算子を示します。
演算子説明オペランド戻り値
-単項否定1 つの数式数値
*乗法2 つの数式数値
/浮動少数点の除法2 つの数式浮動小数点数値
div除法2 つの数式整数数値
modモジューロ2 つの数式1 つの数値
rem剰余2 つの数式1 つの数値
+加算2 つの数式1 つの数値
-減算2 つの数式1 つの数値
単項否定演算子は 1 つのオペランドを持つ唯一の四則演算子です。この演算子の構文を次に示します。
-expression
expression は数式です。
注意: 単項演算子と expression の間には空白がありません。単項否定はuint もしくは uint64 型のオペランドでは許可されません。
四則演算式の戻り値のデータ型は、オペランドのデータ型に依存します。次のデータ型を決定するルールが適用され、四則演算の結果のデータ型が決定します。
  1. float を含み double を含まない演算の結果は float になります。
  2. それ以外の場合で、double を含む演算の結果は double になります。
  3. それ以外の場合で、uint64 または uint で符号無し整数(unsigned int)より小さい値を含む演算の結果は、uint64 または uint になります。uint または uint64 で符号ありの場合は許可されずにエラーになります。
  4. それ以外の場合で、int64 を含む演算の結果は int64 になります。
  5. それ以外の場合、結果は int になります。
  6. 1.5f(m) などの 32 ビットの数量値は float と同じように処理され、1m などの 64 ビット数量値は double と同じように処理されます。

例: Curl 言語のデータ型決定ルール
{value
    || int 型の変数 "x" を宣言し 28 で初期化
    let x:int = 28
    || double 型の変数 "y" を宣言し 3.0 で初期化
    let y:double = 3.0
    || int 型の変数 "z" 3 で初期化
    let z:int = 3

    {text
        || "x / y" の値を出力し、結果のデータ型を出力します。
        || ルールにより、結果は double 型になります。
        x / y is ... {value x / y}, which is a {type-of x / y}
        || "x / z" の結果を出力し、結果のデータ型を出力します。
        x div z is ... {value x div z}, which is a {type-of x div z}
    }
}
注意: intdiv 演算子を使用して int で除算すると、結果は int になります。int には小数部分がないので、この演算の結果の情報が失われる場合があります。
上の例では、x / y の結果が double で、x div y の結果が int になります。演算式 (x / y) が value 式で囲まれていることに留意してください。テキスト書式内では、囲まれたコードがテキストではなく式として処理されるように value 式を使用する必要があります。
/ および div 演算子を使用して数値オペランドを除算することができます。数値オペランドは、整数、浮動小数点、数量またはベクトルです。/ 演算子は 2 つの数値オペランドを取り、 double または数量を返します。div 演算子は 2 つの数値オペランドを取り、 int を返します。

例: /div 演算子の使用
{text 3 / 2 is...}     {value 3 / 2}
{br}{text 3.0 / 2 is...}   {value 3.0 / 2}
{br}{text 3s / 2s is...}    {value 3s / 2s}
{br}{text 3s / 2 is...}    {value 3s / 2}

{text 3 div 2 is...}   {value 3 div 2}
{br}{text 3.0 div 2 is...} {value 3.0 div 2}
{br}{text 3s div 2s is...}  {value 3s div 2s}
|| 3 秒 を 2 で割る場合に、divは使用できません。 
|| このケースでは、/ のみを使用してください。
注意: 上の例では、{br} により出力時に改行が挿入されています。
mod 演算子はオペランドのモジューロを返します。rem 演算子はオペランドを除算した後の剰余を返します。

例: remmod 演算子
{text 3 rem 2 is...}   {value 3 rem 2}
{br}{text -3 rem 2 is...}  {value -3 rem 2}
{br}{text 3 rem -2 is...}  {value 3 rem -2}
{br}{text -3 rem -2 is...} {value -3 rem -2}

{text 3 mod 2 is...}   {value 3 mod 2}
{br}{text -3 mod 2 is...}  {value -3 mod 2}
{br}{text 3 mod -2 is...}  {value 3 mod -2}
{br}{text -3 mod -2 is...} {value -3 mod -2}

リレーショナル演算子

要約:
  • リレーショナル演算子はオペランドを比較し、ブール値を返します。
  • 数値の比較にはリレーショナル演算子を使用します。
  • 値およびデータ型を比較するリレーショナル演算子もあります。
次の表に Curl 言語のリレーショナル演算子を一覧します。
演算子説明オペランド戻り値
==平等2 つの任意の式ブール
!=不等2 つの任意の式ブール
<小なり2 つの数式ブール
>大なり2 つの数式ブール
<=小なりまたは等しい2 つの数式ブール
>=大なりまたは等しい2 つの数式ブール
isaデータ型の確認1 つの式と 1 つのデータ型ブール
リレーショナル式の評価では、オペランドが比較されてブール値が返されます。すなわち、true または false を返します。
多くのオブジェクト指向の言語と同様に、Curl 言語ではプリミティブ値の値比較およびオブジェクトのポインタ比較を実行します。(このルールには 2、3 の例外があります。たとえば、String および DateTime オブジェクトは値として比較されます)。リレーショナル演算子を使用して 2 つのプリミティブ値を比較すると、値が比較されてその結果が返されます。このような比較は値比較または構造比較と呼ばれます。

例: 値比較
{value
    || 二つの変数 "a" と "b" を宣言し初期化します。
    let a:int = 5
    let b:int = 6

    || 各比較演算子を使い、"a" と "b" を比較します。
    {text a is {value a}, b is {value b}
        {br}a == b is ... {value a == b}
        {br}a != b is ... {value a != b}
        {br}a > b is ... {value a > b}
        {br}a < b is ... {value a < b}
        {br}a >= b is ... {value a >= b}
        {br}a <= b is ... {value a <= b}
    }
}
リレーショナル演算子式のオペランドが同じデータ型として評価されない場合は、互換性のあるデータ型に値が強制変換されます。値の強制変換では、「四則演算子」に記述されているデータ型決定ルールが適用されます。uint または uint64 を符号付の整数と比較した場合は例外であり、その比較は許可されて強制変換なしで処理されます。
2 つの浮動小数点数を比較する場合は、浮動小数点数の精度が結果に影響することに注意してください。

例: 単精度の浮動小数点数の比較
{value
    || 3つの floats 型 "a", "b", "c" を宣言します。
    || "a" を 1.0f で初期化します。
    || "b" を .9999999f で初期化します。
    || これは float型の有効数字の範囲内の数です。
    || "c" を .99999999f で初期化します。
    || これは有効数字範囲外の数になります。
    || 例の出力を格納する "message" という変数名の VBox を宣言します。
    let a:float = 1.0f
    let b:float = 0.9999999f
    let c:float = 0.99999999f
    let message:VBox = {VBox}

    || "a" が "b" と等しいかを判別し、
    || "message" に適切なテキストを追加します。
    {message.add {paragraph Is 1.0f equal to 0.9999999f?}}
    {if a == b then
        {message.add {text Yes}}
     else
        {message.add {text No}}
    }

    || "a" が "c" と等しいかを判別し、
    || "message" に適切なテキストを追加します。
    {message.add {paragraph Is 1.0f equal to 0.99999999f?}}
    {if a == c then
        {message.add {text Yes}}
     else
        {message.add {text No}}
    }

    || "message" の値を返します。
    message
}
同等演算子を使用して 2 つのオブジェクトを比較する場合は、オブジェクトのポインタの値が比較されます。このような比較はポインタ比較または識別比較と呼ばれます。次の図では、x および y が同じ値であっても同じオブジェクトを参照していないために等しくならないことを示します。
Figure: 同等演算子のポインタの比較
次の例も同様に、x および y に同じ値が代入されていても等しくならないことを示します。

例: ポインタ比較
{let x:{Array-of int} = {new {Array-of int}, 1, 2, 3}}
{let y:{Array-of int} = {new {Array-of int}, 1, 2, 3}}
{let z:{Array-of int} = x}

x == y is... {value x == y}

x == z is... {value x == z}
ただし、特定のオブジェクトについては既定のポインタ比較がオーバーライドされる場合があります。たとえば、StringInterface および DateTime を継承するオブジェクトの場合は規定の比較がオーバーライドされます。このようなオブジェクトでは、値比較が実行されます。

例: 文字列比較
{let x:String = {String "Hello"}}
{let y:String = {String "Hello"}}
{let z:String = x}

x == y is... {value x == y}

x == z is... {value x == z}
リレーショナル演算子の仕様については、「リレーショナル演算子の仕様」のセクションの表を参照してください。
データ型を操作する特別なリレーショナル演算子があります。isa 演算子は、最初のオペランドのデータ型が 2 番目のオペランドに一致した場合に true を返します。それ以外の場合は false を返します。この演算子の構文を次に示します。
expression isa type
ここで、expression はオブジェクトまたは値として評価され、type はクラス名またはプリミティブのデータ型として評価されます。
expression がオブジェクトとして評価される場合、expressiontype または type のサブクラスのインスタンスであればisatrue を返します。

例: isa をオブジェクトと使用
{value
    || Graphic を継承する HBox クラスのインスタンスに対して変数を宣言します。
    let h:HBox = {HBox}

    {text h isa Graphic evaluates to ... {value h isa Graphic}{br}
          h isa HBox evaluates to ... {value h isa HBox}{br}
          h isa float evaluates to ... {value h isa float}
    }
}
expression がプリミティブ値として評価される場合、expression のプリミティブ データ型が type であれば isatrue を返します。isa は、プリミティブ値が指定されたデータ型に一致する場合のみ true を返します。たとえば、int8 の値が int であるかどうかを調べるのに isa を使用すると isafalse を返します。isa を値と使用する例を次に示します。

例: isa とプリミティブ型の使用
{value
    || int の宣言
    let i:int

    {text i isa int evaluates to ... {value i isa int}
        {br}i isa bool evaluates to ... {value i isa bool}
        {br}i isa Graphic evaluates to ... {value i isa Graphic}
    }
}
データ型の詳細については「データ型」を参照してください。

論理演算子

要約:
  • 論理演算子はブール値を扱います。
次の表に Curl 言語の論理演算子を一覧します。
演算子説明オペランド戻り値
not論理否定1 つのブール式ブール
and論理積2 つのブール式ブール
or論理和2 つのブール式ブール
論理式の各オペランドはブール値 (true または false) として評価される必要があります。戻り値もブール値になります。
論理積演算子には 2 つのオペランドが必要です。 論理積の式では、両方のオペランドが true に評価された場合 true を返します。それ以外の場合は false を返します。具体的には、最初のオペランドが false に評価されると、2 番目の式は評価されずに false を返します。最初のオペランドが true に評価された場合、Curl 言語は 2 番目のオペランドを評価します。2 番目のオペランドが true に評価された場合、式は true を返します。それ以外の場合は false を返します。
論理和演算子には 2 つのオペランドが必要です。論理和の式では、1 つまたは両方のオペランドが true に評価された場合に true を返します。それ以外の場合は false を返します。具体的には、最初のオペランドが true に評価されると、2 番目の式を評価せずに true を返します。最初のオペランドが false に評価された場合、2 番目のオペランドが評価されます。2 番目のオペランドが true に評価された場合、式は true を返します。それ以外の場合は false を返します。
論理否定演算子には 1 つのオペランドが必要です。この演算子の構文を次に示します。
not expression
expression はブール式です。not 演算子と expression の間に空白があることに注意してください。論理否定式では、オペランドが true に評価された場合、式は false を返します。オペランドが false に評価された場合は true を返します。

例: 論理演算子の使用
{value
    || 変数 "a" と "b" を宣言し初期化します。
    let a:bool=true
    let b:bool=false

    || "a" と "b" と共に論理演算を使います。
    {text a is {value a}, b is {value b}
        {br}a and b is ... {value a and b}
        {br}a and true is ... {value a and true}
        {br}a and (5 > 2) is ... {value a and (5 > 2)}
        {br}a or b is ... {value a or b}
        {br}not a is ... {value not a}
        {br}not b is ... {value not b}
    }
}

文字列演算子

要約:
  • 文字列の連結演算子は、オペランドの印字表現を連結して作成される文字列を返します。
文字列の連結演算子は、オペランドの印字表現を連結して作成される文字列を返します。文字列の詳細については「文字列」の章を参照してください。次の表に文字列の連結演算子を示します。
演算子説明オペランド戻り値
&文字列の連結任意の式文字列
文字列の連結演算子は、最初のオペランドの末尾に 2 番目のオペランドを連結して作成される文字列を返します。オペランドが文字列として評価されない場合は、連結する前に文字列への変換が実行されます。(実際には、オペランドの %s キーで format マクロが呼び出されます)。

例: 文字列の連結演算子の使用
{value
    || int、char、double、bool、String 型の変数を宣言し初期化します。
    let i:int = 3
    let c:char = '='
    let d:double = 3.7
    let b:bool = false
    let s:String = "a horse"

    || 文字列を連結します。
    let temp1:String = s & " is " & s & " ... "
    let temp2:String = i & c & d & " is " & b
    let result:String = temp1 & temp2

    || "result" の文字列を返します。
    result
}

強制変換演算子

要約:
  • 強制変換演算子は、指定したデータ型を使用して値を返します。
強制変換演算子は、指定されたデータ型を使用して値を返します。つまり、強制変換演算子は値を指定したデータ型に変換します。次の表にこの演算子の要約を示します。
演算子説明オペランド戻り値
asaデータ型の強制変換最初のオペランド:任意の式、2 番目のオペランド:任意のデータ型指定したデータ型を持つ値

例: 強制変換演算子
{value
    || 変数 "d" を double 型で宣言し、
    || 37.7 で初期化します。
    let d:double = 37.7

    || int 型に変換した変数 "d" の値を表示します。
    d asa int
}
この演算子については、「データ型の操作:データ型の変換」で詳しく説明されています。

NULL 許容の拡張演算子

"NULL 許容" 演算子は変数の宣言で使用され、変数のデータ型名の前に付けて、その変数値が指定したデータ型または null のいずれかになることを示します。この演算子が必要な場合とその使用方法については、「null」のセクションを参照してください。