a24z紹介

0.2 バグ潰しとか、追加とか色々。


a24z言語はLuaみたいな感じだけど、Luaよりもっと機能を限定したみたいな言語です。っていってもあんまりわからんな。ランタイムのサイズでいうと、5KBを切るぐらいの。
と、思ってたんだけど、Luaとはちょっと違うような。実はLuaってあんまり知らない。

  • 組み込み言語

組み込み言語と呼ばれながらも、なんか汎用言語みたいな微妙さがあるLuaとは違う。豊富なグローバル変数C++オブジェクトとの値のやりとりもそれなりに簡単に。

  • できるだけ効率にこだわる

勝手にメモリアロケートされるとかが嫌なので、スタック足りない時以外はメモリアロケートなんか起きない…多分。
変数参照はいつだってインデックスで。ハッシュテーブルはもちろん、リストやら、配列の線型探索すら必要無い。

ここらへん、機械語の1/10ぐらいの速度は出るのではないか、と思う。計測してないけど。予想としてはJITじゃないJavaぐらいの速度が。


そんな感じ。まあ、別にLuaでいいじゃん、と言えば、それまでなんだけど、あんな連想配列やら、ちゃんとしたクロージャなんかいらねーんだよ!!とか思わない?



簡単に説明。
compilerディレクトリでmakeする。すると、compilerの中にa24zcができる。これがコンパイラ

field x: int
field y: float

def start() -> void :
	y = 0.4
	x = 4
	yield
	x = 8
	y = y * 2.0
	yield
	x = 4
	y = y * 2.0
	yield

こーいうプログラムを書くとする、んで、test.a24zとでもして、コンパイル

$ a24zc test.a24z test.a24zc

これでコンパイル終わり。test.a24zcがバイトコードの入ったファイル。
んで、

#include "loader.h"
#include "vm.h"
#include <stdio.h>

static a24z_value a24z_field[8];

enum {
	FIELD_X,
	FIELD_Y,
};

int
main( )
{
	struct a24z_program *prog;
	struct a24z_vm *vm;
	struct a24z_native_funcs natives;

	natives.func_table = NULL;
	natives.method_table = NULL;
	prog = a24z_load_file( "test.a24zc", &natives, NULL );

	if ( prog == NULL )
		return 1;

	vm = new_a24z_vm( prog, a24z_field );
	a24z_vm_run( vm );
	printf("x=%d, y=%f\n", INT_VALUE(a24z_field[FIELD_X]), FLOAT_VALUE(a24z_field[FIELD_Y]));
	a24z_vm_run( vm );
	printf("x=%d, y=%f\n", INT_VALUE(a24z_field[FIELD_X]), FLOAT_VALUE(a24z_field[FIELD_Y]));
	a24z_vm_run( vm );
	printf("x=%d, y=%f\n", INT_VALUE(a24z_field[FIELD_X]), FLOAT_VALUE(a24z_field[FIELD_Y]));

	a24z_unload_program( prog );


	return 0;
}

こんなプログラムを書いて、liba24zvm.aとリンク。で、実行すると、

x=4, y=0.400000
x=8, y=0.800000
x=4, y=1.600000

こんな感じ。

field x: int
field y: float

まず、これが、field変数の宣言。上から順番にインデックスが付いていく。xが0番目、yが1番目。で、field変数はグローバル変数として使える。

def start() -> void :
	y = 0.4
	x = 4

見たまんま。y が 0.4 で x が 4。んで、yieldが中断。a24z_vm_runから帰ってくる。これの繰り返し。基本はこれだけ、というか、このくらいしか機能が無いんだが。


想定する使い方としては、オブジェクトごとにVM割り当てて、あとは適当にfield書き換える、みたいな感じで。よーするに、C++オブジェクトのメソッドの一部だけをスクリプトで書く、みたいなことがやりたかったんですよ。
あとは、読み、書きごとに関数を呼び出すattr変数とか、VMごとではなく、a24z_programごとに共有されるshare変数とか。これについてはまた機会があったら。
関数呼び出しはnatives.func_tableやらnatives.method_tableをぐにょぐにょすれば。