カテゴリー別アーカイブ: 基本構文

Decimal型

※v8.0からサポートされます。

データ型として Decimal 型が使用できるようになりました。

Decimal は符号と scale プロパティを伴った96ビットの仮数部を使用して浮動小数点数を表すことができます。

正の 79,228,162,514,264,337,593,543,950,335 から

負の 79,228,162,514,264,337,593,543,950,335 まで

の範囲の10進数を表し、多数の有効な整数桁と小数桁をサポートします。

ソース

{curl 8.0 applet}
{curl-file-attributes character-encoding = “utf8”}
{import * from CURL.LANGUAGE.MATH}
{let vb:VBox =  {VBox
                    {HBox “max-value is:”,Decimal.max-value},
                    {HBox “min-value is:”,Decimal.min-value}
                } }
{value
    vb
}

実行結果decimal.jpg

 

 

 

 


サンプル

http://developers.curlap.com/curl/v8/decimal.curl

 

 

式とコメント

{Curly Bracket}

式とは基本的にCurl言語のコマンドを指します。Curlではほとんどの式が{と}で囲まれるようになります。そもそもCurlの名前の由来は、この”{“(Curly Bracket)からきています。式の中に式を記載する場合は、さらに{と}で囲むこととなります。そのため、式を囲むブラケットの数でコードのレベルを示すこととなります。

{define-proc {my-proc}:void
  {message-box “ABC”}
}

{my-proc}

 

value式

value式は、複数のコードを記載し、最後の部分式の値を結果として画面や変数へ返します。

{value
    let v = 1 || この式は{let v = 1}と記載することも可能です。
    set v = 2 || この式は{set v = 2}と記載することも可能です。
    v
}

実行結果
  2

 

do式

do式は、valueと似ていますが、doは結果を返しません。

{do
    let v = 1 || この式は{let v = 1}と記載することも可能です。
    set v = 2 || この式は{set v = 2}と記載することも可能です。
}

実行結果
 結果なし

 

コメント

Curlでの1行コメントは、||を利用します。複数行のコメントには|##|で囲みます。

{do
    let v = 1 || 1行のみコメント
    |#
        複数行コメント
    #|
}

 

変数の宣言と値の代入

宣言と代入

Curlでの値の宣言方法は以下のように「let 変数名:データ型 = 初期値」となります。

let str:String = “あいうえお” || もしくは{let str:String = “あいうえお”}

以下のように複数の変数を同時に宣言することもできます。

let (str:String, int:i) = (“あいうえお”, 123) 

値を代入する場合は、下記のようにsetを使います。 

set str = “ABCDE” || もしくは{set str = “ABCDE”}

let同様に、以下のように複数の値を同時にセットできます。 

set (str, i) = (“かきくけこ”, 456) 

この際にJava等の言語と違い、注意しないといけないことはNullを許容しないということです。もしNullを許容する変数を宣言する場合は、「#データ型」というような形式でシャープを付与して宣言する必要があります。 

let str:#String = null

Curl6.0からサポートされた宣言方法で、定数を宣言する場合は、defという宣言の仕方ができます。これは定数としての宣言となります。また、データ型をしているする必要もありません。

def str = “あいうえお” || let constant str:String = “あいうえお”と同様 

 

式の結果を代入

式の結果を代入することができます。例えば、ifやswitch、valueの結果を変数に代入することができます。以下はif文の例です。 

set str
    {if a > 1 then
        “あいうえお”
     else
        “かきくけこ”
    }

 

値の増減

Javaのi++やi–のように値の増減をコーディングするには、incやdecを利用します。 

{inc i} || 増
{dec i} || 減

 

関連ドキュメント

基本構文

 

演算子

Curlで利用できる演算子は以下の通りです。

四則演算子 +, -, *, /, div, mod, rem
リレーショナル演算子 ==, !=, <, >, <=, >=, isa
論理演算子 and, or, not
文字列演算子(文字列の結合) &
強制変換演算子(キャスト) asa
NULL 許容演算子 #

 

{value
    let i:int = 2 * 2 
    let str:String = “AB” & “CD”
}

詳細については、以下のサイトをご覧ください。

演算子

 

条件式

条件式について説明していきます。

if文

基本的なルールは以下のようになります。

{if 式 then
    …
 elseif 式 then
    …
 else
    …
}

サンプルは以下のようになります。 

let x:int = 1
let y:int = 2
{if x > y then
    {output “xが大きい”} || outputは出力コンソールに表示するものです。
 else
    {output “yが大きい”}
}

ちなみに、Curlの特徴的な利用方法で、if文は値を返しますため、以下のように利用できます。 

let x:int = 1
let y:int = 2
{output
    {if x > y then
        “xが大きい” || outputは出力コンソールに表示するものです。
     else
        “yが大きい”
    }
}

unless文

これはif文の逆ですね。基本的にはあまり使わないと思います。

 

switch文

他の言語でもサポートされているswitch文です。値の評価には数値だけでなく、どんなデータ型でも可能です。 

{switch 比較変数 
 case 値1 do
    …
 case 値2 do
    …
 else
    …
}

サンプルは以下の通りです。 

let x:int = 1
{switch x
 case 0 do
    {output “xは0”}
 case 1, 2 do
    {output “xは1か2です”}
 else
    {output “xは3以上の値”}
}

 

type-switch文

データ型別に処理を行いたいときはtype-switch文を利用します。基本的にはswitch文と似ていますのでサンプルのみ下に記載します。

{type-switch x
 case i:int do
    {output “xはint”}
 case f:float do
    {output “xはfloat”}
 else
    {output “xはintでもfloatでもないです。”}
}

関連ドキュメント

条件式の構成

 

ループ式

Curlでのループ式の利用方法です。Curlでは、for、until、whileを利用することができます。また、他言語同様break、continueも装備しております。

for文

for文にはいくつかの記述方法があります。まずは、範囲内でのループの記述方法を記載します。

例えば、1づつ増加させていくようなループ文を記載するには、{for … to … step … do …}もしくは{for … below step … do …}を利用します。この2つのfor文は似ていますが、toは~までで、belowは~以下という場合に利用します。具体的なサンプルは以下の通りです。

|| 1づつ増やしていく
{for i:int = 0 below 8 do
    {output i}
}

これは0から7までの値をコンソールに表示します。またstepは、増分する値の幅を指定するために利用できます。

|| 2づつ増やしていく
{for i:int = 0 below 8 step 2 do
    {output i}
}

また減らしていく場合は、donwtoもしくはaboveを利用します。 

|| 2づつ減らしていく
{for i:int = 8 above 0 step 2 do
    {output i}
}

コンテナループについてはコレクション・クラスを説明の機会に紹介します。

 

while文

次にwhile文の記述方法です。条件がtrueの間、処理を繰り返します。 

{while 条件 do
    ….
}

サンプルは以下のようになります。

{while start < 10 do
    {output start}
    set start = start + 1
}

 

until文

Curlではuntil文についてもサポートしております。これは条件がfalseの間、処理を繰り返します。

{until 条件 do
    ….
}

サンプルは以下のようになります。

{until start == 10 do
    {output start}
    set start = start + 1
}

 

breakとcontinue

Curlは、他言語同様、breakやcontinueについてもサポートしております。 

{continue}

{break} 

 

関連ドキュメント

ループ式の構成

 

プロシージャとクロージャ

クロージャ

Javascriptなどで利用されるクロージャ機能はCurlにもあります。これは匿名プロシージャとも呼ばれます。これにはprocマクロを利用します。また、プロシージャとして型定義を指定するために、proc-typeマクロが用意されています。この機能を具体例に沿って説明していきたいとおもいます。

{curl 6.0 applet}

{value
    let p:{proc-type {int, int}:int} =
        {proc {a:int, b:int}:int
            || 足し算の結果を返す
            {return a + b}
        }

    {output {p 10, 20}} || 30
    {output {p 5, 30}}   || 35
}

ここでは、単純な足し算のクロージャを例にとって説明します。まず、クロージャを作成するには、procマクロを利用します。procマクロの引数に、実際に必要な引数(ここで足し算する2つの値aとb)を”{“と”}”で囲み、その後戻り値を”:”の後に記載します。あとは、中身のロジックを記載していきます。(ここでは足し算をし、結果を返すというものです。)また、このクロージャ自体を変数に代入する場合(上記の例では、pという変数に代入)、変数の型を定義するため、上記のようにproc-typeマクロを利用します。

このプロシージャを実行するには、変数名を”{“と”}”で囲み、実行します。例えば、上記のように{p 引数, 引数}のようにいます。また、この変数をさらに他のプロシージャやメソッドの引数として指定できますので、Javascriptでよく利用されるコールバック関数的な使い方もできます。

グローバル・プロシージャ(関数)

Curlでは、グローバルな関数(プロシージャ)も作成することができます。具体例を以下に記載します。

{curl 6.0 applet}

{define-proc public {add a:int, b:int}:int
    || 足し算の結果を返す
    {return a + b}
}

{value
    {output {add 20, 30}}
}

これを作成するには、define-procマクロを利用します。あとは、メソッドを作成するようのと同様に記載し、利用いたします。(もちろんpublic以外のプロシージャも作成できます。)

ラムダ式

C#でもサポートされているラムダ式がCurlでも利用できます。これによりプロシージャを利用する際、コード量を減らすことができます。サンプルは以下のようになります。

|| 通常のプロシージャ
def x = {proc {i1:int, i2:int}:int
              {return i1 * i2}
           }

|| ラムダ式(fnというマクロ。C#と同様=>演算子を利用します。
def x = {fn i1, i2 => i1 * i2}

 

関連ドキュメント

匿名プロシージャと引数

 

キーワード引数と残余引数

Curlにはキーワード引数残余引数という独特な引数を付与できます。

通常の引数

プロシージャやメソッド等の通常の引数では以下のようにします。

|| プロシージャの作成
{define-proc public {my-proc1 i:int}:void
   || 処理
}

{my-proc1 100} || 実行

キーワード引数(Keyword Argument)

Curlの持つキーワード引数とは、「引数 = 引数のデフォルト値」というように、プロシージャやメソッド等にセットします。以下に例を記載します。 

|| プロシージャの作成
{define-proc public {my-proc2 i:int = 100}:void
    || 処理
}

{my-proc2 i = 200}
{my-proc2} || {my-proc2 i = 100}と同等

また、複数キーワード引数を指定することや通常の引数と混合させることができます。 

|| プロシージャの作成
{define-proc public {my-proc3 
                                 str:String,
                                 i:int = 100,
                                 f:float = 1.0
                            }:void
    || 処理
}

{my-proc3 “abc”, i = 200}
{my-proc3 “efg”, f = 2.0}
{my-proc3 “xyz”}
{my-proc3 “abc”, i = 200, f = 2.0}

キーワード引数の利点としては、キーワード引数の値をセットする必要がなければ省略できますし、順番が前後しても特に問題がありません。

残余引数(Rest Argument)

残余引数とは、引数に名前(変数)を持たない引数を、無制限に受け取ることができます。これは3つのピリオド…”として指定します。また、”…:String”のように、型を指定することができます。

{define-proc public {my-proc4 }:void
}

{define-proc public {my-proc5 i:int, …:String}:void
}

プロシージャの中では以下のようにコンテナループでそれぞれの引数を順に取得することができます。 

{define-proc public {my-proc6 }:void
    {for v in do
        {output v}
    }
}

{my-proc6 “abc”, “def”, 123, 1.0, true}

ちなみに残余引数の数を算出するにはcount-argumentsマクロを利用します。例えば、{count-arguments …}のようになります。

詳細については、こちらを参照ください。

 

クラスの作成

クラス

Curlでクラスを作成するにはdefine-classを使用します。

{define-class public Person
    || ここにコンストラクタ、メンバ、メソッド等をコーディング
}

クラスのインスタンス化は、以下のようにします。 

let p:Person = {Person}
もしくは
let p:Person = {new Person}

コンストラクタ

コンストラクタは、constructorを利用します。また、デフォルトコンストラクタはdefaultという名前で作成します。

{define-class public Person

    field private _name:String

    {constructor public {default
                                   name:String
                               }
         set self._name = name
    }
}

default以外のコンストラクタも複数作成することができます。

{define-class public Person

    field private _name:String

    {constructor public {default
                                   name:String
                               }
         set self._name = name
    }

    {constructor public {TestConstructor
                                   first-name:String,
                                   last-name:String
                               }
         set self._name = first-name & ” ” & last-name
    }
}

{let p1:Person = {Person “amori”}} || デフォルトコンストラクタ
{let p2:Person = {Person.TestConstructor “akira”, “mori”}} || コンストラクタTestConstructor

フィールド、ゲッター(getter)、セッター(setter)

フィールドは上記の例の中の_name:Stringのように記載します。

また、ゲッター、セッターをCurlでは定義できます。Java等ではgetName、setNameのような名前でメソッドとして定義するのが通常ですが、Curlではゲッター、セッターをsettergetterを利用して、定義することができます。

{define-class public Person

    field private _name:String

    {getter public {name}:String
        {return self._name}
    }

    {setter public {name _name:String}:void
        set self._name = _name
    }

    {constructor public {default
                                   name:String
                               }
         set self._name = name
    }
}

{let p:Person = {Person “amori”}}
{output p.name}  || ゲッター
{set p.name = “hokada”} || セッター

また、getter、setterを簡単に記述するために、以下のサンプルのように、フィールドにアクセサとして記述することができます。

field public-get private-set x:String
field public-get package-set y:int
field public-get z:bool

 

メソッド

メソッドの定義には、methodを利用します。

{define-class public Person

    field private _name:String

    {constructor public {default
                                   name:String
                               }
         set self._name = name
    }

    || 戻り値 : Stringのメソッド
    {method public {toString}:String
        {return {format “I’m %s.”, self._name}}
    }
}

クラスの継承

クラスを継承するには、inheritsを利用します。また、construct-superを利用して、親クラスのコンストラクタをコールすることができます。さらに親クラスのメソッド等をコールするには、superを利用します。

{define-class public Member
    {inherits Person} || 親クラス

    field _id:int

    {getter public {id}:int
          {return self._id}
    }

    {constructor public {default
                                   id:int,

                                   name:String
                               }
         {construct-super name}
    }
}

{let m:Member = {Member 1, “amori”}}
{output m.id}
{output m.name} || 親クラスのゲッター

また、Curlでは多重継承もサポートしております。多重継承をするには、inheritsの中に複数のクラスをカンマ区切りでコーディングします。

{define-class public Child
    {inherits Oya1, Oya2, Oya3} || 親クラス(多重継承)

    || …….
}

抽象クラス(abstract)

CurlではJavaのようなインターフェースはサポートされていません。ただし、抽象クラスを作成することはできます。(もちろんabstractなメソッド)これを利用するには、修飾子にabstractを指定します。

{define-class public abstract AbstractPerson

    {method public abstract {toString}:String } 
}

アクセス属性

Curlのアクセス属性は、public、private、package、protectedを指定できます。それぞれの説明は以下のとおりです。

public 全コードがメソッドを呼び出すことができることを示します
package 同じパッケージ内のコードのみがメソッドを呼び出すことができることを示します(デフォルト)
protected 同じパッケージ内のコードまたはサブクラス内のコードのみがメソッドを呼び出すことができることを示します
private 同じクラス内のコードのみがメソッドを呼び出すことができることを示します

アクセス属性「library」

バージョン7からlibrary属性を付与できるようになりました。これは同じマニフェスト内ではpublicのような動きをし、違うマニフェストからはpublicとしてアクセスできないというものです。これにより、ライブラリなどで内部的にはパッケージ間で利用したいが、外部公開したくない場合にやくにたちます。(これはJava7のmoduleのような機能)

 詳細は、こちらを参照ください。

 

ファクトリの作成

Curlではファクトリパターンを“ファクトリ”という機能を利用して、簡単に実装できます。これはfactoryを利用します。 

|| TestFactory
{define-class public abstract TestFactory

  {getter public abstract {name}:String }

  {factory public {default
                      switch:int = 1
                  }:TestFactory
    {return
        {if switch == 1 then
            {Class01} || 子クラスのインスタンス生成
         else
            {Class02} || 子クラスのインスタンス生成
        }
    }
  }
}

|| Class01
{define-class public Class01 {inherits TestFactory}
  {getter public {name}:String
    {return “class 01”}
  }
}

|| Class02
{define-class public Class02 {inherits TestFactory}
  {getter public {name}:String
    {return “class 02”}
  }
}

{do
    def fac = {TestFactory switch = 2}
    {output fac.name} || 実行結果はClass02.nameの”class 02”
}

ファクトリの詳細はこちらをご覧ください。

パッケージの作成

パッケージの作成

Curlでパッケージを作成するには、まず以下のようにヘラルドにpackageを指定します。そのファイル内にpackage式を利用し、パッケージの内容を記述します。

{curl 6.0 package}

{package COM.CURLAP.ABC,
    author = “amori”,
    copyright = “Copyright ….”,
    version = “1.0”
}

|| ここに、クラスやプロシージャ等を定義していく。

ちなみに、Javaのようにディレクトリをパッケージ名と合わせる必要はありません。また、いくつかのファイルから構成される場合も、このpackageを指定しているファイル内で、includeを利用してファイルを読み込むことができます。 

{curl 6.0 package}

{package COM.CURLAP.ABC,
    author = “amori”,
    copyright = “Copyright ….”,
    version = “1.0”
}

|| クラス等を定義した外部ファイルを読み込む
{include “abc1.scurl”}
{include “abc2.scurl”}

|| 直接クラス等を記載できる。
{define-class public A
    || …
}
{define-class public B
    || …
}

パッケージのインポート

パッケージをインポートするにはimportを利用します。 

{import * from COM.CURLAP.ABC,
    location = “load.scurl” || 例えば上記のファイル名がload.scurlの場合
}

スーパーパッケージ

java7で出てきたsuperpackageのようなことも可能です。例えば以下のようにスーパーパッケージ(ここではCOM.CURLAP.SUPERPACK)を作成し、そのパッケージに含めるサブパッケージ(ここではCOM.CURLAP.AとCOM.CURLAP.B)をpublic属性付きでimportします。

{curl 6.0 package}

{package COM.CURLAP.SUPERPACK}

{import public * from COM.CURLAP.A}
{import public * from COM.CURLAP.B}

これをアプリケーションで利用する場合には、{import * from COM.CURLAP.SUPERPACK}と記述しますと、COM.CURLAP.AもCOM.CURLAP.Bもimportできます。

詳細については、こちらを参照ください。

データ型

Curlは、以下のような多くのデータ型をサポートしています。

プリミティブ型(整数、浮動小数点数、ブール値、文字、数量)

整数

小数部を持たない数値です。
int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、byte

浮動小数点

小数部を持つ数値です。
float、double

ブール値

trueまたはfalseのいずれかを格納します。デフォルトはfalseです。
bool

文字

文字(Curl言語の文字はUnicode標準に準拠しています。)
char

数量

数量は、値とそれに関する測定単位が一体となったものです。
Acceleration、Angle、Area、Distance、EmDistance、Fraction、Frequency、Intensity、Mass、Percent、PixelDistance、Resolution、Speed、Time

クラス型

これはdefine-classで作成されるクラスです。文字列、コレクションなどの組み込むクラスも含まれます。

プロシージャ

プロシージャをproc-typeマクロを利用し、変数の型として定義できます。詳細はプロシージャとクロージャを参照ください。

列挙型

指定した要素の固定リストから成るデータ型です。これはdefine-enumで定義することができます。

any型

任意のデータ型を格納できます。プリミティブを含むこともできます。デフォルトはnullです。変数に格納される値のデータ型がわかっている場合は、anyは利用しないでください。

 

各データ型の詳細は、こちらをご覧ください。

 

 

例外の作成とハンドリンク

CurlにもJava等同様に以下のように例外をtry~catchできます。

{try
    || 処理
 catch 例外1 do
    || 例外1発生時の処理
 catch 例外2 do
    || 例外2発生時の処理
 finally
    || finally処理

また例外クラスを作成するには、以下のサンプルのように、Exceptionクラスを継承して作成します。

{define-class public MyException {inherits Exception}
    {constructor public {default message:String}
         {construct-super message}
    }

このような例外を発生させるには、throwマクロを利用します。

{throw {MyException “My exception has occurred.”}}

以下はサンプルです。

{try
    let i:int = 0
    {if i < 0 then
        {throw {MyException “exception!!”}
    }
 catch e:MyException do
    {popup-message e.message}
}