// bfid - BrainFuck GNU interpreter, (C) 2002 Philippe Biondi, biondi@cartel-securite.fr // Translated to D by leonardo maffi, Sept 20 2007 import std.stdio: writefln, getchar, putchar; import std.string: removechars; import std.file; void bf_interpreter(string prog) { int ip = 0; int p = 0; int level = 0; auto tape = new ubyte[1_000]; const CELL = typeof(tape[0]).max; // clean up input program to speed up execution prog = removechars(prog, "^><+-.,[]"); while (ip < prog.length) { auto x = prog[ip++]; switch (x) { // order of cases computed from actual frequencies case '>': p++; if (tape.length <= p) tape.length = tape.length * 2; break; case '<': if (p) p--; else { assert(0, "Warning: inserting one element at the begining"); //writefln("Warning: inserting one element at the begining"); //tape = [0] ~ tape; } break; case '[': if (!tape[p]) { while (true) { if (prog[ip] == '[') level++; if (prog[ip] == ']') { if (level) level--; else break; } ip++; } ip++; } break; case ']': ip -= 2; while (true) { if (prog[ip] == ']') level++; if (prog[ip] == '[') { if (level) level--; else break; } ip--; } break; case '+': tape[p] = (tape[p] + 1) & CELL; break; case '-': tape[p] = (tape[p] - 1) & CELL; break; case '.': putchar(tape[p]); break; default: // always x == ',' because the program is clean tape[p] = getchar(); break; } // end switch } // end while } void main(string[] args) { if (args.length < 2) writefln("Brainfuck interpreter. Usage: bfiSS brainfuck_program_name"); else bf_interpreter( cast(string)std.file.read(args[1]) ); }