BrainCrash interpreter
// BrainCrash interpreter on C++ | |
// written by metarin. | |
#include <vector> | |
#include <iostream> | |
#include <fstream> | |
#include <cstring> | |
int main(int argc, char** argv) | |
{ | |
if (argc < 2 || strcmp(argv[1], "-h") == 0) | |
{ | |
std::cout << "usage:\n" | |
"\tbfi <file path>\n"; | |
return 0; | |
} | |
std::ifstream ifs(argv[1], std::ios::in); | |
if (!ifs) | |
{ | |
std::cout << "Can't open " << argv[1] << '\n'; | |
return -1; | |
} | |
// array (Turing Machine's tape) | |
std::vector<char> arr(14, '\0'); | |
// iterator (Turing Machine's tape head) | |
auto itr = arr.begin(); | |
// buffer | |
char buf = '\0'; | |
// loop val | |
std::vector<std::streampos> begLoop; | |
// init memory | |
memcpy(&*arr.begin(), "Hello, world!", 13); | |
ifs.get(buf); | |
while (!ifs.eof()) | |
{ | |
//putchar(buf); | |
switch (buf) | |
{ | |
case '>': // ポインタのインクリメント | |
if (itr - arr.begin() + 1 >= arr.size()) | |
{ | |
size_t n = itr - arr.begin(); | |
arr.resize(arr.size() + 100, 0); | |
itr = arr.begin() + n; | |
} | |
itr++; | |
break; | |
case '<': // ポインタのデクリメント | |
itr--; | |
break; | |
case '+': // ポインタの参照先のインクリメント | |
(*itr)++; | |
break; | |
case '-': // ポインタの参照先のデクリメント | |
(*itr)--; | |
break; | |
case '.': // ポインタの参照先の出力 | |
std::cout.put(*itr); | |
break; | |
case ',': // ポインタの参照先への入力 | |
(*itr) = std::cin.get(); | |
break; | |
case '[': // ループ開始 | |
if (*itr) // *itr != 0 | |
{ | |
begLoop.push_back(ifs.tellg()); | |
} | |
// 最初からポインタの参照先が0の場合 | |
// Syntax Error(非対称な括弧) やるとインタプリタ巻き込んで落ちるよ! | |
else // *itr == 0 | |
{ | |
int nestc = 1; | |
while (nestc && ifs.good()) | |
{ | |
ifs.get(buf); | |
if (buf == '[') | |
++nestc; | |
else if(buf == ']') | |
--nestc; | |
} | |
} | |
break; | |
case ']': // ループ終端 | |
if (*itr != '\0') // *itr != 0 | |
{ | |
ifs.seekg(*(begLoop.end() - 1)); | |
} | |
else // *itr == 0 | |
{ | |
begLoop.pop_back(); | |
begLoop.shrink_to_fit(); | |
} | |
break; | |
case '|': // OR | |
if (itr - arr.begin() + 1 >= arr.size()) | |
{ | |
size_t n = itr - arr.begin(); | |
arr.resize(arr.size() + 100, 0); | |
itr = arr.begin() + n; | |
} | |
itr++; | |
*itr = *(itr - 1) | *itr; | |
break; | |
case '&': // AND | |
if (itr - arr.begin() + 1 >= arr.size()) | |
{ | |
size_t n = itr - arr.begin(); | |
arr.resize(arr.size() + 100, 0); | |
itr = arr.begin() + n; | |
} | |
itr++; | |
*itr = *(itr - 1) & *itr; | |
break; | |
case '^': // XOR | |
if (itr - arr.begin() + 1 >= arr.size()) | |
{ | |
size_t n = itr - arr.begin(); | |
arr.resize(arr.size() + 100, 0); | |
itr = arr.begin() + n; | |
} | |
itr++; | |
*itr = *(itr - 1) ^ *itr; | |
break; | |
case '~': | |
*itr = ~(*itr); | |
break; | |
default: // コメント | |
break; | |
} | |
ifs.get(buf); | |
} | |
while(*itr) | |
{ | |
std::cout.put(*itr); | |
itr++; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment