J3C は 3Dアニメーションキット J3W 用のコンパイラです. J3C は JAVA風の文法を持つオブジェクト指向言語 として設計されています. ただし,JAVAのような汎用言語と異なりJ3Wの3Dアニメーション機能を使用 するための専用言語です.
J3Cではクラスの意味が C++ や JAVA と異なり,クラスは他のクラスから 参照することはできません.J3Cではクラスの独立性が非常に高く基本的に クラスのデータメンバ,メソッドをすべてはすべてプライベート(正確には C++のprotected.つまり継承したサブクラスからは参照可能)となっています.
したがって継承している場合を除いて他のクラスのデータメンバ,メソッド を参照することはできません.四則演算,制御構造は C, JAVA等の言語と同 じような機能を持ちますが,データ型は32ビットの整数型のみとなっています.
文法は,JAVA, C++のような C系の文法を使用しています.以下の解説は C等の言語の知識がある方を想定しています.特に文の動作は C等の言語と 基本的に同等です.
mainクラス,INIT, RUN, EVENTメソッドはここで示す言語仕様の外側の仕様となります. J3Cプログラミング入門 を参照して下さい.
変数名,定数名,メソッド名,クラス名などの識別子は先頭の文字が英字またはアンダスコア で始まる英数字またはアンダスコアで構成される文字列で長さは最大63文字までです. 英字の大文字と小文字は区別されます.
My_Class _A12345 i a12_345
は正しい識別子名の例です.
以下のJAVAの予約語とasm, libraryはユーザ定義の識別子名としては使用できません.
boolean | byte | char | double |
float | int | long | short |
break | case | continue | default |
do | else | for | if |
return | switch | while | class |
extends | implements | import | interface |
package | void | throws | catch |
finally | throw | try | super |
this | abstract | final | native |
public | private | protected | static |
synchronized | transient | volatile | |
asm | library |
また,組み込み関数名とj3dasmのニーモニックはユーザ定義の識別子名としては使用できません.
Pause | Throw | INC | DEC | ADD |
SUB | MUL | DIV | SHL | SHR |
AND | OR | not | CMP | NEG |
sqrt | sin | cos | atan | Random |
BRA | BEQ | BNE | BGR | BGE |
BLS | BLE | BMI | BPL | LOOP |
CALL | RETURN | PUSH | POP | ClearRegisters |
PushRegisters | PopRegisters | CLEARG | PUSHG | POPG |
ENTER | LEAVE | CALLTB | LOAD | LOADM |
XLOAD | GetCommon | LOADBP | STORE | XSTORE |
SetCommon | STORBP | new | delete | Wait |
Stop | Send | Receive | SendTo | child |
GraphMode | TextMode | BackgroundColor | Zoom | Wire |
Emit | Parallel | InKey | RawKey | Mouse |
Number | Char | Stringm | String | Note |
Midi | Forward | Back | Left | Right |
Up | Down | RotHead | RotPitch | RotBank |
Move0 | Move | Scale | SetGravity | GetGravity |
SetAcceleration | GetAcceleration | SetVelocity | GetVelocity | SetWVelocity |
GetWVelocity | NewObject | DefPoint | DefPlane | DeleteObject |
See | Point | Specular | Ambient | EYEORG |
CountVertex | Plane | Transpose | VertexRelative | VertexAbsolute |
SetOffset | ClearOffset | GetPosition | SetPosition | Where |
Distance | Priority | Relative0 | Look | Relative |
FindVertex | SetVertex | GetVertex | SetPlane | GetPlane |
SetScale | GetScale | gNumber | gChar | gStringm |
gString | gColor | gClear | gCursor | gPosition |
gLine | gLineClear | SystemTime | SystemCount | SystemProcess |
CommonData | Write | Read | Light | READPL |
NumColors | NumShading | VertexCount | PolygonCount | SetColor |
ResetColor | Version |
J3CはJ3W仮想マシン専用に設計された言語です.専用言語といっても文法は, C, C++, JAVA に非常に近いものとなっています.したがって C, C++, JAVA を用いてプログラミングできる方は,J3Cのソースを理解することは容易であると思 います.
J3Cのプログラムはクラスの定義,ライブラリの定義,外部ファイルの挿入 (import宣言)の繰り返しから構成されます.
クラスは C++, JAVA とは異なってインスタンス化された時点から自律的に 実行が開始されます. クラスのインスタンスであるオブジェクトが実際に 存在する「物体」として動作します.
ライブラリはクラスとは異なり,インスタンス化されることはなく,C に おける外部ライブラリのようにどのクラスからも共通に使用できる手順や定数宣言 を記述します.
j3c は(ver.1.05 現在)1パスのコンパイラであるためクラス, ライブラリ共に参照時には宣言済みの必要があります.クラス間の相互参照が必要な場合 (あるクラスで別クラスのインスタンスを生成する時に発生する)は,共通の親クラスを定義 するなどの工夫が必要となります.
importは別に保存されているソースファイルをその位置に挿入します. インクルードされたファイルはそこでコンパイルされます.同一ファイルが複数回 インクルードされた場合には,最初に一度だけコンパイルされ,2度目からは無視されます.
同一ファイルかどうかの判定はファイル名のみで行っているため,別ディレ クトリに同名のファイルが存在し,両方のファイルをインポートしようとし ても同一ファイルと判定されます.
ライブラリはクラスと異なりインスタンス化することはありません. スコープはグローバルで複数のクラスからライブラリに属するメソッドと定数を参照 することができます. クラスのようにデータメンバ(クラス変数)を持つことはできませんが,定数を 宣言することはできます.
クラスはインスタンス化されるとスレッドとして独立して動作します. クラスは独立しているため,すべてのデータメンバとメソッドのスコープは プライベートであり,他のクラスから参照することはできません.
extends節で宣言済みのクラスを指定した場合,extends節で指定したクラスから データメンバとメソッドを継承します.
j3c のプログラムには少なくとも1つ mainという名のクラスが必要です. J3Cプログラミング入門 を参照して下さい.
クラスにはメソッド関数の宣言と変数または定数の宣言を置きます.
クラス内で使用する関数を定義します.型名は int のみです. メソッドは使用前に定義されている必要があります.
すべてのクラスには INIT, RUN, EVENTメソッドが必須(継承も可)です. J3Cプログラミング入門 を参照して下さい.
クラスに属する変数,または定数を宣言します.
変数の初期化は final宣言されたもの(定数)のみが可能です. 変数の配列は1次元配列のみ宣言できます.JAVAと異なり,配列の大きさを 指定する必要があります.final宣言された定数は定数式中に使用することができます.
final int AnyConstan = 5; final int AnyConstantArray[5] = {100, 200, 500, 600, 0};
の形式で使用します.初期化された配列の参照時の インデックスに変数は使用できません.
変数の型は int型(32ビット整数)のみです. 値を変更する通常の変数には volatile を前に置きます.変数は初期化することができません.
変数は配列とすることもできます.定数式の部分には配列列の要素数を指定します. 配列の添字は必ず 0 から始まります.したがって
volatile int array[10];
という宣言では array[0]からarray[9]までの10個の要素となります. 変数宣言では変数の値の初期化はできません.
{ と } で囲まれた部分はブロックと呼ばれ,ブロック内で有効な変数,定数を宣言できます. 変数,定数の宣言は文より前に置く必要があります.
ブロックの最後まで有効な局所変数を宣言できます.型はintのみです. ブロック内で文リストの前に宣言します.局所変数も定数のみが初期化できます.
文と文の間はセミコロンで区切ります.セミコロンは空文(何もしない文) または,文と文の区切りとして作用します.したがって,ブロックの最後 の文にはセミコロンを付ける必要はありません(もしセミコロンを付けても空文と解釈 されるため問題ありません).
文としては以上の14種類が使用可能です.Cなどの言語にほぼ(IF以外)共通する 文法となっています.
空文は文が必要な位置にセミコロンを置くと何もしない文とすることができます.
代入は局所変数,データメンバ,レジスタ変数に右辺の式の値を代入します. 左辺は局所変数,データメンバ,およびそれらの配列,またはレジスタ変数 を使用します. 代入文は値を返さないため,C, C++ のように連続した代入 ( A = B = C = 0; )はできません.
例えば
AnyVariable = 100 * 200 / 5; AnyArray[2] = sqrt(AnyVariable); RX = AnyArray[2] * 12;
という形式で使用します.
メソッドを文として呼び出した場合の返り値は無視されますが,代入文の右辺や 式中で使用された場合はメソッド中で最後に評価された式の値が返ります.
組込関数呼び出しは,仮想マシンJ3Wの機能を使用するためにJ3C内に組み込まれ ている関数です.引数は通常のメソッドやライブラリの呼び出しとは異なり, 組み込み関数毎に形式が異なります.詳細は J3Cの組み込み関数 を参照して下さい.
この組込関数が j3c を汎用言語ではなく,3次元アプリケーション作成言語と特徴 付ける部分です.3次元アニメーションを目的とする場合には必ず使用することになります.
library宣言されているライブラリが持つメソッドを呼び出します. ライブラリ呼出はライブラリが宣言済みである限り,どのクラスまたは ライブラリから参照することが可能(グローバルスコープを持つ)です.
実引数リストはメソッド呼び出し,ライブラリ呼び出しの時の引数です. 引数の数は0以上任意の個数が可能です.
AnyLibrary.method(); val = AnyLibrary.AnyConstant;
のような形式で使用します.
ASM文で指定された文字列は,そのままj3cの出力としてアセンブラソースに埋め込まれます. j3dasm の入力として有効な文字列を指定する必要があります.
例えば
asm("; これはコメントの例"); asm(" ADD RX RY ; 命令とコメントも可能");
という形式で使用します.j3cでサポートしていないJ3Wの命令を直接記述したり,j3c の 生成するアセンブラソースにコメントを埋め込む場合に使用します.
switch文は,C, C++, JAVA と同じく式の値で分岐する場合に使用します. break文を使用しない場合,分岐したラベル以後を上から下へ順に実行 します.break文が存在するとswitch文の実行は終了します. caseラベルに一致する値がなく,default: が存在する場合は その部分が実行されます.
switch (i) { case 1 : case 2 : a = a + 1; break; case 3 : a = a + 2; break; default : a = a + 3; }
この例では,変数 i の値が1と2の場合は変数 a に1を加え,3の場合は変数 a に2を加え,変数 i の値がそれ以外の場合は変数 a に3を加えます. C と同様に break文に注意してください.
while文は,C, C++, JAVA と同じく繰り返し処理に使用します. 式の値が真(非0)の間繰り返し,文が実行されます.
i = 0; while(i < 100) { i = i + 1; Number(i); Char(13); }
この例では 1から99を表示します.
do文は,C, C++, JAVA と同じく繰り返し処理に使用します. 式の値が真(非0)の間繰り返し,文が実行されます. while文と異なり,文は少なくとも1度実行されます.
i = 0; do { i = 1 + 1; Number(i); Char(13); } while (i < 100);
この例では 1から99を表示します.
for文は C++ や JAVA よりも C に似ています.つまり
for(i=0; i<100; i=i+1) DoSomething();
は可能ですが,以下のように変数宣言とともに使用することはできません.
for(int i=0; i<100; i=i+1) DoSomething();
つまり,for文に使用する変数(制御変数)は事前に宣言しておく必要があります.
また,i++ ではなく,i=i+1 の形式に気付かれたと思いますが,J3Cでは現在, i++ の形式の演算子をサポートしていないためです.
if文だけが C, C++, JAVA の文法とわずかに異なり,else節の前にセミコロンを 置くことができません. この点は Pascalの if 文と似ています(then は使用しませんが).
if (a == 0) String(" This string will be displayed when a = 0") else String(" This string will be displayed when a != 0");
elseの前にセミコロンを置くとセミコロンの前でif文は終了することになって, elseでエラーとなります.
すべてのメソッドは,最後に評価した式の値が返ります.return文は 式を評価する目的で使用します.式の伴なわないreturn文は何もしません. 処理の流れを制御する目的では使用できません. 通常,メソッドの最後で返す値を明示するために使用します. メソッド定義の途中でreturn文を使用してもメソッドは終了しません.
// 正しくない(意図する処理ではない) int check(int foo) { volatile int i; if (foo == 0) return 1 else return 0; i = 5; }
上の例では return文でメソッドから抜けて呼び出し元に戻ることはありません. したがって i = 5 が実行され,最後に評価された式の値5が関数の値となります.
// 正しい int check(int foo) { volatile int i, result; if (foo == 0) result = 1 else result = 0; i = 5; return result; }
最後に評価された式はresultの値となってcheck関数の値となります.
break文は,最も内側のループ(for, do, while, switch)から抜けます. break文は,通常switch文中で case とともに使用して重要な働きをします. Pascal派の方は注意してください.
continue文は,ループ(for, do, while)内で continue 文の後の処理を飛ばして 次のループの先頭から開始します.
式は C, C++, JAVA に比べると演算子の種類が少ないですが,実用上は充分な 種類を持っています.演算子の優先順位は Pascal とほぼ同じと考えても良い でしょう. つまり,演算子の優先順位は以下の順序で低くなります. 通常の四則演算(加減乗除)と同じく乗除は加減算より先に評価されます.
単純式Aと単純式Bの以下に示す大小関係によって返る値が変化します.
通常の四則演算の加減算を行ないます. 演算子 | はビットORです.
通常の四則演算の乗除算を行ないます. 演算子 & はビットANDです.
数値は10進数,16進数,キャラクタで記述できます.
val = 123456789; val = 0xABCDEF0; val = 'A';
定数の値を参照します.配列の要素を指定することもできますが,配列の添え字は 定数式の必要があります.配列定数の添え字に変数を使用することはできません.
RX,RY,RZ,RH,RP,RBレジスタ変数は,組み込み関数のうち30種類程度の関数の 呼び出し時の設定,または,返り値の取得に用いられます. また,クラスインスタンス生成時のRX,RY,RZ,RH,RP,RBレジスタ変数の値は 生成されたインスタンスに引き継がれます.「コンストラクタの引数」的な 働きを持ちます.
RQレジスタはクラスインスタンスの識別(プロセスIDと呼ぶ)に使用します. RQはインスタンス生成時に0が設定されるため,例えば,RXにプロセス番号を 代入した後にインスタンスを生成し,生成されたクラス内で RQ = RXとすると インスタンスのプロセス番号を指定することが可能です.
RLレジスタは受信されたメッセージを保持しています.RLレジスタに書き込 むことは可能ですが,クラスのEVENTメソッド内でメッセージの参照に使用す るだけにするべきです.
レジスタ変数はユーザ定義の library で1つ以上の値を返したい場合等に利用できます.
また,new組込み関数で生成されるインスタンスは, newを実行する時の
レジスタ変数を受け継ぎます.インスタンスに対する引数として RQ - RB の
最大8個の32ビット整数を渡すことができます.
定数式はコンパイル時に値が決定できる必要があります.したがって 実行時に値が変化する可能性のあるメソッドや変数を使用することは できません. 変数のうち final宣言された変数は実行時に値が変化し ないため使用できます. クラス名は,new組み込み関数とchild組み込み関数において宣言済みの クラス名を置くことができます.