Created
August 30, 2015 15:27
-
-
Save DTSCode/55c816c8121d5cf009c4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
+ : Increments the value at the current cell by one. | |
- : Decrements the value at the current cell by one. | |
> : Moves the data pointer to the next cell (cell on the right). | |
< : Moves the data pointer to the previous cell (cell on the left). | |
. : Prints the ASCII value at the current cell (i.e. 65 = 'A'). | |
, : Reads a single input character into the current cell. | |
[ : If the value at the current cell is zero, skips to the corresponding ] . | |
Otherwise, move to the next instruction. | |
] : If the value at the current cell is zero, move to the next instruction. | |
Otherwise, move backwards in the instructions to the corresponding [ . | |
*/ | |
#include <iostream> | |
#include <fstream> | |
#include <streambuf> | |
#include <algorithm> | |
#include <string> | |
#include <vector> | |
class BrainfuckTape { | |
public: | |
BrainfuckTape(): tape{0}, tape_ptr(tape.begin()) { | |
} | |
~BrainfuckTape() { | |
} | |
void inc() { | |
(*tape_ptr)++; | |
} | |
void dec() { | |
(*tape_ptr)--; | |
} | |
void next() { | |
tape_ptr++; | |
} | |
void prev() { | |
tape_ptr--; | |
} | |
void out() { | |
std::cout << char(*tape_ptr); | |
} | |
void get() { | |
} | |
int value() { | |
return *tape_ptr; | |
} | |
private: | |
std::vector<int> tape; | |
std::vector<int>::iterator tape_ptr; | |
}; | |
void error(const std::string &msg) { | |
std::cerr << "error: " << msg << std::endl; | |
return; | |
} | |
void compile(std::string code) { | |
BrainfuckTape tape; | |
std::string::iterator loop_begin; | |
for(std::string::iterator iter = code.begin(), end = code.end(); iter != end; iter++) { | |
if(*iter == '+') { | |
tape.inc(); | |
} else if(*iter == '-') { | |
tape.dec(); | |
} else if(*iter == '>') { | |
tape.next(); | |
} else if(*iter == '<') { | |
tape.prev(); | |
} else if(*iter == '.') { | |
tape.out(); | |
} else if(*iter == ',') { | |
tape.get(); | |
} else if(*iter == '[') { | |
if(tape.value() == 0) { | |
iter = std::find(iter, code.end(), ']'); | |
} else { | |
loop_begin = iter; | |
} | |
} else if(*iter == ']') { | |
if(tape.value() == 0) { | |
iter++; | |
} else { | |
iter = loop_begin; | |
} | |
} | |
} | |
std::cout << std::endl; | |
} | |
int main(int argc, char *argv[]) { | |
int status = 0; | |
if(argc != 2) { | |
error("improper usage.\nusage: " + std::string(argv[0]) + " FILE"); | |
status = 1; | |
} else { | |
std::ifstream handle(argv[1]); | |
if(not handle) { | |
error("could not open file."); | |
status = 1; | |
} else { | |
std::string code((std::istreambuf_iterator<char>(handle)), std::istreambuf_iterator<char>()); | |
compile(code); | |
} | |
} | |
return status; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment