Execute Brain****/D: Difference between revisions
Content added Content deleted
m (moved RCBF/D to Execute Brain****/D) |
(Move 2 alternate implementations from Execute Brain****. http://rosettacode.org/mw/index.php?title=Execute_Brain****&action=history) |
||
Line 1: | Line 1: | ||
{{implementation|Brainf***}}{{collection|RCBF}} |
{{implementation|Brainf***}}{{collection|RCBF}} |
||
== Implementation 1 == |
|||
{{works with|D|2.007+}} |
{{works with|D|2.007+}} |
||
An implementation of Rosetta Code [[Brainfuck|BrainF*ck]] interpreter in [[D]]. |
An implementation of Rosetta Code [[Brainfuck|BrainF*ck]] interpreter in [[D]]. |
||
Line 70: | Line 72: | ||
} |
} |
||
</lang> |
</lang> |
||
== Implementation 2 == |
|||
Alternative version, simpler and faster: |
|||
<lang d>import core.stdc.stdio: getchar, putchar, EOF; |
|||
import core.stdc.stdlib: exit; |
|||
void brainfuckRun(const string code) { |
|||
static pure int[int] matchBraces(const string code) |
|||
out(result) { |
|||
foreach (k, v; result) { |
|||
assert(k >=0 && k < code.length); |
|||
assert(v >=0 && v < code.length); |
|||
assert(v in result); |
|||
} |
|||
} body { |
|||
int[int] loops; |
|||
int[] loopStack; |
|||
foreach (i, instruction; code) { |
|||
if (instruction == '[') |
|||
loopStack ~= i; |
|||
else if (instruction == ']') { |
|||
assert(loopStack.length); |
|||
loops[i] = loopStack[$ - 1]; |
|||
loopStack.length -= 1; |
|||
loops[loops[i]] = i; |
|||
} |
|||
} |
|||
assert(!loopStack.length); |
|||
return loops; |
|||
} |
|||
static void runCode(const string code, const int[int] loops) { |
|||
enum char empty = '\0'; |
|||
char[30_000] tape = empty; |
|||
int cell, index; |
|||
while (index < cast(int)code.length) { |
|||
immutable int instruction = code[index]; |
|||
switch (instruction) { |
|||
case '>': cell++; assert(cell < tape.length); break; |
|||
case '<': cell--; assert(cell >= 0); break; |
|||
case '+': tape[cell]++; break; |
|||
case '-': tape[cell]--; break; |
|||
case '.': putchar(tape[cell]); break; |
|||
case ',': |
|||
int c = getchar(); |
|||
if (c == EOF) |
|||
exit(1); |
|||
tape[cell] = cast(char)c; |
|||
break; |
|||
case '[': |
|||
if (tape[cell] == empty) |
|||
index = loops[index]; |
|||
break; |
|||
case ']': |
|||
if (tape[cell] != empty) |
|||
index = loops[index]; |
|||
break; |
|||
default: break; |
|||
} |
|||
index++; |
|||
} |
|||
} |
|||
int[int] loops = matchBraces(code); |
|||
runCode(code, loops); |
|||
} |
|||
void main() { |
|||
brainfuckRun("++++++++++[>+++++++>++++++++++>+++>+<<<<-] |
|||
>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."); |
|||
}</lang> |
|||
== Implementation 3 == |
|||
Faster partially compile-time version (code generated at compile-time, run at run time): |
|||
<lang d>import core.stdc.stdio, core.stdc.stdlib; |
|||
pure string ctbf(in string code) { |
|||
string r; |
|||
foreach (c; code) |
|||
switch (c) { |
|||
case '>': r ~= "i++; assert(i < m.length);"; break; |
|||
case '<': r ~= "i--; assert(i >= 0);"; break; |
|||
case '+': r ~= "m[i]++;"; break; |
|||
case '-': r ~= "m[i]--;"; break; |
|||
case '[': r ~= "while (m[i]) {"; break; |
|||
case ']': r ~= "}"; break; |
|||
case '.': r ~= "putchar(m[i]);"; break; |
|||
case ',': r ~= "int d = getchar(); |
|||
if (d == EOF) exit(1); |
|||
m[i] = cast(char)d;"; break; |
|||
default: break; |
|||
} |
|||
return r; |
|||
} |
|||
void main() { |
|||
char[30_000] m = '\0'; |
|||
size_t i; |
|||
mixin(ctbf("++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++ |
|||
++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.")); |
|||
}</lang> |