ワンライナーでBrainfuck処理系を書きました。
発端は自分が開発しているBrainfuck
処理系(GitHub - alphaKAI/brainfuck)を高速化している時に、ふとこれ、ワンライナー化出来るのでは...?と考え、書いてみたら出来ました。
例によってZ Combinator
による無名再帰を多用しています
一部型を省略可能な場所がありますが可読性のために残してあります。
(注意: 複雑なコードだと単純な再帰になっているためスタックオーバーフローを起こしてしまい、実行できません....)
完全なワンライナーにしました!!
では、以下に完成したコードを貼ります
import std.algorithm,
std.array,
std.stdio,
std.string,
std.conv;
import core.memory;
R delegate(Args) Z(R, Args...)(R delegate(R delegate(Args), Args) f){
return (Args args) => f(Z(f), args);
}
void main() {
((string input) =>
(operators =>
((char* code) =>
((ubyte* memory) =>
((ulong memoryIndex) =>
(removeTrash =>
(process =>
process(input)
)((string input) =>
((string[] _code) =>
(
(
GC.realloc(code, _code.length * char.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE),
GC.realloc(memory, _code.length * ubyte.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE)
),
Z((int delegate(int) copy, int i) => i < _code.length ? (code[i] = _code[i].to!char, copy(i + 1)) : 0)(0),
((int pc) =>
(optimizer =>
((int delegate() destructor) =>
((int[int] brackets) =>
(process =>
(
process(int.init),
destructor()
)
)(Z((int delegate(int) process, int index) =>
index < _code.length
? ((char current) =>
(
(current == '>'
? memoryIndex++
: current == '<'
? memoryIndex--
: current == '+'
? memory[memoryIndex]++
: current == '-'
? memory[memoryIndex]--
: current == '.'
? (
write(memory[memoryIndex].to!char),
stdout.flush()
)
: current == ','
? ((string buf) =>
(
Z((int delegate() getLine) => ((buf = readln()) == null || !buf.length) ? getLine() : 0)(),
memory[memoryIndex] = cast(ubyte)buf[0]
)
)(string.init)
: current == '['
? (memory[memoryIndex] == 0 ? (index = brackets[index], 0) : 0)
: current == ']'
? (memory[memoryIndex] != 0 ? (index = brackets[index], 0) : 0)
: 0
),
process(index + 1)
)
)(code[index])
: 0
))
)(optimizer(int.init, (int[]).init, (int[int]).init))
)(() => (GC.free(code), GC.free(memory), memoryIndex = 0, 0))
)(Z((int[int] delegate(size_t, int[], int[int]) optimizer, size_t i, int[] leftstack, int[int] brackets) =>
i < _code.length ?
((char c) =>
!canFind(operators, _code[i])
? optimizer(i + 1, leftstack, brackets)
: (
c == '['
? (optimizer(i + 1, leftstack ~ pc++, brackets))
: (c == ']' && leftstack.length != 0)
? (left =>
(leftstack.popBack(),
(right =>
(
(brackets[left] = right, brackets[right] = left),
pc++,
optimizer(i + 1, leftstack, brackets)
)
)(pc))
)(leftstack[$ - 1])
: (pc++, optimizer(i + 1, leftstack, brackets))
)
)(code[i]) : brackets
)
)
)(int.init)
)
)(removeTrash(input))
)
)((string key) => key.split("").filter!(x => operators.canFind(x)).array)
)(ulong.init)
)(cast(ubyte*)GC.malloc(300000 * ubyte.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE))
)(cast(char*) GC.malloc(300000 * char.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE))
)([">", "<", "+", "-", ".", ",", "[", "]"])
)(">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.");
// => Hello World!
}