四則演算、スタックマシンのベンチマーク

                 O    i  Oi  r   rO  ri  riO
元         : 570 460 381 361 360 350 311 310
読込       : 571 531 370 360 361 371 320 340
最適化     : 371 310 380 321 290 260 291 260
関数化     : 461 381 370 320 311 300 290 261
動的       : 120 err 110 err 350 err 350 err
動的ASM    :  30 err  20 err  30 err  30 err
動的読込   : 110 err 120 err 360 err  60 err
トランス   : 101  80  90  70  70  60  70  60
トランスASM:  30  20  41  30  30  30  30  30

とってみました。
トランスレータ速いですねぇ。
さらに、CPUのスタックを使ってやると速いってことがわかりました。
動的というか、実行時コンパイルは、最適化かけるとエラーでます。


で、なんだっけ、、、
ActionScript3.0にコンパイルするには、トランスレータ書けば十分じゃないのかという
ざっとした、結論が得られました。


てことは、6502のアセンブラ作るって話になるのか。。。
というか、NESの開発環境を作ることになるのか。
できるのかよ!

;
; スタックマシン用プログラム
;

PUSHI	1
PUSHI	2
ADD
PUSHI	10
MUL
PUSHI	1
SUB
PRINTI
RET

これを読み込んで、Dのソースを出力する。トランスレータ

import std.string;
import std.file;
int main(char argv) {
	// ファイル読み込み
	char str = cast(char)read(argv[1]);
	// トランスレート
	printf("enum { MAX_STACK = 200 };\n");
	printf("int stack[MAX_STACK];\n");
	printf("int sp = MAX_STACK - 1;\n");
	printf("int main() {\n");
	foreach (char line; str.split("\n")) {
		char[] c = line.split();
		if (c.length == 0) continue;
		switch (c[0]) {
		case "POP": printf("\t++sp;\n"); break;
		case "PUSHI": printf("\tstack[sp--] = %.*s;\n", c[1]); break;
		case "ADD": printf("\tstack[sp+2] = stack[sp+2] + stack[sp+1]; ++sp;\n"); break;
		case "SUB": printf("\tstack[sp+2] = stack[sp+2] - stack[sp+1]; ++sp;\n"); break;
		case "MUL": printf("\tstack[sp+2] = stack[sp+2] * stack[sp+1]; ++sp;\n"); break;
		case "PRINTI": printf("\tstack[sp+1] = printf(\"%%d\\n\", stack[sp+1]);\n"); break;
		case "RET": break;
		default: break;
		}
	}
	printf("\treturn 0;\n");
	printf("}\n");
	return 0;
}

で、出力結果。

enum { MAX_STACK = 200 };
int stack[MAX_STACK];
int sp = MAX_STACK - 1;
int main() {
	stack[sp--] = 1;
	stack[sp--] = 2;
	stack[sp+2] = stack[sp+2] + stack[sp+1]; ++sp;
	stack[sp--] = 10;
	stack[sp+2] = stack[sp+2] * stack[sp+1]; ++sp;
	stack[sp--] = 1;
	stack[sp+2] = stack[sp+2] - stack[sp+1]; ++sp;
	stack[sp+1] = printf("%d\n", stack[sp+1]);
	return 0;
}

分岐とか考えると、もうちょっと複雑になりますが、まぁ、こんくらいで。