1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#define BF_BUFFER_MIN "0"
#define BF_BUFFER_MAX "32768"
static const char* BF_HEAD = "#include <stdint.h>\n"
"#include <stdio.h>\n"
"\n"
"#define BUFFER_MIN " BF_BUFFER_MIN "\n"
"#define BUFFER_MAX " BF_BUFFER_MAX "\n"
"\n"
"int main(void)\n"
"{\n"
" static uint8_t buffer[BUFFER_MAX];\n"
" static uint32_t index = 0;\n";
static const char* BF_IPTR = " if (index < BUFFER_MAX)\n"
" ++index;\n"
" else\n"
" index = 0;\n";
static const char* BF_DPTR = " if (index > BUFFER_MIN)\n"
" --index;\n"
" else\n"
" index = BUFFER_MAX - 1;\n";
static const char* BF_IVAL = " ++buffer[index];\n";
static const char* BF_DVAL = " --buffer[index];\n";
static const char* BF_PUTC = " putchar(buffer[index]);\n";
static const char* BF_GETC = " buffer[index] = getchar();\n";
static const char* BF_LOOP1 = "L$a:\n"
" if (buffer[index] == 0)\n"
" goto L$b;\n";
static const char* BF_LOOP2 = "L$b:\n"
" if (buffer[index] != 0)\n"
" goto L$a;\n";
static const char* BF_TAIL = " return 0;\n"
"}\n";
static std::string replace_all(const std::string& a, const std::string& b, std::string s)
{
size_t pos = 0;
while ((pos = s.find(a)) != std::string::npos)
s.replace(pos, a.size(), b);
return s;
}
static std::string chars2string(std::vector <char> chars)
{
std::stringstream sstream;
for (char c : chars)
sstream << c;
return sstream.str();
}
int main()
{
int c, label = 1, nest = 0;
std::cout << BF_HEAD;
while ((c = std::cin.get())) {
if (std::cin.eof())
break;
switch (c) {
case '>': std::cout << BF_IPTR; break;
case '<': std::cout << BF_DPTR; break;
case '+': std::cout << BF_IVAL; break;
case '-': std::cout << BF_DVAL; break;
case '.': std::cout << BF_PUTC; break;
case ',': std::cout << BF_GETC; break;
case '[':
std::cout << replace_all("$", chars2string({ char(label + '0'),
char(nest + '0') }), BF_LOOP1);
++nest;
break;
case ']':
--nest;
std::cout << replace_all("$", chars2string({ char(label + '0'),
char(nest + '0') }), BF_LOOP2);
if (!(nest))
++label;
break;
default:
break;
}
}
std::cout << BF_TAIL << std::endl;
return 0;
}
|