Skip to content

Instantly share code, notes, and snippets.

@Rexagon
Last active May 9, 2016 12:43
Show Gist options
  • Save Rexagon/c9da8c9b094c05bf49696b4e7440c8bb to your computer and use it in GitHub Desktop.
Save Rexagon/c9da8c9b094c05bf49696b4e7440c8bb to your computer and use it in GitHub Desktop.
Brainfuck console interpreter
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <fstream>
class Script
{
public:
bool Load(const std::string& code)
{
m_bracemap.clear();
std::stack<int> temp;
int state = 0;
for (size_t i = 0; i < code.size(); ++i) {
if (code[i] == '[') {
state++;
temp.push(i);
}
else if (code[i] == ']') {
state--;
int start = temp.top();
temp.pop();
m_bracemap[start] = i;
m_bracemap[i] = start;
}
}
if (state == 0) {
m_code = code;
return true;
} else {
m_bracemap.clear();
return false;
}
}
void Run()
{
std::vector<int> cells(999);
unsigned int codeptr = 0;
unsigned short cellptr = 500;
bool couted = false;
while (codeptr < m_code.size()) {
unsigned char s = m_code[codeptr];
if (s == '>') {
cellptr++;
if (cellptr == cells.size()) cells.push_back(0);
} else if (s == '<') {
if (cellptr <= 0) {
cellptr = 0;
} else {
cellptr--;
}
} else if (s == '+') {
cells[cellptr]++;
} else if (s == '-') {
cells[cellptr]--;
} else if (s == '.') {
std::cout << char(cells[cellptr]);
couted = true;
} else if (s == ',') {
if (couted) std::cout << "\n";
std::cout << "[inp]: ";
int inp;
std::cin >> inp;
cells[cellptr] = char(inp);
} else if ((s == '[') && (cells[cellptr] == 0)) {
codeptr = m_bracemap[codeptr];
} else if (s == ']' && (cells[cellptr] != 0)) {
codeptr = m_bracemap[codeptr];
} else if (s == '!') {
break;
}
codeptr++;
}
if (couted) std::cout << "\n";
}
private:
std::string m_code;
std::map<int, unsigned int> m_bracemap;
};
int main(int argc, char** argv)
{
Script script;
if (argc == 1) {
std::cout << "BrainfuckIO v0.1.0\nCreated by ENOJ <^_^>\nType @ for help and ! to exit\n[code]: ";
std::string input;
std::getline(std::cin >> std::ws, input);
while (input != "!") {
if (input == "@") {
std::cout << "It is just a brainfuck interpreter written using C++.\n -f filename to load code from file\n -c code to load code from console\n";
} else {
if (script.Load(input)) {
script.Run();
} else {
std::cout << "Error in loading script!\n";
}
}
std::cout << "[code]: ";
std::getline(std::cin >> std::ws, input);
}
} else if (argc > 2) {
std::string flag(argv[1]);
if (flag == "-c") {
if (script.Load(std::string(argv[2]))) {
script.Run();
} else {
std::cout << "Error in loading script!\n";
return 0;
}
} else if (flag == "-f") {
std::string code;
std::ifstream file;
file.open(std::string(argv[2]));
if (file) {
while (!file.eof()) {
std::string line;
file >> line;
code += line;
}
if (script.Load(code)) {
script.Run();
} else {
std::cout << "Error in loading script!\n";
return 0;
}
} else {
std::cout << "File not found!\n";
return 0;
}
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment