Execute Brain****: Difference between revisions

→‎{{header|D}}: Move alternate implementations to /D subpage. They must go there, else readers of /D subpage cannot see that alternate implementations are available.
(bug fix: ignore unknown chars instead of logging them.)
(→‎{{header|D}}: Move alternate implementations to /D subpage. They must go there, else readers of /D subpage cannot see that alternate implementations are available.)
Line 127:
 
[[/D|Implementation in D]].
 
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>
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>
 
=={{header|dodo0}}==
Anonymous user