Specript Language Reference rev.0.7.0 www.specript.org

目次 | << 前章 | 次章 >>

8.式

Specriptでは、処理は全て式として表されます。条件分岐やループなどの制御も、 条件演算子や多分岐演算子、もしくはランタイムライブラリのfunction呼び出しなどの 式によって表現されることとなります。

式は下記の箇所に登場します。

  • property(要素property、制約property、functionローカルpropertyを含む)定義の初期化式
  • function(要素function、制約functionを含む)定義の本体式
  • function定義における引数のデフォルト値式
  • また、補足的に下記の箇所に登場します。

  • function呼び出しにて、引数に引き渡す値を表す式
  • record生成式内にて、要素propertyの値を表す式(初期化式)
  • list生成式内にて、要素の値を表す式
  • map生成式内にて、キーとヴァリューの値を表す式
  • list/mapアクセスにおいて、添え字の値を表す式
  • 式は次の要素から構成されます。

  • property参照/function呼び出し
  • "this"
  • record生成式/list生成式/map生成式
  • リテラル
  • ()で括られた式
  • 演算子
  • この内、

  • property参照/function呼び出し
  • "this"
  • record生成式/list生成式/map生成式
  • リテラル
  • ()で括られた式
  • は、式の最小構成単位を成し、演算子のオペランド(項)と成り得ます。

    8−1.property参照/function呼び出し

    式中では、定義されているpropertyを参照したり、functionを呼び出したりすることが できます。

    【例】
        // property "p"が定義されます。
        property p:integer = 2;
    
        // function "f"が定義されます。
        function f(a:integer):integer = a * -1;
    
        // property "q"の初期化式中で、property "p"を参照し、function "f"を呼び出しています。
        property q:integer = p + f(10);
    
        // function "g"の本体式中で、property "p"を参照し、function "f"を呼び出しています。
        function g(a:integer):integer = p + f(a);
        

    property、functionが参照、呼び出し可能かどうかは、そのproperty、functionの 所属するnamespaceが、式の記述されるnamespaceから可視であるかどうかによって定まります。

    namespaceによる可視範囲の制御については第4章第1節第3項を 参照してください。

    参照、呼び出しするproperty、functionの名称は、namespace付きの‘フルネーム’で指定します。 または、using宣言を行いnamespace部分の記述を省略することができます。あるいは、alias定義を 行いnamespaceの別名を用いた記述を行うこともできます。

    いずれも詳細は第4章を参照してください。

    引数のあるfunctionを呼び出すとき、各引数には、引き渡す値を表す任意の式を記述することとなります。

    【例】
        property p:integer = 2;
    
        // function "f"が定義されます。
        function f(a:integer, b:integer):integer = (a + b) * 5;
    
        // function "f"呼び出し時、引数に式を記述しています。
        property q:integer = p + f(p + 10, (p - 10) * 2);
        

    function定義において引数にデフォルト値式が指定されている場合には、function呼び出し時、 その引数を省略することができます。

    詳しくは第6章第3節を参照してください。

    また、function呼び出し時、引数名を明示する記法が可能です。

    詳しくは第6章第4節を参照してください。

    8−2."this"

    spec定義または匿名specにおいて、要素propertyまたは制約property定義の初期化式、 要素functionまたは制約functionの本体式中では、そのspec自身の値を指し示す一種の 要素propertyとして、予約語"this"を用いることができます。

    詳しくは第7章第1節第3項を参照してください。

    8−3.record生成式/list生成式/map生成式

    8−3−1.record生成式

    record生成式とは、recordタイプの構造を持つ値を式中で‘ad-hoc’に表現するものです。 record生成式は、"{"〜"}"内にrecordの要素propertyを ","区切りで列挙するように記述します。要素propertyの名称と初期化式は "="で区切ります。

    【record生成式の書式(EBNF)】

    <record生成式> ::=

    ( <要素property有りrecord生成式> | <空recordリテラル> )

    <要素property有りrecord生成式> ::=

    "{" <要素property名> "=" <初期化式> ( "," <要素property名> "=" <初期化式> )* "}"

    <空recordリテラル> ::=

    "{" "}"

    【記述例】
  • propertyの初期化式がrecord生成式
  •     property p:record = {e = 1, f = "a", g = '2008-03-03'};
        
  • functionの本体式がrecord生成式
  •     function f(a:integer, b:integer):record = {
            e1 = a,
            e2 = b,
            e3 = a + b,
            e4 = "xyz"
        };
        

    record生成式中の要素propertyの初期化式には、要素propertyの値を表す任意の式を記述する こととなります。

    record生成式では、要素propertyにspecを指定することはできません。要素propertyの specは、常に、暗黙に初期化式の評価結果が表すspecであるとされます。

    record生成式で、recordに要素functionを持たせることはできません。

    8−3−2.list生成式

    list生成式とは、listタイプの構造を持つ値を式中で‘ad-hoc’に表現するものです。 list生成式は、"["〜"]"内にlist要素を","区切りで 列挙するように記述します。

    【list生成式の書式(EBNF)】

    <list生成式> ::=

    ( <要素有りlist生成式> | <空listリテラル> )

    <要素有りlist生成式> ::=

    "[" <list要素の式> ( "," <list要素の式> )* "]"

    <空listリテラル> ::=

    "[" "]"

    【記述例】
  • propertyの初期化式がlist生成式
  •     property p:list<integer> = [1, 4, 5, 3];
        
  • functionの本体式がlist生成式
  •     function f(a:integer, b:integer):list<integer> = [
            a,
            b,
            a + b,
            a - b
        ];
        

    list生成式の要素には、要素の値を表す任意の式を記述することとなります。ただし、 全ての要素の式の評価結果は、全て同一のspec、もしくは全てがお互いに互換性のあるspecで なければなりません。

    8−3−3.map生成式

    map生成式とは、mapタイプの構造を持つ値を式中で‘ad-hoc’に表現するものです。 map生成式は、"["〜"]"内にmapエントリーを","区切りで 列挙するように記述します。mapエントリーのキー・ヴァリューは"=>"で区切ります。

    【map生成式の書式(EBNF)】

    <map生成式> ::=

    ( <エントリー有りmap生成式> | <空mapリテラル> )

    <エントリー有りmap生成式> ::=

    "[" <キーの式> "=>" <ヴァリューの式> ( "," <キーの式> "=>" <ヴァリューの式> )* "]"

    <空mapリテラル> ::=

    "[" "=>" "]"

    【記述例】
  • propertyの初期化式がmap生成式
  •     property p:map<string, integer> = ["A" => 8, "B" => 4, "C" => 5];
        
  • functionの本体式がmap生成式
  •     function f(a:integer, b:integer):map<string, integer> = [
            "A" => a,
            "B" => b,
            "C" => a + b,
            "D" => a - b
        ];
        

    map生成式のキーとヴァリューには、キーとヴァリューの値を表す任意の式を記述する こととなります。ただし、全てのキーの式の評価結果は、全て同一のspec、もしくは 全てがお互いに互換性のあるspecでなければなりません。かつ、全てのヴァリューの式の 評価結果は、全て同一のspec、もしくは全てがお互いに互換性のあるspecとならなければ なりません。

    8−4.リテラル

    式中では、任意のリテラルをそのリテラルが表す値を表すものとして記述することができます。

    リテラルについては第2章第8節を参照してください。

    8−5.()で括られた式

    式中では、"("〜")"で括られた式を、演算子のオペランドに 適用することができます。"("〜")"で括られた式の評価が まず行われ、その評価値を演算子へ適用することとなります。

    機能的には演算子の優先順位を変える効果があると言うことができます。

    8−6.演算子

    Specriptでは、四則演算子、比較演算子、論理演算子などの基本的な演算子は、C言語や Javaのそれと同等のものをサポートしています。ただし、

    シフト演算子やビット毎の論理演算子などビット演算に関する演算子
    "+="などの複合代入演算子
    インクリメント/デクリメント演算子など変数の値を変化させるための演算子

    これらはサポートしていません。

    その一方、「switch 〜 case 〜」に相当する多分岐演算子やlistに対する 包含演算子("in")など、Specript固有の演算子が用意されています。

    演算子 説明 優先順位
    . 要素アクセス 1
    [] list/mapアクセス
    .{} recordプロジェクション演算子
    + - 正符号/負符号演算子(単項演算子) 2
    ! 論理NOT演算子(単項演算子)
    << キャスト演算子(単項演算子)
    * / % 乗除算演算子 3
    + - 加減算演算子 4
    < > <= >= 大小比較演算子 5
    is is演算子
    == != 等値比較演算子 6
    =~ 正規表現マッチ演算子
    in 包含演算子
    && 論理AND演算子 7
    || 論理OR演算子 8
    ?: 条件演算子(三項演算子) 9
    ==? !=? =~? in? <? >? <=? >=? is? 多分岐演算子(多項演算子) 10

    8−6−1.要素アクセス(".")

    要素アクセス演算子は、オペランドの評価結果に対して、その評価結果のspecに定義されている 要素propertyまたは要素functionへのアクセスを試みる演算子です。

    評価結果のspecがrecord、もしくはrecordの派生specである場合、定義されている 要素propertyの参照と要素functionの呼び出しが可能です。評価結果のspecがrecord およびrecordの派生spec以外の場合、定義されている要素functionの呼び出しが可能です。

    要素アクセス演算子適用対象がnullであったときは、常にnullが 返ります。この場合、要素propertyまたは要素functionとしていかなるものが指定されていても、 無視されます。

    8−6−2.list/mapアクセス("[" 〜 "]")

    list/mapアクセス演算子は、listの要素、またはmapの ヴァリューを取得する演算子です。listの場合は取得する要素のインデックスを、 mapの場合は取得するヴァリューに対するキーを指定します。

    listの場合、添え字にはインデックスとしてintegerの値を 引き渡します。添え字の値を表すものとして、任意の式を記述できます。

    添え字の評価値が負の値のときは、実行時エラーとなります。添え字の評価値がlistの 要素数以上のときは、実行時エラーとならず、nullが返ります。

    【例】
        property p:list<string> = ["A", "B", "C"];
    
        // list "p"より、2番目(インデックス"1")の要素を取得します。
        property q:string = p[1];  // q == "B"となります。
    
        // listの要素数以上の添え字を指定すると、nullが返ります。
        property r:string = p[3];  // r == nullとなります。
        

    mapの場合、添え字にはそのmapのキーのタイプの値を引き渡します。 添え字の値を表すものとして、任意の式を記述できます。

    添え字の評価値をキーとするヴァリューが存在しなかったとき、nullが 返ります。

    【例】
        property p:map<date, string> = [
            '2008-01-01' => "A",
            '2008-01-02' => "B",
            '2008-01-03' => "C"
        ];
    
        // map "p"のキーはdateタイプなので、dateの値を添え字に引き渡します。
        property q:string = p['2008-01-03'];  // q == "C"となります。
    
        // mapに存在しないキーを指定すると、nullが返ります。
        property r:string = p['2008-01-04'];  // r == nullとなります。
        

    listmapいずれの場合も、要素あるいはヴァリュー取得対象の listmapnullであったときは、nullが 返ります。

    【例】
        // nullのlistです。
        property p:list<string> = null;
    
        // nullであるlistに対するアクセスの結果はnullとなります。
        property q:string = p[1];  // q == null となります。
    
        // nullのmapです。
        property r:map<date, string> = null;
    
        // nullであるmapに対するアクセスの結果はnullとなります。
        property s:string = r['2008-01-03'];  // s == null となります。
        

    8−6−3.recordプロジェクション演算子(".{" 〜 "}")

    recordプロジェクション演算子は、recordの要素propertyを取得し、 部分recordを構築する演算子です。

    【例】
        property p:record = {
            e1 = "A",
            e2 = 123,
            e3 = '2008-03-03',
            e4 = '2008-04-04'
        };
    
        // record "p"よりプロジェクション演算子で、要素property "e2"と"e4"を取得、
        // "e2"、"e4"のみからなるrecordを構築します。
        property q:record = p.{e2, e4};  // q == {e2 = 123, e4 = '2008-04-04'}となります。
        

    recordプロジェクション演算子はrecordへのみ適用できます。また、 recordの要素propertyのみ指定できます。要素functionを取得することは できません。要素functionが指定された場合、コンパイル時エラーまたは実行時エラーと なります。

    要素propertyがひとつだけ指定された場合も、要素propertyを一つ持つrecordが 構築されます。

    【例】
        property p:record = {
            e1 = "A",
            e2 = 123,
            e3 = '2008-03-03',
            e4 = '2008-04-04'
        };
    
        // プロジェクション演算子で、要素property "e2"のみからなるrecordを構築します。
        property q:record = p.{e2};  // q == {e2 = 123}となります。
        

    要素propertyが一つも指定されなかった場合、空のrecordが構築されます。

    【例】
        property p:record = {
            e1 = "A",
            e2 = 123,
            e3 = '2008-03-03',
            e4 = '2008-04-04'
        };
    
        // プロジェクション演算子で、要素propertyが指定されなかった場合、空のrecordが
        // 構築されます。
        property q:record = p.{};  // q == {}となります。
        

    存在しない要素propertyが指定された場合、コンパイル時エラーまたは実行時エラーと なります。

    recordプロジェクション演算子適用対象のrecordnullで あったときは、nullが返ります。この場合、要素propertyとしていかなる ものが指定されていても、無視されます。

    【例】
        // nullのrecordです。
        property p:record = null;
    
        // nullであるrecordに対するプロジェクション演算子適用の結果はnullとなります。
        property q:record = p.{e2, e4};  // q == null となります。
        

    8−6−4.正符号/負符号演算子("+"、"-")

    正符号演算子は、数値系タイプ(integerdecimalreal)に対して、値の符号をそのまま維持する演算を行います。

    負符号演算子は、数値系タイプ(integerdecimalreal)に対して、値の符号を反転する演算を行います。

    正符号/負符号演算子について、適用可能なタイプと振る舞いを下記に示します。

    オペランド 振る舞い
    integer, decimal, real オペランドの評価値について、符号を維持または反転する演算を行い、 得られた値を返します。

    8−6−5.論理NOT演算子("!")

    論理NOT演算子は、オペランドのbooleanの値のtruefalseを反転した値を返す演算子です。

    オペランドの評価結果がboolean以外の場合、コンパイル時エラーまたは 実行時エラーとなります。

    論理NOT演算子を適用可能なタイプと振る舞いを下記に示します。

    オペランド 振る舞い
    boolean オペランドの評価値がtrueのときfalseを 返します。オペランドの評価値がfalseのとき trueを返します。

    8−6−6.キャスト演算子("<<")

    Specriptのキャスト演算子は‘構造的キャスト’を行う演算子です。構造的キャストとは、 recordおよびその派生specにおいて、継承関係に無くとも、要素propertyの定義が 構造的に一致していればキャスト可能とするものです。

    「構造的に一致」とは、「キャスト先specの要素propertyと同名の要素propertyが元specに 存在するとき、元specの要素propertyのspecが、キャスト先specの要素propertyのspecと 同一である、または構造的に一致する」ことを表します。 存在するとき、

    【例】
        spec S : {
            property e1:string;
            property e2:string;
        }
    
        spec T : {
            property e1:string;
            property e2:string;
        }
    
        property p:S = { e1 = 1, e2 = 2; };
    
        // property "p"のspecは"S"であり、"T"とは継承関係に無いので、エラーとなります。
        property q:T = p;  // コンパイル時エラー
    
        // "T"へのキャストを明示することにより、構造的に受け入れ可能なのでエラーとなりません。
        property r:T = <<T<< p;  // OK
    
        spec U : {
            property e1:string;
            property e2:integer;  // 要素"e2"のタイプがspec "S"と異なります。
        }
    
        // "S"は"U"に対して構造的に受け入れ不可能なので、キャストをしてもエラーとなります。
        property s:U = <<U<< p;  // コンパイル時エラー
        

    8−6−7.乗除算演算子("*"、"/"、"%")

    乗除算演算子は、数値系タイプ(integerdecimalreal)に対して、乗算("*")、除算("/")、 剰余算("%")を行います。

    乗除算演算子について、適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    integer, decimal, real integer, decimal, real 左オペランドの評価値と右オペランドの評価値について、積、商、または 剰余を求める演算を行い、得られた値を返します。左右オペランドの タイプが異なる場合、暗黙的に、より包括的なタイプへキャストを行った後 演算を行います。
    数値系タイプ間の暗黙のキャストについては本章第7節第1項を参照してください。

    8−6−8.加減算演算子("+"、"-")

    integer, decimal, real

    数値系タイプ(integerdecimalreal)に対する 加減算演算子は、左右オペランドの評価値について加算("+")、または 減算("-")を行います。

    数値系タイプ(integerdecimalreal)に対する 加減算演算子について、適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    integer, decimal, real integer, decimal, real 左オペランドの評価値と右オペランドの評価値について、和または差を求める 演算を行い、得られた値を返します。左右オペランドのタイプが異なる場合、 暗黙的に、より包括的なタイプへキャストを行った後、演算を行います。
    数値系タイプ間の暗黙のキャストについては本章第7節第1項を参照してください。

    string

    stringに対しては加算演算子("+")のみ適用できます。stringに対する 加算演算子は、左右オペランドのstringの値を連結した新たなstringを返します。

    【例】
        property p:string = "abc";
        property q:string = "def";
        property r:string = p + q;  // r == "abcdef"となります。
        

    stringに対する加算演算子について、適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    string string 左オペランドの評価値と右オペランドの評価値を連結したstringを 返します。

    list

    listに対して加算演算子("+")を適用できます。listに対する 加算演算子は、左右オペランドのlistの値を結合した新たなlistを返します。

    【例】
        property p:list<integer> = [2, 3, 3, 4];
        property q:list<integer> = [3, 4, 5];
        property r:list<integer> = p + q;  // r == [2, 3, 3, 4, 3, 4, 5]となります。
        

    listに対する加算演算子は和集合(Union)を取るものではありません。

    listに対する加算演算子について、適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    右オペランドと同一のタイプアーギュメントのlist 左オペランドと同一のタイプアーギュメントのlist 左オペランドの評価値と右オペランドの評価値を連結した新たな listを返します。

    8−6−9.大小比較演算子("<"、">"、"<="、">=")

    大小比較演算子は、左右オペランドの値の大小関係を比較する演算子です。比較の結果を booleanの値で返します。

    【例】
        // integerの比較
        property p:integer = 5;
        property q:integer = 6;
        property r:boolean = p < q;  // r == trueとなります。
    
        // stringの比較(stringの場合はUnicodeコードの大小で比較されます。)
        property s:string = "abc";
        property t:string = "abd";
        property u:boolean = s < t;  // u == trueとなります。
    
        // dateの比較
        property v:date = '2007-12-23';
        property w:date = '2007-12-25';
        property x:boolean = v < w;  // x == trueとなります。
        

    大小比較演算子を適用可能なタイプと大小判定条件を下記に示します。適用不可なタイプの 組み合わせだった場合、コンパイル時エラーまたは実行時エラーとなります。

    左オペランド 右オペランド 大小判定条件
    integer, decimal, real integer, decimal, real 左オペランドの評価値と右オペランドの評価値について、値の大小を 比較します。左右オペランドのタイプが異なる場合、暗黙的により包括的な タイプへキャストを行った後、値を比較します。
    string string 文字列を構成する文字のUnicodeコードの大小で比較します。
    date date dateの表す年月日で、より後の日付の方を「大きい」とします。
    timestamp timestamp timestampの表す年月日時分秒ミリ秒で、より後の日時の 方を「大きい」とします。
    数値系タイプ間の暗黙のキャストについては本章第7節第1項を参照してください。

    8−6−10.is演算子("is")

    is演算子は、左のオペランドの評価値のspecがisに続いて示されるspecに対して 互換性のあるとき、trueを返す演算子です。

    specの互換性評価の詳細について第7章第3節を 参照してください。
    【例】
        // 制約functionのあるspecを定義します。
        spec S : string {
            constraint function c = length <= 4;
        }
    
        // 値"abcd"はspec "S"に対して互換性があります。
        property p:boolean = "abcd" is S;  // p == trueとなります。
    
        // 値"abcde"はspec "S"に対してSpec違反を発生させるので、互換性がありません。
        property q:boolean = "abcde" is S;  // q == falseとなります。
    
        // 値"123"はspec "S"に対して、タイプが異なるので、互換性がありません。
        property r:boolean = 123 is S;  // r == falseとなります。
        

    is演算子を適用可能なタイプと振る舞いを下記に示します。

    オペランド(左) 振る舞い
    任意 オペランドの評価値がisに続いて示されるspecに対して 互換性があるときtrueを、互換性が無いときfalseを 返します。

    8−6−11.等値比較演算子("=="、"!=")

    等値比較演算子は、左右オペランドの値が等しいか否か比較する演算子です。比較の結果を booleanの値で返します。Specriptのタイプは全て値扱い(by-value)です。 stringrecordについても値による比較が行われます。

    【例】
        // integerの比較
        property p:integer = 5;
        property q:integer = 5;
        property r:boolean = p == q;  // r == trueとなります。
    
        // stringの比較
        property s:string = "abc";
        property t:string = "abc";
        property u:boolean = s == t;  // u == trueとなります。
    
        // recordの比較
        property v:record = { e1 = 1, e2 = "a" };
        property w:record = { e1 = 1, e2 = "a" };
        property x:boolean = v == w;  // x == trueとなります。
        

    等値比較演算子を適用可能なタイプと等値判定条件を下記に示します。適用不可なタイプの 組み合わせだった場合、コンパイル時エラーまたは実行時エラーとなります。

    左オペランド 右オペランド 等値判定条件
    integer, decimal, real integer, decimal, real 左オペランドの評価値と右オペランドの評価値について、値を比較します。 左右オペランドのタイプが異なる場合、暗黙的により包括的なタイプへ キャストを行った後、値を比較します。
    boolean boolean 左右オペランドの評価値が同一のとき「等しい」とされます。
    string string 文字列を構成する文字のUnicodeコードで比較します。全て一致するとき 「等しい」とされます。
    date date dateの表す年月日が一致するとき、「等しい」とされます。
    timestamp timestamp timestampの表す年月日時分秒ミリ秒が完全に一致するとき、 「等しい」とされます。
    record record 要素propertyの数、名称、タイプが全て一致し、それら要素propertyの 値がそれぞれ等しいとき、recordは「等しい」とされます。 要素propertyの比較は再帰的に行われます。
    list list listの要素のタイプが同一で、要素の数が等しく、二つの list内の同一インデックスの要素の値が全て等しいとき、 listは「等しい」とされます。要素の比較は再帰的に 行われます。
    map map mapのキーとヴァリューのタイプが同一で、エントリー数が 等しく、二つのmapのキーのセットが完全に一致し、キーに 関連付くヴァリューの値も全てそれぞれ等しいとき、mapは 「等しい」とされます。キーとヴァリューの比較は再帰的に行われます。
    数値系タイプ間の暗黙のキャストについては本章第7節第1項を参照してください。

    recordの場合を含めて、派生specで要素functionが定義されていても、等値比較の 結果に影響を与えません。要素functionの評価値は、等値比較時に考慮されません。

    8−6−12.正規表現マッチ演算子("=~")

    正規表現マッチ演算子は、右オペランドのstringの値を正規表現としたとき、左オペランドの stringの値がそれにマッチした場合にtrueを返す演算子です。

    正規表現マッチ演算子はstringにのみ適用できます。左右オペランドの評価結果がstring以外と なる場合、コンパイル時エラーまたは実行時エラーとなります。

    【例】
        property p:string = "abc";
        property q:string = "[a-z]*";
        property r:boolean = p =~ q;  // r == trueとなります。
        

    サポートされる正規表現は、Javaのjava.lang.String.matchesメソッドのサポートするものと 同一です。

    正規表現マッチ演算子を適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    string string 右オペランドのstringの値を正規表現として、 左オペランドのstringの値がその正規表現にマッチしたとき trueを、マッチしなかったときfalseを返します。

    8−6−13.包含演算子("in")

    包含演算子は、左オペランドの値が右オペランドのlistの要素として存在した 場合にtrueを返す演算子です。

    【例】
        // "l"中に"e"が含まれていた場合に"true"を返す式となっています。
        function included(l:list<integer>, e:integer):boolean = e in l;
        

    右オペランドは評価結果が必ずlistとならなければなりません。左オペランドのタイプが listの要素のタイプと合致しない場合はコンパイル時エラーまたは実行時エラーとなります。

    【例】
        property r:boolean = "x" in [1, 2, 3];  // コンパイル時エラー
        

    包含演算子を適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    右オペランドのlistのタイプアーギュメントと同一のタイプ list 左オペランドの評価値が、右オペランドのlistの要素の 中に存在したときtrueを、存在しなかったとき falseを返します。

    8−6−14.論理AND演算子("&&")

    論理AND演算子は、左右オペランドのbooleanの値がともにtrueの ときtrueを返す演算子です。

    左オペランドの評価値がfalseになったとき、右オペランドの評価は行われません。

    左右オペランドの評価結果がboolean以外の場合、コンパイル時エラーまたは 実行時エラーとなります。

    論理AND演算子を適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    boolean boolean 左オペランドの評価値がfalseのとき、falseを 返します。左オペランドの評価値がtrueのとき、初めて 右オペランドを評価してそのbooleanの値を返します。

    8−6−15.論理OR演算子("||")

    論理OR演算子は、左右オペランドのbooleanの値のいずれかがtrueの ときtrueを返す演算子です。

    左オペランドの評価値がtrueになったとき、右オペランドの評価は行われません。

    左右オペランドの評価結果がboolean以外の場合、コンパイル時エラーまたは 実行時エラーとなります。

    論理OR演算子を適用可能なタイプと振る舞いを下記に示します。

    左オペランド 右オペランド 振る舞い
    boolean boolean 左オペランドの評価値がtrueのとき、trueを 返します。左オペランドの評価値がfalseのとき、初めて 右オペランドを評価してそのbooleanの値を返します。

    8−6−16.条件演算子("?" 〜 ":" 〜)

    条件演算子は「if 〜 else 〜」に相当する三項演算子です。

    【例】
        // "x"が正、負、零であるか判断し、それぞれ"1"、"-1"、"0"を返す式となっています。
        function sign(x:integer):integer = x > 0 ? 1 : x < 0 ? -1 : 0;
        

    条件演算子を適用可能なタイプと振る舞いを下記に示します。

    第1オペランド 第2オペランド 第3オペランド 振る舞い
    boolean 第3オペランドと同一のタイプ 第2オペランドと同一のタイプ 第1オペランドの評価値がtrueのとき、第2オペランドを 評価しその値を返します。第1オペランドのbooleanの値が falseのとき、第3オペランドを評価しその値を返します。

    8−6−17.多分岐演算子

    多分岐演算子は「switch 〜 case 〜」に相当する多項演算子です。等値比較演算子、 正規表現マッチ演算子、包含演算子、大小比較演算子、is演算子に対応したバリエーションが あります。

    ==? ? : 等値比較演算子("==")に対応するバリエーション
    !=? ? : 等値比較演算子("!=")に対応するバリエーション
    =~? ? : 正規表現マッチ演算子("=~")に対応するバリエーション
    in? ? : 包含演算子("in")に対応するバリエーション
    <? ? : 大小比較演算子("<")に対応するバリエーション
    >? ? : 大小比較演算子(">")に対応するバリエーション
    <=? ? : 大小比較演算子("<=")に対応するバリエーション
    >=? ? : 大小比較演算子(">=")に対応するバリエーション
    is? ? : is演算子("is")に対応するバリエーション

    第1項に値の比較を行う式、nを1以上として第2n項に第1項の値の比較対象となる式、 第2n+1項に第2n項の値に関する比較が成立した場合に返す値を表す式、を記述します。

    【例】
        // 等値比較演算子に対応したバリエーションです。
        // "x"が"1"に等しいとき"A"を、"2"に等しいとき"B"を、"3"に等しいとき"C"を返す式と
        // なっています。
        function branching1(x:integer):string =
            x ==?          // switchに相当します。
                1 ? "A" :  // caseに相当します。
                2 ? "B" :  // caseに相当します。
                3 ? "C"    // caseに相当します。
            ;
    
        // 正規表現マッチ演算子に対応したバリエーションです。
        // "x"が数字のみの場合"1"を、英字のみの場合"2"を、英数字混在している場合"3"を返す
        // 式となっています。
        function branching2(x:string):integer =
            x =~?
                "[0-9]*"       ? 1 :
                "[a-zA-Z]*"    ? 2 :
                "[a-zA-Z0-9]*" ? 3
            ;
    
        // 包含演算子に対応したバリエーションです。
        // "x"が"a"、"b"、"c"いずれかであった場合"1"を、"p"、"q"、"r"いずれかであった場合"2"を、
        // "x"、"y"、"z"いずれかであった場合"3"を返す式となっています。
        function branching3(x:string):integer =
            x in?
                ["a", "b", "c"] ? 1 :
                ["p", "q", "r"] ? 2 :
                ["x", "y", "z"] ? 3
            ;
    
        // 大小比較演算子に対応したバリエーションです。
        // "x"が"30"以上のとき"A"を、"20"以上のとき"B"を、"10"以上のとき"C"を返す式と
        // なっています。
        function branching4(x:integer):string =
            x >=?
                30 ? "A" :
                20 ? "B" :
                10 ? "C"
            ;
        

    多分岐演算子には、大小比較演算子に対応したバリエーションを除いて「default」に相当する 記述はできません。

    【例】
        // 「default」に相当する項を記述しようとしてもコンパイル時エラーとなります。
        function branching5(x:integer):string =
            x ==?
                1 ? "A" :
                2 ? "B" :
                3 ? "C" :
                    "D"    // コンパイル時エラー
            ;
    
        // 大小比較演算子に対応するバリエーションでのみ「default」に相当する項を記述できます。
        function branching6(x:integer):string =
            x >=?
                30 ? "A" :
                20 ? "B" :
                10 ? "C" :
                     "D"    // OK、"10"未満の場合"D"となります。
            ;
        

    大小比較演算子に対応するバリエーション以外、または大小比較演算子に対応するバリエーションで 「default」相当項が存在しない場合、いずれの第2n項に関する比較も成立しなかったときは、 実行時エラーとなります。

    【例】
        function branching(x:integer):string =
            x ==?
                1 ? "A" :
                2 ? "B" :
                3 ? "C"
            ;
    
        // "x"が"1"〜"3"のいずれにもマッチしなかった場合、実行時エラーとなります。
        property p:string = branching(4);  // 実行時エラー
        

    多分岐演算子を適用可能なタイプと振る舞いを下記に示します。

    第1オペランド 第2nオペランド 第2n+1オペランド 最終オペランド 振る舞い
    対応する二項演算子の左オペランドに適用可能なタイプ 対応する二項演算子の右オペランドに適用可能なタイプ 全ての第2n+1オペランドは同一のタイプ 第2n+1オペランドと同一のタイプ
    (※大小比較演算子に対応するバリエーションでのみ記述可能)
    第1オペランドの評価値を左オペランド、第2nオペランドの評価値を 右オペランドとして対応する二項演算子を適用してtrueと なったとき、第2n+1オペランドの評価値を返します。
    いずれの第2nオペランドについてもtrueとならなかったとき、 最終オペランドが存在すれば最終オペランドの評価値を返却、 最終オペランドが存在しないときは実行時エラーとなります。

    8−7.数値演算に関する詳細

    8−7−1.数値系タイプ間における暗黙のキャスト

    数値系タイプ(integerdecimalreal)の値に 対して、

  • 乗除算演算子
  • 加減算演算子
  • 大小比較演算子
  • 等値比較演算子
  • が適用されるとき、左右オペランドのタイプが異なった場合、数値系タイプ間で暗黙の キャストが行われます。

    左(右)オペランドのタイプ 右(左)オペランドのタイプ 暗黙のキャスト後のタイプ
    integer decimal decimal
    integer real real
    decimal real real

    realからdecimalまたはintegerへ、decimalから integerへは、暗黙にキャストされることはありません。

    decimalからrealへ暗黙のキャストが行われるとき、realタイプとして 表現できない大きさまたは小ささの値であった場合、実行時エラーとなります。

    8−7−2.四則演算に関する詳細

    乗算(*

    T.B.D.

    除算(/

    除算の場合の振る舞いについて、詳細を示します。

    左オペランド(被除数) 右オペランド(除数) 振る舞い
    integer integer 商は、小数第一位以下を切り捨て、演算結果値もintegerと なります。
    decimal decimal T.B.D.
    real real T.B.D.

    乗余算(%

    T.B.D.


    目次 | << 前章 | 次章 >>


    (c)2007-2008, Specript Development Team Last Updated: 2008-03-06