Skip to content

Instantly share code, notes, and snippets.

@metarin

metarin/bci.cpp

Created Dec 23, 2019
Embed
What would you like to do?
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
You can’t perform that action at this time.