表紙 短縮
brainfuck2d
brainfuck(入出力ストリームが必要)のコードを、Dの
delegate void(std.stream.InputStream, std.stream.OutputStream)
なデリゲートに変換します。
brainfuckコードをDソースコード表現を経由してネイティブコードにコンパイルさせるようにしています
いまのところDMD2.011上でのHello World以外は検証してないです。
・ストリームからの入力の検証をやってないのでそこが特に怪しいです
・バッファの境界操作をしてないです。"<."とか">"を10000回書いて"."すると死にます
・><+-の連続を最適化するとかやってないです
改良とかあればお願いします。とりあえずNYSLで。
brainfuck2d.d
module brainfuck2d;
public import std.cstream;
invariant wstring default_operator_char = "><+-.,[]"w;
string representBrainfuckVMinD(in wstring bf, invariant wstring operator_char = default_operator_char) {
// generate brainfuck VM code in D
string d_code = "
delegate void(std.stream.InputStream ins = std.cstream.din, std.stream.OutputStream outs = std.cstream.dout) {
ubyte[] array;
array.length = 10000;
ubyte* p = array.ptr;
";
// translate brainfuck code to D
int index = 0;
wchar c;
while(index < bf.length) {
c = bf[index];
if(c==operator_char[0]) {
d_code ~= "++p;";
} else if(c==operator_char[1]) {
d_code ~= "--p;";
} else if(c==operator_char[2]) {
d_code ~= "++(*p);";
} else if(c==operator_char[3]) {
d_code ~= "--(*p);";
} else if(c==operator_char[4]) {
d_code ~= "outs.write(*p);";
} else if(c==operator_char[5]) {
d_code ~= "*p = cast(ubyte) ins.getc();";
} else if(c==operator_char[6]) {
d_code ~= "while(*p) {";
} else if(c==operator_char[7]) {
d_code ~= "}";
} else {
};
index++;
}
d_code ~= "}";
return d_code;
}
main.d
import brainfuck2d;
void main(char[][] args) {
auto helloworld = mixin(representBrainfuckVMinD("
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++
++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>
++++++++[<++++>-]<+.[-]++++++++++.
"w));
helloworld(din, dout);
invariant wstring vip = "おぇwWksぅー"w;
auto こんちわwwww = mixin(representBrainfuckVMinD("
おwwwwwwwwwぅぇwwwwwwwwおWーぇkおwwwwwwwぅぇwwwwおWーぇwkwwwwwwwkkwwwkぅWーおwwwwwwwwぅぇww
wwおWーぇkおwwwwwwwwwwwぅぇwwwwwおWーぇkおwwwwwwwwぅぇwwwおWーぇkwwwkWWWWWWkWWWWWWWWkぅWーお
wwwwwwwwぅぇwwwwおWーぇwkぅWーwwwwwwwwwwk
"w, vip));
こんちわwwww();
}