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以外の関数を呼べるようにするとかだろうか。でも、それは、また、インターフェースどうするかがわかんないんだよな…実装は簡単なんだけど。
で、えーと、面倒になってきたので、最適化の話は明日にでも。