構文 - Script Language 
Last-modified: 2010-03-24 (水) 22:24:36
このページについて 
AngelScript(AS)のスクリプト構文について書きます。
(このページに書かれているサンプルコードの一部はAngelScript公式のドキュメントから転載しています。)
「同等」と「同様」について 
文中で「C++と同等」と「C++と同様」という言葉を使っています。
「C++と同等」は「C++とほぼ同じ」という意味合いで,
「C++と同様」は「C++と全く同じ」という意味合いで使っています。
字句 
コメント 
C++と同様に1行コメント,ブロックコメントの2種類が使えます。
値 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
| int a = 3;
int b = 0xFFFF;
double ca = 1.2345;
double cb = 1.2345e10;
float da = 1.2345f;
float db = 1.2345e10f;
bool ea = true;
bool eb = false;
|
型 
組み込み型 
C++と同等の組み込み型が用意されています。
- void
- C++と同様に関数の戻り値に型に使います。
- bool
- C++と同様のもので,true,falseのどちらかの値を持ちます。
- 整数
- 下記のタイプが存在します。
型名 | 最小値 | 最大値 |
int8 | -128 | 127 |
int16 | -32768 | 32767 |
int int32 | -2147483648 | 2147483674 |
int64 | -92233772036854775808 | 9223372036854775807 |
uint8 | 0 | 255 |
uint16 | 0 | 65535 |
uint uint32 | 0 | 4294967295 |
uint64 | 0 | 18446744073709551615 |
公式のドキュメントによると,パフォーマンスを最適化したいのであれば
32bitより小さい型の値はクラスのメンバ変数など,データを保持するもののみに使用し,
それ以外(ローカル変数,一時変数など)は32bitの型の値を使用したほうがいいようです。
- 小数
- 下記のタイプが存在します。
型名 | 値の範囲 | 一番小さい正の値 | 最大桁数 |
float | +/- 3.402823466e+38 | 1.175494351e-38 | 6 |
double | +/- 1.7976931348623158e+308 | 2.2250738585072014e-308 | 15 |
公式のドキュメントによりますと,ASではNaN(Not-aNumber)を0x7fc00000で表現しているようです。
配列 
配列の変数は次のように宣言します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
| int[] intArray;
int[] intArrA,intArrB,intArrC;
int[] a;
int[] b(3);
int[] c = {1,2,3};
|
配列はC++と同様にインデクス式を使ってアクセスします。
また,配列の長さはlength()メソッドにより取得できます。
1
2
3
4
5
|
-
|
!
| int[] a = {0,1,2};
for ( uint i = 0; i < a.length(); ++i )
{
a[i] += 1;
}
|
ユーザー定義型 
ユーザー定義型(クラスや列挙型)の変数はC++と同様に宣言することができます。
1
2
3
4
5
6
|
| obj a;
a = obj();
|
オブジェクトハンドル 
オブジェクトハンドルとはC++でいう参照・ポインタにあたるものです。
参照先のオブジェクトは参照カウンタで寿命を管理しているため,「既に破棄されたデータにアクセスする」という不正なデータアクセスはおこりません。
もしnullなオブジェクトハンドルにアクセスしようとしたら例外が発生しスクリプトの実行が止まります。
1
2
3
4
5
6
7
8
9
10
11
|
-
|
!
| obj o;
obj@ a; obj@ b = @o;
b.ModifyMe();
if ( a is null ) {
@a = @b; }
|
文字列 
ASでの文字列は8bitもしくは16bitのデータの配列として扱われます。
ASではC++と同等のエスケープシーケンス文字が用意されています。
下記がエスケープシーケンス文字をまとめた表です。
文字 | 値 | 意味 |
¥0 | 0 | null文字 |
¥¥ | 92 | バックスラッシュ |
¥' | 39 | シングルコーテーション |
¥" | 34 | ダブルコーテーション |
¥n | 10 | 改行文字 LF |
¥r | 13 | 改行文字 CR |
¥t | 9 | TAB |
¥xFFFF | 0xFFFF | 16bitで表した文字 |
¥uFFFF | 0xFFFF | unicode16bitで表した文字 |
¥uFFFFFFFF | ¥0xFFFFFFFF | unicode32bitで表した文字 |
文字列はダブルコーテーションもしくはシングルコーテーション(要オプション設定)で囲んで表します。
1
2
3
4
5
6
7
8
|
| string str1 = "This is a string with \"escape sequences\".";
string str2 = 'If single quotes are used then double quotes can be included without "escape sequences".';
|
C++と同様に複数の文字列を1つの文字列として連結することができます。
1
2
3
|
| string str = "First Line.¥n"
"Second Line.¥n";
|
ASでは"""を使うことで複数行に渡す文字列を簡単に記述することができます。
1
2
3
4
5
|
| string str = """
First Line.
Second Line.
""";
|
文 
宣言文 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
| int var = 0, var2 = 10;
object@ handle, handle2;
const float pi = 3.141592f;
int randaomVar;
object@ nullHandle;
object defaultCtorCalled;
|
式文 
C++同様の式文が使えます。詳しくは式の項をご覧ください。
if文 
C++同等のif文が使えます。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
-
|
!
-
|
!
-
|
!
| if( condition )
{
}
if( value < 10 )
{
}
else
{
}
|
ただし,C++と異なり,C#のように条件部はbool値である必要があります。
1
2
3
4
5
6
7
8
9
10
11
|
-
!
-
!
| int notZeroValue = 1;
if ( notZeroValue ) {
}
if ( notZeroValue != 0 )
{
}
|
for文 
C++と同等のfor文が使えます。
ただし,条件部はif文と同じようにbool値である必要があります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
-
|
|
|
|
|
|
-
|
!
|
-
|
!
!
| for ( int n = 0; n < 10; ++n )
{
if ( n == 5 )
{
continue;
}
if ( n == 9 )
{
break;
}
}
|
while文 
C++と同等のwhile文が使えます。
ただし,条件部はif文と同じようにbool値である必要があります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-
|
|
|
|
-
|
!
|
-
|
!
!
| int i = 0;
while( i < 10 )
{
i++;
if ( i == 5 )
{
continue;
}
if ( i == 9 )
{
break;
}
}
|
do-while文 
C++と同等のdo-while文が使えます。
ただし,条件部はif文と同じようにbool値である必要があります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-
|
|
|
|
-
|
!
|
-
|
!
!
| int i = 0;
do
{
i++;
if ( i == 5 )
{
continue;
}
if ( i == 9 )
{
break;
}
}while( i < 10 );
|
switch文 
C++と同様のswitch文が使えます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
-
|
|
|
|
|
|
|
|
|
|
|
!
| switch( value )
{
case 0:
break;
case 2:
case constant_value:
break;
default:
}
|
return文 
C++と同様のreturn文が使えます。
1
2
3
4
5
6
7
8
9
|
-
|
!
-
|
!
| float valueOfPI()
{
return 3.141592f; }
void function()
{
return; }
|
スコープブロック文 
C++と同様のスコープブロック文が使えます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| -
|
|
|
-
|
|
|
|
!
|
|
!
| {
int a;
float b;
{
float a;
b = a;
}
}
|
式 
代入式 
C++と同様の代入式が使えます。
代入演算式 
C++と同等の代入式が使えます。
ASのシフト演算はC++のものと異なり,左シフト,符号無し右シフト,符号有り右シフトの3種類のシフトが使えます。
1
2
|
| lvalue += rvalue;
lvalue = value + rvalue;
|
使用可能な代入演算記号は下記の通りです。
+= -= *= /= = &= |= ^= <<= >>= >>>=
関数呼び出し 
C++と同様の関数呼び出しが使えます。
1
2
3
4
|
| func();
func(arg);
func(arg1, arg2);
lvalue = func();
|
型変換式 
オブジェクトハンドルの型変換の例を下記に示します。
もし,オブジェクトハンドルの型変換に失敗したらnullのオブジェクトハンドルが返されます。
1
2
3
4
5
6
7
|
| intf @a = @clss();
clss @b = cast<clss>(a);
|
組み込み型の値の変換式 
組み込み型の値の変換の例を下記に示します。
1
2
3
4
5
|
| int a = 1.0f;
float b = float(a)/2;
|
算術演算式 
C++と同様の算術演算式が使えます。
c = -(a + b);
演算記号 | 説明 | 左項 | 右項 | 結果 |
+ | 正符号演算 | - | 数値 | 数値 |
- | 負符号演算 | - | 数値 | 数値 |
+ | 加算 | 数値 | 数値 | 数値 |
- | 減算 | 数値 | 数値 | 数値 |
* | 乗算 | 数値 | 数値 | 数値 |
/ | 除算 | 数値 | 数値 | 数値 |
% | 余算 | 数値 | 数値 | 数値 |
ビット演算式 
C++と同等のビット演算式が使えます。
ASではD言語のように右シフトが2種類に増えています。
c = ~(a | b);
演算記号 | 説明 | 左項 | 右項 | 結果 |
ビット反転 | - | 数値 | 数値 |
& | ビット論理積 | 数値 | 数値 | 数値 |
| | ビット論理和 | 数値 | 数値 | 数値 |
^ | ビット排他論理和 | 数値 | 数値 | 数値 |
<< | 左シフト | 数値 | 数値 | 数値 |
>> | 右シフト | 数値 | 数値 | 数値 |
>>> | 算術右シフト | 数値 | 数値 | 数値 |
論理演算式 
C++と同等の論理演算式が使えます。
ASでは,not,and,or,xorが既存の演算記号の代わり使うことができます。
if ( a and b or not c ) {}
演算記号 | 説明 | 左項 | 右項 | 結果 |
not ! | 論理否定 | - | bool値 | bool値 |
and && | 論理積 | bool値 | bool値 | bool値 |
or || | 論理和 | bool値 | bool値 | bool値 |
xor | 排他論理和 | bool値 | bool値 | bool値 |
等値式 
C++と同様の等値式が使えます。
1
2
3
4
5
6
|
-
!
-
!
| if ( a == b )
{
}
if ( a != b )
{
}
|
比較式 
C++と同様の比較式が使えます。
1
2
3
4
|
| if ( a < b ) {}
if ( a <= b ) {}
if ( a > b ) {}
if ( a >= b ) {}
|
同一性式 
2つのオブジェクトハンドルが示すものが同じかどうかを調べる式です。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
-
|
!
-
|
!
-
|
!
| object@ a,b;
if ( a is null )
{
}
if ( a !is null )
{
}
if ( a is b )
{
}
|
インクリメンタル式・デクリメンタル式 
C++と同様のインクリメンタル式,デクリメンタル式が使えます。
1
2
3
4
5
6
7
8
9
10
11
|
| a = i++;
b = ++i;
c = i--;
d = --i;
|
インデクス式 
C++と同様のインデクス式が使えます。
添え字に使う型は,インデクス式がオーバーロードできるためオブジェクトのタイプごとに異なります。
arr[i] = 1;
条件式 
C++と同等の三項条件式が使えます。
if文と同様に,条件部はbool値である必要があります。
condition ? a : b;
メンバアクセス 
object.property = 1;
object.method();
C++と同様にオブジェクトのメンバにアクセスできます。
ASではオブジェクトにプロパティアクセサを持つことができるため
メンバ変数にアクセスしているように見えて,実際は関数を呼び出しているということもありえます。
詳細はクラスのプロパティアクセサの項をご覧ください。
オブジェクトハンドルアクセス 
オブジェクトのハンドルにアクセスする際に頭に@をつけます。
この記号を使うことで,オブジェクトハンドルが指すオブジェクトを変更したり,参照したりします。
1
2
3
4
5
|
| @handle = @object;
@handle = null;
|
丸括弧 
C++と同様の丸括弧が使えます。
a = c * ( a + b );
スコープ解決 
C++に似たスコープ解決演算子が使えます。
::を使うことでグローバル変数・関数を指定することができます。
1
2
3
4
5
6
|
-
|
|
!
| int value;
void function()
{
int value; ::value = value; }
|
オブジェクトハンドル 
オブジェクトハンドルはオブジェクトの参照を保持することができる型です。
オブジェクトハンドルを使うことで,1つのオブジェクトを複数の変数からアクセスできるようになります。
C++でいうポインタや参照と同じようなものだと考えてください。
オブジェクトハンドル変数の宣言 
オブジェクトハンドルの型は型名 + @で表現します。
object@ obj_h;
このコードでは,obj_hにnull参照が保持されます。
null参照が保持されている状態は,オブジェクトの参照を保持していない状態と考えてください。
メンバへのアクセス 
オブジェクトハンドルが参照しているオブジェクトのメンバへのアクセスは
通常のオブジェクトのメンバへのアクセスと同じようにアクセスします。
object obj;
object@ obj_h;
obj.Method();
obj_h.Method();
もし,オブジェクトハンドルがnull参照を保持している状態でメンバへアクセスしようとすると
例外が発生し,実行中のスクリプトが停止します。
値のコピー 
オブジェクトハンドルの変数に対して代入演算子=を使うと,
通常のオブジェクト変数に対して代入演算を記述したときと同じことが行われます。
object obj;
object@ obj_h;
obj_h = obj;
もちろん,オブジェクトハンドルがnull参照を保持している場合は例外が発生します。
参照のコピー 
オブジェクトハンドルが保持する参照をコピーしたい場合は@記号を使います。
object obj;
object@ obj_h;
@obj_h = @obj;
同一性チェック 
同一性式を使うことで,2つのオブジェクトハンドルが同じオブジェクト参照を保持しているか調べることが出来ます。
object@ obj_a, obj_b;
if ( obj_a is obj_b ) {}
if ( obj_a !is null ) {}
オブジェクトの寿命 
オブジェクトハンドルが参照するオブジェクトは
全てのオブジェクトハンドルから参照を保持されなくなった時点で解放されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-
|
|
|
|
|
!
| object@ obj_h;
{
object obj;
@obj_h = @obj;
}
obj_h.Method();
@obj_h = null;
|
ポリモフィズム 
オブジェクトハンドルを使うことで基底クラス・インターフェースのへの変換やダウンキャストを実現します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
-
|
|
|
-
|
!
|
-
|
!
!
| interface I {}
class A : I {}
class B : I {}
I @i1 = A();
I @i2 = B();
void function(I @i)
{
A @a = cast<A>(i);
if( a is null )
{
}
else
{
}
}
|
関数 
変数 
インターフェース 
ASのインターフェースはC#やD言語と同等のものと考えてもらって構いません。
インターフェースにはC++でいう純粋仮想関数を宣言することができます。
ただし,C#やD言語のインターフェースとは異なり,インターフェースが他のインターフェースを継承することはできません。
その代わり,クラスは複数のインターフェースを継承することができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
-
|
!
-
|
-
!
!
| interface MyInterface
{
void DoSomething();
}
class MyClass : MyInterface
{
void DoSomething()
{
}
}
interface IntfA {}
interface IntfB {}
class Example : IntfA , IntfB {}
|
import 
列挙型 
C++と同様のenumが使えます。
1
2
3
4
5
6
7
|
-
|
|
|
|
!
| enum MyEnum
{
eValue0,
eValue2 = 2,
eValue3,
eValue200 = eValue2 * 100
}
|
typedef 
クラス 
使い方 
演算式オーバーロード 
プロパティアクセサ 