■
0.8
久しぶりに家でコード書いたよ。
今回大きいのはビルトイン関数追加機能。
これは直接VM命令に変換される関数を定義できる機能。
利点は、
- いちいちextern書かなくていい
- いちいちnative定義しなくていい
- ほんのちょっと速い
のみっつ。
まず、common/builtins.defの中身を、
def sin(float) -> float { /* この中がVMの一部になる */ float v; /* 関数が呼ばれたときは、その引数がスタックに積んである */ /* TOPF → スタックの一番上のfloat値を拾ってくる */ v = sinf( TOPF ); /* 戻り値はスタックの一番上に置いとく */ TOPF = v; /* PC++ と NEXT のふたつは必要なのでとりあえず入れておく */ PC++; NEXT; } def putf(float) -> void { /* POPF はポップして一番上の値を拾ってくる */ printf("%f\n",POPF()); PC++; NEXT; }
こんな感じにして、gen_opcodeを実行する。すると、どっかで、SIN命令とPUTF命令が定義されて、
def start() -> void: putf(sin(3.14159))
こういう感じのa24zをコンパイルすると、
start func(index:0) 0: LOAD_CONST 3.141590, 2: SIN 3: PUTF 4: RETVOID 0(byte),
こういうバイトコード列になる。っていうの。
スタックマシンVMの挙動が理解できるなら便利だと思うんだけど、ちょっとわかりにくいかも。