0.3
0.3
配列実装、関数呼び出しまわりが腐ってたのを修正、あと、なんか色々。投げやりなREADMEとか。
全然テストしてません。自己責任で。
昨日言ってた配列を実装。
field nanika_array: int [] def start() -> void : nanika_array[0] = 4 nanika_array[1] = 255 yield nanika_array[1] = 8 yield nanika_array[0] = 9 yield
こんなふうにしといて、
#include "loader.h" #include "vm.h" #include <stdio.h> static a24z_value a24z_field[8]; enum { FIELD_NANIKA_ARRAY, }; int main( ) { struct a24z_program *prog; struct a24z_vm *vm; struct a24z_native_funcs natives; a24z_value buf[4]; natives.func_table = NULL; natives.method_table = NULL; prog = a24z_load_file( "test.a24zc", &natives, NULL ); if ( prog == NULL ) return 1; /* ここで nanika_array の配列を指定 */ POINTER_VALUE(a24z_field[FIELD_NANIKA_ARRAY]) = buf; vm = new_a24z_vm( prog, a24z_field ); a24z_vm_run( vm ); printf("nanika_array[0]=%d, nanika_array[1]=%d\n", INT_VALUE(buf[0]), INT_VALUE(buf[1])); a24z_vm_run( vm ); printf("nanika_array[0]=%d, nanika_array[1]=%d\n", INT_VALUE(buf[0]), INT_VALUE(buf[1])); a24z_vm_run( vm ); printf("nanika_array[0]=%d, nanika_array[1]=%d\n", INT_VALUE(buf[0]), INT_VALUE(buf[1])); a24z_unload_program( prog ); return 0; }
こーすれば、
nanika_array[0]=4, nanika_array[1]=255 nanika_array[0]=4, nanika_array[1]=8 nanika_array[0]=9, nanika_array[1]=8
こんな感じに。実行時に配列を作る方法は無いけど、mallocとかを呼べるようにしてやれば一応可能。
Cの関数を呼ぶ方法は、func_tableに関数を入れておいて、プログラムのほうでexternしておけば使える。
field nanika_array: int[] extern new_array( size:int ) -> int [] extern delete_array( ptr: int [] ) -> void def start() -> void : nanika_array = new_array( 8 ) nanika_array[0] = 4 nanika_array[1] = 255 yield delete_array( nanika_array )
こんなふうにしておいて、
#include "loader.h" #include "vm.h" #include <stdio.h> #include <stdlib.h> enum { FIELD_NANIKA_ARRAY, }; static a24z_value new_array( a24z_value *sp ) { int size = INT_VALUE(sp[0]); a24z_value v; POINTER_VALUE(v) = malloc( size * sizeof(a24z_value) ); puts("new"); return v; } static a24z_value delete_array( a24z_value *sp ) { a24z_value *ptr = POINTER_VALUE( sp[0] ); a24z_value v; free( ptr ); puts("delete"); return v; } static a24z_native_func func_table[] = { new_array, delete_array, }; int main( ) { struct a24z_program *prog; struct a24z_vm *vm; struct a24z_native_funcs natives; a24z_value field[8]; /* ここで呼び出す関数を指定 */ natives.func_table = func_table; natives.method_table = NULL; prog = a24z_load_file( "test.a24zc", &natives, field ); if ( prog == NULL ) return 1; vm = new_a24z_vm( prog, field ); a24z_vm_run( vm ); printf("nanika_array[0]=%d, nanika_array[1]=%d\n", INT_VALUE( POINTER_VALUE(field[FIELD_NANIKA_ARRAY])[0] ), INT_VALUE( POINTER_VALUE(field[FIELD_NANIKA_ARRAY])[1] ) ); a24z_vm_run( vm ); a24z_unload_program( prog ); return 0; }
こんな感じ。関数もfieldと一緒で、上から順番にインデックスが付けられていく。
これで、とりあえず欲しいと思ってた機能はひととおり揃ったはず。
あとは、start以外の関数を呼べるようにするとかだろうか。でも、それは、また、インターフェースどうするかがわかんないんだよな…実装は簡単なんだけど。
で、えーと、面倒になってきたので、最適化の話は明日にでも。