Generic Headers
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
typedef std::string const BFProgram;
BF Interpreter
class BFInterpretor
{
static const std::size_t MemorySize = 10000;
std::vector<char> memory;
std::vector<std::size_t> openLoops;
BFProgram& program;
std::istream& input;
std::ostream& output;
std::size_t dataPointer;
std::size_t progPointer;
std::size_t scanToEndOfLoop()
{
std::size_t nestedLoops = 1;
std::size_t scanPos = progPointer;
for(;nestedLoops != 0;++scanPos)
{
switch(program[scanPos])
{
case '[': ++nestedLoops; break;
case ']': --nestedLoops; break;
default: break;
}
}
return scanPos;
}
public:
BFInterpretor(BFProgram& program, std::istream& input = std::cin, std::ostream& output = std::cout)
: memory(MemorySize)
, program(program)
, input(input)
, output(output)
, dataPointer(0)
, progPointer(0)
{}
static bool bfComment(char c)
{
switch(c)
{
case '>': case '<': case '.': case ',': case '+': case '-': case '[': case ']':
return false;
default:
break;
}
return true;
}
void run()
{
while(progPointer < program.size())
{
++progPointer;
switch(program[progPointer - 1])
{
case '>': dataPointer = (dataPointer + 1) % MemorySize;break;
case '<': dataPointer = (dataPointer - 1) % MemorySize;break;
case '+': ++(memory[dataPointer]); break;
case '-': --(memory[dataPointer]); break;
case '.': output.put(memory[dataPointer]); break;
case ',': memory[dataPointer] = input.get(); break;
case '[': if (memory[dataPointer]) {
openLoops.push_back(progPointer);
}
else {
progPointer = scanToEndOfLoop();
}
break;
case ']': if (memory[dataPointer]) {
progPointer = openLoops.back();
}
else {
openLoops.pop_back();
}
break;
default: break; /* Ignore all comments */
}
}
}
};
Program Loader
BFProgram loadProgram(std::istream& program)
{
std::string programText;
std::string line;
while(std::getline(program, line))
{
line.erase(std::remove_if(std::begin(line), std::end(line), [](char c){return BFInterpretor::bfComment(c);}), std::end(line));
programText.append(line);
}
return programText;
}
BFProgram loadProgram(std::string const& file)
{
if (file == "-") {
return loadProgram(std::cin);
}
std::ifstream program(file);
return loadProgram(program);
}
Main
int main(int argc, char* argv[])
{
std::vector<std::string> args(argv+1 , argv+argc);
if (args.empty()) {
args.push_back("-");
}
for(std::string const& file: args) {
std::string program = loadProgram(file);
BFInterpretor interpretor(program);
interpretor.run();
}
}