Squirrel その4

Squirrel ではクラスが使用できます。
C++ほど便利なわけではないですが、一応継承も出来ます。
デストラクタはありませんがコンストラクタはあります。

class CVec3{
    x = 0.0;
    y = 0.0;
    z = 0.0;

    constructor(...)
    {
        if(vargc >= 3){
            x = vargv[0];
            y = vargv[1];
            z = vargv[2];
        }
    }

    function Print()
    {
        print(x + ", " + y + ", " + z + "\n");
    }
};

コンストラクタは constructor キーワードで作成します。
引数の ... は 0 個以上の引数を指定できます。
vargc に引数の個数、vargv の配列に引数の中身が入っています。
これはクラスのコンストラクタだけでなく、普通の関数でも使用できます。
なお、Squirrel では関数のオーバーロードは出来ません。
引数の数が違おうとも後に定義した関数やメソッドが有効になります。
このクラスを使用するにはインスタンスを作成します。

local v1 = CVec3();
local v2 = CVec3(1, 2, 3);
v1.x = v2.x;

メンバに private はありません。すべて public です。
面白いことに、クラスはテーブルと違って代入時にはコピーが作成されます。
また、テーブルを使うことで名前空間を作成することが可能です。

TestNamespace <- {
    Utils = {};
};
class TestNamespace.Utils.TestClass{
    constructor()
    {
        print("constructor is done.");
    }
};
function TestNamespace::Utils::TestClass::Print()
{
    print("I am TestClass.");
}

名前空間の指定方法が微妙にわかりにくいので気をつけてください。
また、クラスに外部からメンバを追加することも可能です。

class TestClass{
    constructor()
    {
        print("TestClass constructor.");
    }
};
TestClass.val <- 10;
function TestClass::Print()
{
    print("TestClass::Print.");
}

気をつけなければならないのはインスタンスを作成したあとにはメンバの追加が出来ないことです。
もちろんインスタンスに追加することも出来ません。この辺はテーブルと違う部分です。
メンバ変数には静的メンバ変数があります。

class TestClass{
    static test = "I am Static.";
};

静的メンバ変数はいわゆる定数にすぎません。変更不可。なお、静的メソッドはありません。
クラスの継承は extends キーワードを用います。

class Foo{
    constructor()
    {
        print("This is Foo constructor.");
    }
};

class FooEx extends Foo{
    constructor()
    {
        Foo.constructor();
        print("This is FooEx constructor.");
    }
};

local a = FooEx(); // FooEx のインスタンスを作成
local b = FooEx.parent; // FooExの継承元クラス(Foo)を取得する
local c = b(); // Fooのインスタンスを作成

メソッドは必ずオーバーライドされます。継承元のメソッドは明示的に実行する必要があります。
また、クラスには暗黙的に parent メンバが作成され、これが継承元クラスになります。
この継承元クラスをローカル変数に突っ込めばここから継承元クラスのインスタンスを作成できます。
Squirrel には operator の代わりにメタメソッドがあります。

class CVec3{
    function _add(other)
    {
        return CVec3(x + ohter.x, y + other.y, z + other.z);
    }
};

local a = CVec3(1, 2, 3);
local b = CVec3(4, 5, 6);
local c = a + b;

コンストラクタ等は前述のものが設定されているものとしてください。
_add は + のメタメソッドです。四則演算以外にも色々な命令に対するメタメソッドが用意されています。
メタメソッドには引数があるものとないものがありますが、引数の種類は何でもOKです。
例の場合はベクトルの加算なので引数は同じベクトルクラスですが、積算の場合は浮動小数点にすることができます。

で、クラスはこんなもんで。
次回で何とか言語仕様を終わらせる予定。