CT Brainf*ck
ふと思い立ったので書いてみた.D言語のCTFEは優秀なのですっきり書けたのは書けたけど,何かちょっと嵌まった.以下嵌まった所.
- 配列のlength
arr ~= 0; // OK arr.length = 10; // Error : cannot be evaluated at compile time
時間があったらrt以下を読んでみる
- mixin後の関数呼び出し
mixin("int func() { return 0; }"); func(); // Error : no identifer func pragma(msg, func()); // OK
これ何でなんだろ?
- 連想配列のin
enum map = ['a':""]; if ('a' in map) // Error : Cannot interpret 'a' in (['a':""]) at compile time
mapは置換されてるはずなんだけど,どうしてだろうか.このせいでswitchを使うはめに…
上の点ふまえてソースは以下.さすがにコンパイルタイムにIO処理は出来ないので,入力スルーで出力は戻り値のバッファに貯めている.
/** * Translates Brainf*ck to D. */ pure nothrow string translate(in string src) { string code = q"EOS string run() { string result; ubyte[] tape = [0]; size_t i; EOS"; foreach (c; src) { switch (c) { case '+': code ~= "tape[i]++;"; break; case '-': code ~= "tape[i]--;"; break; case '.': code ~= "result ~= tape[i];"; break; case '<': code ~= "i--;"; break; case '>': code ~= "i++; if (tape.length <= i) tape ~= 0;"; break; case '[': code ~= "while (tape[i]) {"; break; case ']': code ~= "}"; break; default: } } return code ~ "return result; }"; } // test mixin(translate(import("hello.bf"))); pragma(msg, run());