Created
August 13, 2015 20:34
-
-
Save yannayl/d8c2c93d96ee2cffcc92 to your computer and use it in GitHub Desktop.
brainfuck to c converter
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
| /* | |
| * A simple, non-optimizing brainfuck to C translator. | |
| * 2010-08-31 - Version 1.0 (Cory Burgett) | |
| * | |
| * This code is hereby placed into the public domain. | |
| * | |
| * Originally located at: http://www4.ncsu.edu/~cmburget/brainfucc.c | |
| * based on https://gist.github.com/939687.git | |
| */ | |
| #include <stdio.h> | |
| int is_arith(char c) { | |
| switch (c) { | |
| case '>': | |
| case '<': | |
| case '+': | |
| case '-': | |
| return -1; break; | |
| default: return 0; break; | |
| } | |
| } | |
| int is_data(char c) { | |
| switch (c) { | |
| case '.': | |
| case ',': | |
| case '[': | |
| case ']': | |
| return -1; break; | |
| default: return 0; break; | |
| } | |
| } | |
| void print_depth(FILE *out, unsigned depth) { | |
| //fprintf(out, "// depth = %u\n", depth); | |
| for (; depth > 0; --depth) | |
| fprintf(out, "\t"); | |
| } | |
| void print_arith(FILE *out, unsigned depth, char c, unsigned repetitions, unsigned char_nr) { | |
| //fprintf(out, "// char = %c\n", c); | |
| #if 1 | |
| print_depth(out, depth); | |
| switch (c) { | |
| case '>': fprintf(out, "cell += %u;", repetitions); break; | |
| case '<': fprintf(out, "cell -= %u;", repetitions); break; | |
| case '+': fprintf(out, "*cell += %u;", repetitions); break; | |
| case '-': fprintf(out, "*cell -= %u;", repetitions); break; | |
| default: break; | |
| } | |
| fprintf(out, " // %u-%u\n", char_nr + 1 - repetitions, char_nr); | |
| #else | |
| unsigned i; | |
| for (i = 0; i < repetitions; i++) { | |
| print_depth(out, depth); | |
| switch (c) { | |
| case '>': fprintf(out, "++cell;\n"); break; | |
| case '<': fprintf(out, "--cell;\n"); break; | |
| case '+': fprintf(out, "++*cell;\n"); break; | |
| case '-': fprintf(out, "--*cell;\n"); break; | |
| default: break; | |
| } | |
| } | |
| #endif | |
| } | |
| void print_data(FILE *out, unsigned *depth, char c, unsigned char_nr){ | |
| //fprintf(out, "// char = %c\n", c); | |
| if (']' == c) { | |
| *depth -= 1; | |
| } | |
| print_depth(out, *depth); | |
| switch (c) { | |
| case '.': fprintf(out, "putchar(*cell);"); break; | |
| case ',': fprintf(out, "*cell = getchar();"); break; | |
| case '[': fprintf(out, "while (*cell) {"); break; | |
| case ']': fprintf(out, "}"); break; | |
| default: break; | |
| } | |
| fprintf(out, " // %u\n", char_nr); | |
| if ('[' == c) { | |
| *depth += 1; | |
| } | |
| } | |
| int main(int argc, char **argv) | |
| { | |
| FILE *in = stdin, *out = stdout; | |
| int c; | |
| int cellsize = 30000; | |
| unsigned times = 0; | |
| char prev = '\0'; | |
| unsigned depth = 1; | |
| unsigned char_nr = -1; | |
| fprintf(out, | |
| "#include <stdio.h>\n" | |
| "#include <stdlib.h>\n\n" | |
| "int main(int argc, char **argv)\n{\n" | |
| "\tunsigned char *cell = calloc(%d, 1);\n" | |
| "\tunsigned char *cells = cell;\n" | |
| "\tif (!cell) {\n" | |
| "\t\tfprintf(stderr, \"Error allocating memory.\\n\");\n" | |
| "\t\treturn 1;\n" | |
| "\t}\n\n", cellsize | |
| ); | |
| while ((c = getc(in)) != EOF) { | |
| ++char_nr; | |
| if (is_arith(c) && prev == c) { | |
| ++times; | |
| continue; | |
| } | |
| if (times > 0) { | |
| print_arith(out, depth, prev, times, char_nr - 1); | |
| times = 0; | |
| } | |
| prev = c; | |
| if (is_arith(c)) { | |
| ++times; | |
| } else { | |
| print_data(out, &depth, c, char_nr); | |
| } | |
| } | |
| if (times > 0) { | |
| print_arith(out, depth, prev, times, char_nr); | |
| } | |
| fprintf(out, "\n\tfree(cells);\n\treturn 0;\n}\n\n"); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment