delegateを使って、継続っていうか、インタプリタって言うかそんなのをやる。

もともと、ActionScriptで書くこと考えてたんですけど、Dでも出来るなってことで、、、。

_frame( delegate void(A a) {
	printf("test1\n");
});

_frame( delegate void(A a) {
	printf("test2\n");
});

_frame( delegate void(A a) {
	printf("test3\n");
});

こんなんかいておいて、

while(a.move() | c.move()){printf("---\n");}

こんなんで、

test1
    • -
test2
    • -
test3

と出来ます。ループとgotoも作ってみました。

全ソース

import std.boxer;

class A {
	int[char] labels;
	void delegate (A a) funcs;

	int pos;
	int nextPos;
	
	bool delegate (A a)[int] iffuncs;
	
	this() {
		pos = 0;
		nextPos = -1;
	}

	void init() {}

	void _goto(char name) {
		nextPos = labels[name];
	}

	void _frame(void delegate (A a) f) {
		funcs ~= f;
	}

	void _label(char name) {
		labels[name] = funcs.length;
	}

	void _loop(bool delegate (A a) f) {
		iffuncs[funcs.length] = f;
		funcs ~= delegate void(A a) {
			if (a.iffuncs[a.pos](a)) {
				a.nextPos = a.pos;
			}
		};
	}

	bool move() {
		if (pos >= funcs.length) return false;
		nextPos = -1;
		funcs[pos](this);
		if (nextPos != -1) pos = nextPos;
		else pos++;
		return true;
	}
}

class B : A {
	int a;
	void init() {
		a = 1;
		_frame( delegate void(A a) {
			printf("test1\n");
		});

		_frame( delegate void(A a) {
			printf("test2\n");
			a._goto("a");
		});

		_frame( delegate void(A a) {
			printf("test3\n");
		});

	_label("a");
		_frame( delegate void(A a) {
			printf("test4\n");
		});
		
		_frame( delegate void(A a) {
			B b = cast(B)a;
			if (b.a == 1) {
				printf("test5\n");
			} else {
				printf("test6\n");
			}
		});

		_loop(delegate bool(A a) {
			B b = cast(B)a;
			printf("loop%d\n", b.a);
			b.a++;
			return b.a < 3;
		});

	}

}



class C : A {
	int a;
	void init() {
		a = 1;
	_label("aa");
		_frame(&f1);
		_loop(&f2);
	}

	void f1(A a1) {
		printf("c %d\n", a);
	}

	bool f2(A a1) {
		printf("c %d\n", a++);
		return (a < 10);
	}
}

void main() {
	A a = new B();
	a.init();
	A c = new C();
	c.init();
	while(a.move() | c.move()){printf("---\n");}
}