# Protra言語の文法

トップ > Protra言語の文法

Protraではチャートとトレーディングシステムの記述に独自のプログラミング言語であるProtra言語を使用します。

## プログラムの構成

Protra言語のプログラムは文を並べたものです。文と文の間は`;`または改行で区切ります。ただし、`\`か`_`に続く改行は無視されます。また、行の`#`か`//`より後ろは無視されます。文は式や制御文や関数定義からなります。式は定数、変数、関数呼び出し、配列の生成、配列の参照、@作用素と、これらを演算子で組み合わせたものです。

libディレクトリ以下に置かれたライブラリを読み込むときには、`require "`ライブラリ名`"`を用います。ライブラリ名はライブラリのファイル名から拡張子.ptを除いたものです。`#include <`ライブラリ名`>`も使えます。このときだけは`#`より後ろは無視されません。

## データ型

Protra言語で扱う型はint, float, string, null, 配列の5種類です。intは32bit符号付き整数、floatは倍精度浮動小数点、stringはShift_JISの文字列型、nullは空値`null`のみの型、配列は任意の型の値を格納可能な1次元の配列の参照型です。

## 定数

それぞれの型の定数は以下のように表せます。配列は定数として表せません。

    int     0, 12, 123, ...
    float   0.0, 12.345, ...
    string  "Protra", "program" ...
    null    null

## 変数

変数には任意の型の値を代入できます。変数にはグローバル変数とローカル変数があります。グローバル変数は$から始まる名前でなければなりません。ローカル変数は小文字のアルファベットから始まる名前でなければなりません。以下に例を挙げます。

    グローバル変数  $global, $Global, $g_val, ...
    ローカル変数    local, local2, l_val, ...

一度も代入されていないローカル変数を参照するとエラーになります。代入されていないグローバル変数を参照すると`null`が返ります。ローカル変数は見かけ上代入されていればよいので、代入されていなくてもエラーにならずに`null`が返ることがあります。

    if 0
        hoge = 1    ←実行されない
    end
    if hoge         ←hogeの値はnull
        ....
    end

## 演算子

演算子は基本的にC言語やJavaと同じです。+=などの複合代入演算子や++や--は使えません。ビット演算子も使えません。floatとintの間の演算結果は常にfloatになります。stringの加算は結合した文字列を返します。stringと数値の加算は数値を文字列に変換して結合したものを返します。

int、float、stringについてキャスト演算子が使えます。floatからintへキャストしたときに、値が2つの整数の中間にある場合は偶数になります。たとえば、(int)4.5は4に(int)5.5は6に変換されます。intやfloatをstringにキャストすると文字列に変換されます。stringからintやfloatにキャストすると数値へ変換され、変換に失敗すると0か0.0になります。nullと配列はキャストできません。

## 論理値

`0`、`0.0`、`null`は偽、その他はすべて真として扱われます。

## 制御文

繰り返しや条件分岐を表現するためにwhile文とif文が使えます。

### while文

while文は以下のように記述します。条件式が真である間、処理が繰り返し実行されます。処理には関数定義以外の任意の数の文を書けます。

    while 条件式
        処理
    end

### if文

if文は以下のように記述します。各処理には関数定義以外の任意の数の文を書けます。

    if 条件式1
        処理1
    elsif 条件式2
        処理2
    else
        処理3
    end

1. 条件式1が真ならば処理1のみが実行される。
2. 条件式1が偽のとき条件式2が真ならば処理2のみが実行される。
3. 条件式1が偽のとき条件式2が偽ならば処理3のみが実行される。

以上のような動作をします。ただし、elseは省略できます。elsifはいくつでも追加できますし、省略することもできます。

## 配列

配列は以下のように生成します。これで指定した要素数の配列が生成されて配列型の値が返ります。生成された配列のすべての要素はnullです。

    [要素数]

配列の要素を参照するには以下のようにします。int型の式の値は0〜要素数-1でなければなりません。

    配列型の式[int型の式]

例として100個の要素を用意し、1から100を順に代入するプログラムを示します。

    arr = [100]
    i = 0
    while i < 100
        arr[i] = i + 1
        i = i + 1
    end

データ型で述べたように配列は参照型です。つまり以下のように、ある変数から別の変数へ配列型の値を代入したときには、配列はコピーされずに2つの変数が同じ配列を指します。

    arr1 = [100]
    arr2 = arr1
    arr1[0] = 10    ←arr2[0]も10になる
    arr2[1] = 20    ←arr1[1]も20になる

配列の要素に配列型の値を代入することもできるので、これを利用すると多次元の配列を作れます。

    arr1 = [2]
    arr1[0] = [100]
    arr1[1] = [100]
    arr1[0][10] = 100
    arr1[1][20] = 200

## 関数

関数は以下のように定義します。処理には関数定義以外の任意の数の文を書けます。関数名の最初は大文字のアルファベットでなければなりません。同じ名前で引数の数が異なる関数を定義することができます。引数がない場合は()を省略できます。

    def 関数名(仮引数1, 仮引数2, ...)
        処理
    end

関数が返す値はreturn文で以下のように指定します。return文を書かない場合は`null`が返ります。

    return 式

関数呼び出しは以下のように行います。引数がない関数は()を省略して関数名だけで呼ぶこともできます。

    関数名(実引数1, 実引数2, ...)

例として1から100までの和を計算する関数Sum100を定義し、変数sumにSum100を呼び出して値を代入するプログラムを示します。

    def Sum100
        i = 1
        sum = 0
        while i <= 100
            sum = sum + i
            i = i + 1
        end
        return sum
    end
    sum = Sum100

引数を取る関数の例として、1からnまでの和を計算する関数Sumを定義し、変数sumにSumを呼び出して1から100までの和を代入するプログラムを示します。

    def Sum(n)
        i = 1
        sum = 0
        while i <= n
            sum = sum + i
            i = i + 1
        end
        return sum
    end
    sum = Sum(100)

## @作用素

すべての関数は定義された引数のほかに、暗黙のうちにatという引数を持ちます。何も指定せずに関数を呼び出した場合atの値は0です。

atを指定したい場合は以下のように@作用素で指定します。int型の式の値が@作用素の値で、右側の式における関数呼び出しでatの値になります。@作用素の式としての値は右側の式の値です。

    {int型の式}式

例としてatからn個の数の和を計算する関数ShiftSumを定義し、変数sumに101から200までの和を代入するプログラムを示します。

    def ShiftSum(n)
        i = 1 + at
        n = n + at
        sum = 0
        while i <= n
            sum = sum + i
            i = i + 1
        end
        return sum
    end
    sum = {100}ShiftSum(100)

@作用素を指定した式で@作用素を使用すると、加算した値が@作用素の値になります。関数の中で@作用素を使用すると、atと加算したものが@作用素の値になります。例えば以下の4個の式はすべて同じ値となります。

    (1)
    {1}Func1 + {2}Func2 + 2

    (2)
    {1}(Func1 + {1}Func2 + 2)

    (3)
    def Func
        return {1}Func1 + {2}Func2 + 2
    end
    Func

    (4)
    def Func
        return Func1 + {1}Func2 + 2
    end
    {1}Func

@作用素はProtra言語で最も重要な仕組みです。独自のテクニカル指標を関数として定義する際に大きな効力を発揮します。

Copyright (C) 2003 Daisuke Arai.
Copyright (C) 2008, 2010 panacoran.
This document may be used under the term of the GNU General Public License version 3 or higher.