Created
December 23, 2019 09:00
-
-
Save metarin/7c9ccd511ba5df05b576e1e8a4485278 to your computer and use it in GitHub Desktop.
BrainCrash interpreter
This file contains 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
// 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