C++/スクリプト/メモ
をテンプレートにして作成
ホーム
検索
最終更新
ヘルプ
Wiki書式ヘルプ(整形ルール)
開始行:
* メモ [#u10b9718]
#contents
* エンジンの型 [#z659e65c]
説明の際にところどころ出てくるので書いておく。
|名前|役割|h
|SSObjectType|ユーザー定義型を扱うクラス。1ユーザー定義型...
|SSVariable|変数を扱うクラス。1変数につき1インスタンス。|
|SSFunction|関数を扱うクラス。1関数につき1インスタンス。|
|SSFunctionArg|関数の引数を扱うクラス。1引数につき1インス...
|SSVirtualFuncTable|仮想関数テーブルを扱うクラス。1仮想関...
* コード生成 [#y3d91a37]
シンプルでもいける気がしてきた。
** レジスタ構成 [#ka053590]
|Full Name|Short Name|Comment|h
|Stack Register Pointer|SRP|スタックレジスタポインタ。&br...
|Stack Pointer|SP|スタックポインタ。現在のスタック位置。|
|Program Counter|PC|プログラムカウンタ。現在実行している...
|Program Function|PF|プログラムの関数オブジェクトのポイン...
|Program Line|PL|プログラムのソースコードの行数。デバッグ...
|Link Register|LR|リンクレジスタ。戻り先のバイトコードの...
|Function Register|FR|関数レジスタ。全部で16個。FR00 - FR...
** レジスタの概要 [#b2e56c51]
- 1つのレジスタのサイズは8バイト。
- 4バイトでもいいかなと思ったが,64bit環境でポインタが1...
- ただし,メモリがきつきつの環境もあるので32bitモード用意...
- 1つのレジスタはUNIONで表現。
#code(c,){{
struct Register
{
union
{
u32 data32;
u64 data64;
s32 i32val;
s64 i64val;
f32 f32val;
f64 f64val;
void* ptr; // 64bit環境だとこれは8バイト。
};
};
}}
** スタックレジスタ [#bb1584f7]
- 計算の一時領域として使うレジスタはStackRegister(スタッ...
- スタックレジスタ数は動的に変更し,最大で256。それを越え...
- SRP(Stack Register Pointer)からのオフセットがスタック...
- SR01ならSRP + 0x08のアドレスとなる。(32bitモードなら+0x...
- 通常,関数の先頭でFUNCET命令を使い関数で使用するスタッ...
** 変数とレジスタ [#w8f36726]
- ローカル変数は全てスタックレジスタに割り当てられる。
- スコープを考慮してスタックレジスタの使用数はなるべく少...
- 一時変数もスタックレジスタに割り当てられる。
#code(c,){{
utility Hoge {
static void func()
{
int a; // SR01
int b; // SR02
{
int c; // SR03
}
int d; // SR02
{
int e; // SR03
}
d = (a + b) * d;
// (a + b)が一時変数としてSR03に格納される
// SR03 = a + b;
// SR02 = R03 * R02;
}
};
}}
** 戻り値とレジスタ [#lb8a56e2]
- 戻り値はFR00に格納される。
- FUNCRT命令が実行されるとSR00の値はFR00にコピーされる。
#code(c,){{
utility Hoge
{
static int GetOne()
{
return 1; // FR00 = 1
}
};
}}
** 引数とレジスタ [#g01df345]
- 引数は関数レジスタのFR01から順番にレジスタに割り当てら...
- 非staticなメンバ関数はFR01にthisポインタが割り当てられ...
- 関数レジスタは16個しか用意されていないので,引数の最大...
#code(c,){{
pod Vector3
{
float x;
float y;
float z;
void func(float addValue)
{
// FR01 : this
// FR02 : addValue
}
}
}}
** アセンブラのイメージ [#sc9a365f]
- 簡単なコード
#code(c,){{
0:int add(int a, int b)
1:{
2: return a + b;
3:}
4:void func()
5:{
6: int i = 3;
7: i = add(i , 4);
8:}
# 命令コード
Instruction:
add:
DFUNC 0x0000
DLINE 1 // '{'の位置
FUNCET 0x03 0x03
DLINE 2
ADDI32 R00 R01 R02
DLINE 3 // '}'の位置
FUNCLV 0x03
func:
DFUNC 0x0001
DLINE 5
FUNCET 0x02 0x00
DLINE 6
LDSRC4 SR00 0x0000
DLINE 7
LDSRC4 SR01 0x0004
LDFRSR FR01 SR00
LDFRSR FR02 SR01
CALL 0x0000
LDRF SR00 FR00
FUNCLV 0x02
# コンパイル時に確定する定数のテーブル
ConstantTable:
0x0000: 3
0x0004: 4
SymbolTable:
0x0000: int add(int,int)
0x0004: void func()
}}
** 命令コード [#ac30d5cb]
- どの命令コードも32bitで統一。
- SRegおよびFRegはu8。
|命令|書式|コメント|h
|>|>|BGCOLOR(ORANGE):''ロード''|
|LDSRC1|LDSRC4 SReg ConstantTableIndex(u16)|ConstantTable...
|LDSRC2|~|~|
|LDSRC4|~|~|
|LDSRC8|~|~|
|LDSRSR|LDSRSR SReg1 SReg2|SReg2の値をSReg1にロード|
|LDSRSP|LDSRSP SReg1 StackPointerOffset(u16)|StackPointer...
|LDSRP1|LDSRP1 SReg1 SReg2|SReg2の値をアドレスとみなし,S...
|LDSRP2|~|~|
|LDSRP4|~|~|
|LDSRP8|~|~|
|LDSROJ|LDSROJ SReg1 SReg2|SReg2の値をobject型とみなし,S...
|LDFRSR|LDFRSR FReg SReg|SRegの値をFRegにロード|
|>|>|BGCOLOR(ORANGE):''演算''|
|ADDxxx|ADDI32 SReg1 SReg2 SReg3|SReg1 = SReg2 + SReg3|
|SUBxxx|SUBI32 SReg1 SReg2 SReg3|SReg1 = SReg2 - SReg3|
|MULxxx|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 * SReg3|
|DIVxxx|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 / SReg3|
|MODxxx|MODS32 SReg1 SReg2 SReg3|SReg1 = SReg2 % SReg3|
|>|>|BGCOLOR(ORANGE):''関数あれこれ''|
|FENTER|FENTER AllocSRegNum CopyFRegNum|Function Enter. &...
|FLEAVE|FLEAVE FreeSRegNum|Function Leave. &br;FreeSRegNu...
|CALL|CALL SymbolTableIndex(u16)|LRにPCを代入する。 &br;S...
|CALLVF|CALLVF SReg1 ConstantTableIndex(u16)|Call Virtual...
|>|>|BGCOLOR(ORANGE):''スタック''|
|PUSH|PUSH SReg ConstantTableIndex(u16)|ConstantTableInde...
|POP|POP ConstantTableIndex(u16)|ConstantTableIndexが指す...
|>|>|BGCOLOR(ORANGE):''オブジェクト''|
|OBJNEW|OBJNEW SReg SymbolIndex|Object New.&br;指定のSymb...
|OBJDEL|OBJDEL SReg|Object Delete.&br;指定のSRegが指すオ...
|OBJRFI|OBJRFI SReg|Object Reference Increment.&br;指定の...
|OBJRFD|OBJRFD SReg|Object Reference Decrement.&br;指定の...
|>|>|BGCOLOR(ORANGE):''デバッグ''|
|DLINE|DLINE ConstantValue(u24)|Debug Line.&br;デバッグ情...
|DFUNC|DFUNC SymbolTableIndex(u16)|Debug Function.&br;デ...
* オブジェクトファイル [#sfc8fd99]
- Cでいう.oのファイル。
含まれるもの
- モジュール名
- 定数テーブル
- シンボルテーブル
- シンボル一覧
- シンボル解決情報
** モジュール名 [#j6a7768c]
- モジュール名が文字列として格納される。
** 定数テーブル [#wf3e79a4]
- 必要な定数テーブルの長さ。
- コンパイル時に解決されている定数郡。
- .oのファイルサイズ縮小のために,コンパイル時に解決され...
- そうしておくことで,リンク時に解決される定数郡のデータ...
** シンボルテーブル [#bfa16e2a]
- 必要なシンボルテーブルの長さのみ格納される。
** シンボル一覧 [#a5552a6f]
- モジュールはユーザー定義型リストを持つ。
:ユーザー定義型リスト|
- ユーザー定義型についての情報が0個以上格納されている。
- エンジンではユーザー定義型の情報が1つにつきSSObjectTyp...
|項目|内容|例|h
|シンボルのパス|文字列|BaseLib.Math.Vector3|
|継承しているクラスのパス|文字列|Foo|
|仮想関数テーブルリスト|別項:仮想関数テーブルリストを参...
|変数リスト|別項:変数リストを参照||
|関数リスト|別項:関数リストを参照||
:仮想関数テーブルリスト|
- 仮想関数テーブルについての情報が0個以上格納されている。
- エンジンでは仮想関数テーブルの情報が1つにつきSSVirutal...
|項目|内容|例|h
|シンボルのパス|文字列|BaseLib.IDrawable|
|仮想関数シンボルテーブル|SymbolTableIndexの配列||
:変数リスト|
- 変数についての情報が0個以上格納されている。
- エンジンでは変数の情報が1つにつきSSVariableが1つ生成...
|項目|内容|例|h
|型を示すシンボルのパス|文字列|float|
|シンボル名|文字列|x|
|staticフラグ|bool(staticか否か)||
|readonlyフラグ|bool(readonlyか否か)||
|constフラグ|bool(constか否か)||
:関数リスト|
- 関数についての情報が0個以上格納されている。
- エンジンでは関数の情報が1つにつきSSFunctionが1つ生成...
|項目|内容|例|h
|シンボル名|文字列|add|
|戻り値の型を示すシンボルのパス|文字列|BaseLib.Math.Vecto...
|戻り値のconstフラグ|bool(constか否か)||
|引数リスト|別項:引数リストを参照||
|staticフラグ|bool(staticか否か)||
|constフラグ|bool(constか否か)||
|命令コード|バイトコード||
:引数リスト|
- 引数についての情報が0個以上格納されている。
- エンジンでは引数の情報が1つにつきSSFunctionArgが1つ生...
|項目|内容|例|h
|型を示すシンボルのパス|文字列|float|
|constフラグ|bool(constか否か)||
|refフラグ|bool(refか否か)||
** シンボル解決情報 [#jec91c98]
- シンボルの種類は変数・関数・ユーザー定義型の3つ。
:変数|
|項目|内容|例|h
|代入先|定数テーブル or シンボルテーブル|-|
|シンボルパス|解決するシンボルのパス|BaseLib.Math.Vector3...
|シンボルの何を取得するのか。|・変数オブジェクト(SSVaria...
:関数|
|項目|内容|例|h
|代入先|シンボルテーブル|-|
|シンボルパス|解決するシンボルのパス|BaseLib.Math.Vector3...
|引数リスト|引数の型のリスト||
|属性|const,staticなどの属性||
|シンボルの何を取得するのか。|・関数オブジェクト(SSFuncti...
:ユーザー定義型|
|項目|内容|例|h
|代入先|定数テーブル|-|
|シンボルパス|解決するシンボルのパス|BaseLib.Math.Vector3|
|シンボルの何を取得するのか。|・ユーザー定義型オブジェク...
* 意味解析 [#xe319000]
構文解析が終わった後,コード生成より前にやること。
- ModuleをModuleReposに登録。
- TypePathを解決し,型にリンクさせる
- 関数名・変数名がだぶっていないかチェック。
- 定数(enum,immutable)の確定
- ユーザー定義型のサイズの決定
- ユーザー定義型の静的・非静的メンバ変数の位置を決定
- 自動生成関数の生成
- 関数のレジスタ割り当ての決定
- 関数の定数テーブルを作成
- 関数の非値型のスタックマッピングおよびスタックサイズを...
* 道のり [#s3b4b6c0]
- 意味解析
-- まずutilityと関数だけにしぼる
-- 全てのModuleをシンボルツリーに登録
-- 全ての型をシンボルツリーに登録
-- 関数をシンボルツリーに登録。
-- 関数の中身を意味解析
--- 関数の中身のTypePathやIdentPathのシンボルを解決
--- 意味解析したStatementに置き換え。
* 仕様変更履歴 [#a0f3a6ff]
:2010/07/29|
- prototype moduleの概念を追加。
- classの代入演算子オーバーロードを禁止に。D言語準拠にし...
- オブジェクトハンドルの概念をなくした。
- isと!isを追加。セットでIdentityExpressionも追加。
終了行:
* メモ [#u10b9718]
#contents
* エンジンの型 [#z659e65c]
説明の際にところどころ出てくるので書いておく。
|名前|役割|h
|SSObjectType|ユーザー定義型を扱うクラス。1ユーザー定義型...
|SSVariable|変数を扱うクラス。1変数につき1インスタンス。|
|SSFunction|関数を扱うクラス。1関数につき1インスタンス。|
|SSFunctionArg|関数の引数を扱うクラス。1引数につき1インス...
|SSVirtualFuncTable|仮想関数テーブルを扱うクラス。1仮想関...
* コード生成 [#y3d91a37]
シンプルでもいける気がしてきた。
** レジスタ構成 [#ka053590]
|Full Name|Short Name|Comment|h
|Stack Register Pointer|SRP|スタックレジスタポインタ。&br...
|Stack Pointer|SP|スタックポインタ。現在のスタック位置。|
|Program Counter|PC|プログラムカウンタ。現在実行している...
|Program Function|PF|プログラムの関数オブジェクトのポイン...
|Program Line|PL|プログラムのソースコードの行数。デバッグ...
|Link Register|LR|リンクレジスタ。戻り先のバイトコードの...
|Function Register|FR|関数レジスタ。全部で16個。FR00 - FR...
** レジスタの概要 [#b2e56c51]
- 1つのレジスタのサイズは8バイト。
- 4バイトでもいいかなと思ったが,64bit環境でポインタが1...
- ただし,メモリがきつきつの環境もあるので32bitモード用意...
- 1つのレジスタはUNIONで表現。
#code(c,){{
struct Register
{
union
{
u32 data32;
u64 data64;
s32 i32val;
s64 i64val;
f32 f32val;
f64 f64val;
void* ptr; // 64bit環境だとこれは8バイト。
};
};
}}
** スタックレジスタ [#bb1584f7]
- 計算の一時領域として使うレジスタはStackRegister(スタッ...
- スタックレジスタ数は動的に変更し,最大で256。それを越え...
- SRP(Stack Register Pointer)からのオフセットがスタック...
- SR01ならSRP + 0x08のアドレスとなる。(32bitモードなら+0x...
- 通常,関数の先頭でFUNCET命令を使い関数で使用するスタッ...
** 変数とレジスタ [#w8f36726]
- ローカル変数は全てスタックレジスタに割り当てられる。
- スコープを考慮してスタックレジスタの使用数はなるべく少...
- 一時変数もスタックレジスタに割り当てられる。
#code(c,){{
utility Hoge {
static void func()
{
int a; // SR01
int b; // SR02
{
int c; // SR03
}
int d; // SR02
{
int e; // SR03
}
d = (a + b) * d;
// (a + b)が一時変数としてSR03に格納される
// SR03 = a + b;
// SR02 = R03 * R02;
}
};
}}
** 戻り値とレジスタ [#lb8a56e2]
- 戻り値はFR00に格納される。
- FUNCRT命令が実行されるとSR00の値はFR00にコピーされる。
#code(c,){{
utility Hoge
{
static int GetOne()
{
return 1; // FR00 = 1
}
};
}}
** 引数とレジスタ [#g01df345]
- 引数は関数レジスタのFR01から順番にレジスタに割り当てら...
- 非staticなメンバ関数はFR01にthisポインタが割り当てられ...
- 関数レジスタは16個しか用意されていないので,引数の最大...
#code(c,){{
pod Vector3
{
float x;
float y;
float z;
void func(float addValue)
{
// FR01 : this
// FR02 : addValue
}
}
}}
** アセンブラのイメージ [#sc9a365f]
- 簡単なコード
#code(c,){{
0:int add(int a, int b)
1:{
2: return a + b;
3:}
4:void func()
5:{
6: int i = 3;
7: i = add(i , 4);
8:}
# 命令コード
Instruction:
add:
DFUNC 0x0000
DLINE 1 // '{'の位置
FUNCET 0x03 0x03
DLINE 2
ADDI32 R00 R01 R02
DLINE 3 // '}'の位置
FUNCLV 0x03
func:
DFUNC 0x0001
DLINE 5
FUNCET 0x02 0x00
DLINE 6
LDSRC4 SR00 0x0000
DLINE 7
LDSRC4 SR01 0x0004
LDFRSR FR01 SR00
LDFRSR FR02 SR01
CALL 0x0000
LDRF SR00 FR00
FUNCLV 0x02
# コンパイル時に確定する定数のテーブル
ConstantTable:
0x0000: 3
0x0004: 4
SymbolTable:
0x0000: int add(int,int)
0x0004: void func()
}}
** 命令コード [#ac30d5cb]
- どの命令コードも32bitで統一。
- SRegおよびFRegはu8。
|命令|書式|コメント|h
|>|>|BGCOLOR(ORANGE):''ロード''|
|LDSRC1|LDSRC4 SReg ConstantTableIndex(u16)|ConstantTable...
|LDSRC2|~|~|
|LDSRC4|~|~|
|LDSRC8|~|~|
|LDSRSR|LDSRSR SReg1 SReg2|SReg2の値をSReg1にロード|
|LDSRSP|LDSRSP SReg1 StackPointerOffset(u16)|StackPointer...
|LDSRP1|LDSRP1 SReg1 SReg2|SReg2の値をアドレスとみなし,S...
|LDSRP2|~|~|
|LDSRP4|~|~|
|LDSRP8|~|~|
|LDSROJ|LDSROJ SReg1 SReg2|SReg2の値をobject型とみなし,S...
|LDFRSR|LDFRSR FReg SReg|SRegの値をFRegにロード|
|>|>|BGCOLOR(ORANGE):''演算''|
|ADDxxx|ADDI32 SReg1 SReg2 SReg3|SReg1 = SReg2 + SReg3|
|SUBxxx|SUBI32 SReg1 SReg2 SReg3|SReg1 = SReg2 - SReg3|
|MULxxx|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 * SReg3|
|DIVxxx|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 / SReg3|
|MODxxx|MODS32 SReg1 SReg2 SReg3|SReg1 = SReg2 % SReg3|
|>|>|BGCOLOR(ORANGE):''関数あれこれ''|
|FENTER|FENTER AllocSRegNum CopyFRegNum|Function Enter. &...
|FLEAVE|FLEAVE FreeSRegNum|Function Leave. &br;FreeSRegNu...
|CALL|CALL SymbolTableIndex(u16)|LRにPCを代入する。 &br;S...
|CALLVF|CALLVF SReg1 ConstantTableIndex(u16)|Call Virtual...
|>|>|BGCOLOR(ORANGE):''スタック''|
|PUSH|PUSH SReg ConstantTableIndex(u16)|ConstantTableInde...
|POP|POP ConstantTableIndex(u16)|ConstantTableIndexが指す...
|>|>|BGCOLOR(ORANGE):''オブジェクト''|
|OBJNEW|OBJNEW SReg SymbolIndex|Object New.&br;指定のSymb...
|OBJDEL|OBJDEL SReg|Object Delete.&br;指定のSRegが指すオ...
|OBJRFI|OBJRFI SReg|Object Reference Increment.&br;指定の...
|OBJRFD|OBJRFD SReg|Object Reference Decrement.&br;指定の...
|>|>|BGCOLOR(ORANGE):''デバッグ''|
|DLINE|DLINE ConstantValue(u24)|Debug Line.&br;デバッグ情...
|DFUNC|DFUNC SymbolTableIndex(u16)|Debug Function.&br;デ...
* オブジェクトファイル [#sfc8fd99]
- Cでいう.oのファイル。
含まれるもの
- モジュール名
- 定数テーブル
- シンボルテーブル
- シンボル一覧
- シンボル解決情報
** モジュール名 [#j6a7768c]
- モジュール名が文字列として格納される。
** 定数テーブル [#wf3e79a4]
- 必要な定数テーブルの長さ。
- コンパイル時に解決されている定数郡。
- .oのファイルサイズ縮小のために,コンパイル時に解決され...
- そうしておくことで,リンク時に解決される定数郡のデータ...
** シンボルテーブル [#bfa16e2a]
- 必要なシンボルテーブルの長さのみ格納される。
** シンボル一覧 [#a5552a6f]
- モジュールはユーザー定義型リストを持つ。
:ユーザー定義型リスト|
- ユーザー定義型についての情報が0個以上格納されている。
- エンジンではユーザー定義型の情報が1つにつきSSObjectTyp...
|項目|内容|例|h
|シンボルのパス|文字列|BaseLib.Math.Vector3|
|継承しているクラスのパス|文字列|Foo|
|仮想関数テーブルリスト|別項:仮想関数テーブルリストを参...
|変数リスト|別項:変数リストを参照||
|関数リスト|別項:関数リストを参照||
:仮想関数テーブルリスト|
- 仮想関数テーブルについての情報が0個以上格納されている。
- エンジンでは仮想関数テーブルの情報が1つにつきSSVirutal...
|項目|内容|例|h
|シンボルのパス|文字列|BaseLib.IDrawable|
|仮想関数シンボルテーブル|SymbolTableIndexの配列||
:変数リスト|
- 変数についての情報が0個以上格納されている。
- エンジンでは変数の情報が1つにつきSSVariableが1つ生成...
|項目|内容|例|h
|型を示すシンボルのパス|文字列|float|
|シンボル名|文字列|x|
|staticフラグ|bool(staticか否か)||
|readonlyフラグ|bool(readonlyか否か)||
|constフラグ|bool(constか否か)||
:関数リスト|
- 関数についての情報が0個以上格納されている。
- エンジンでは関数の情報が1つにつきSSFunctionが1つ生成...
|項目|内容|例|h
|シンボル名|文字列|add|
|戻り値の型を示すシンボルのパス|文字列|BaseLib.Math.Vecto...
|戻り値のconstフラグ|bool(constか否か)||
|引数リスト|別項:引数リストを参照||
|staticフラグ|bool(staticか否か)||
|constフラグ|bool(constか否か)||
|命令コード|バイトコード||
:引数リスト|
- 引数についての情報が0個以上格納されている。
- エンジンでは引数の情報が1つにつきSSFunctionArgが1つ生...
|項目|内容|例|h
|型を示すシンボルのパス|文字列|float|
|constフラグ|bool(constか否か)||
|refフラグ|bool(refか否か)||
** シンボル解決情報 [#jec91c98]
- シンボルの種類は変数・関数・ユーザー定義型の3つ。
:変数|
|項目|内容|例|h
|代入先|定数テーブル or シンボルテーブル|-|
|シンボルパス|解決するシンボルのパス|BaseLib.Math.Vector3...
|シンボルの何を取得するのか。|・変数オブジェクト(SSVaria...
:関数|
|項目|内容|例|h
|代入先|シンボルテーブル|-|
|シンボルパス|解決するシンボルのパス|BaseLib.Math.Vector3...
|引数リスト|引数の型のリスト||
|属性|const,staticなどの属性||
|シンボルの何を取得するのか。|・関数オブジェクト(SSFuncti...
:ユーザー定義型|
|項目|内容|例|h
|代入先|定数テーブル|-|
|シンボルパス|解決するシンボルのパス|BaseLib.Math.Vector3|
|シンボルの何を取得するのか。|・ユーザー定義型オブジェク...
* 意味解析 [#xe319000]
構文解析が終わった後,コード生成より前にやること。
- ModuleをModuleReposに登録。
- TypePathを解決し,型にリンクさせる
- 関数名・変数名がだぶっていないかチェック。
- 定数(enum,immutable)の確定
- ユーザー定義型のサイズの決定
- ユーザー定義型の静的・非静的メンバ変数の位置を決定
- 自動生成関数の生成
- 関数のレジスタ割り当ての決定
- 関数の定数テーブルを作成
- 関数の非値型のスタックマッピングおよびスタックサイズを...
* 道のり [#s3b4b6c0]
- 意味解析
-- まずutilityと関数だけにしぼる
-- 全てのModuleをシンボルツリーに登録
-- 全ての型をシンボルツリーに登録
-- 関数をシンボルツリーに登録。
-- 関数の中身を意味解析
--- 関数の中身のTypePathやIdentPathのシンボルを解決
--- 意味解析したStatementに置き換え。
* 仕様変更履歴 [#a0f3a6ff]
:2010/07/29|
- prototype moduleの概念を追加。
- classの代入演算子オーバーロードを禁止に。D言語準拠にし...
- オブジェクトハンドルの概念をなくした。
- isと!isを追加。セットでIdentityExpressionも追加。
ページ名: