From 44d93406a0aec81485576338deed5b8995039662 Mon Sep 17 00:00:00 2001 From: Miguel Angel Astor Romero Date: Mon, 15 Aug 2016 18:31:34 -0400 Subject: [PATCH] Added Brainf*ck to C translator. --- bf.c | 9 ++--- bf2c.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 bf2c.c diff --git a/bf.c b/bf.c index 77d0c72..e9298e1 100644 --- a/bf.c +++ b/bf.c @@ -12,13 +12,12 @@ static long loop_stack[MAX_LOOPS]; /* Loop stack. */ static unsigned int tape_ptr = 0; /* Current tape position. */ static unsigned int loop_ptr = 0; /* Loop stack top. */ -int -main (int argc, char **argv) { +int main (int argc, char **argv) { FILE * f; /* The input file. */ unsigned int i; /* The current file being processed. */ unsigned int l; /* A counter for looping. */ unsigned int done; /* Boolean for looping. */ - char c; /* Current BF instruction. */ + char c; /* Current BF instruction. */ if (argc == 1) { /* There must be at leas one input file. */ @@ -39,7 +38,7 @@ main (int argc, char **argv) { f = fopen (argv[i], "r"); if (f == NULL) { - fprintf (stderr, "Failed to open %s\n", argv[1]); + fprintf (stderr, "Failed to open %s\n", argv[i]); continue; } else { @@ -113,7 +112,7 @@ main (int argc, char **argv) { switch(c) { case EOF: /* Skip the file on EOF. */ - fprintf (stderr, "%s: Fatal error in %s: premature EOF\n", argv[0], argv[1]); + fprintf (stderr, "%s: Fatal error in %s: premature EOF\n", argv[0], argv[i]); goto skip; break; diff --git a/bf2c.c b/bf2c.c new file mode 100644 index 0000000..f46a07a --- /dev/null +++ b/bf2c.c @@ -0,0 +1,125 @@ +#include +#include +#include + +#define EXIT_NO_INPUT 4 + +static const char * BF_HEADER = "#include \n#include \n#include \n\nstatic unsigned char tape[30000];\nstatic unsigned int tape_ptr = 0;\n\nint main(void) {\n\tmemset(tape, 0, 30000 * sizeof(unsigned char));\n"; +static const char * BF_FOOTER = "\n\treturn EXIT_SUCCESS;\n}\n"; + +static inline void print_tabs (FILE * f, unsigned int t) { + int i; + for (i = 0; i < t; i++) + fputc('\t', f); +} + +int main (int argc, char **argv) { + FILE * f; /* The input file. */ + FILE * o; /* The output file. */ + unsigned int i; /* The current file being processed. */ + unsigned int t; /* Tab level. */ + char c; /* Current BF instruction. */ + char * out_file; /* Output file name. */ + + if (argc == 1) { + /* There must be at leas one input file. */ + fprintf (stderr, "%s: fatal error: no input files\n", argv[0]); + return EXIT_NO_INPUT; + + } else { + + for (i = 1; i < argc; i++) { + /* Try to open the input and output files. */ + out_file = (char *) calloc (strlen(argv[i]) + 3, sizeof(char)); + if (out_file == NULL) { + fprintf (stderr, "Could not allocate memory for output file name\n"); + return EXIT_FAILURE; + + } else { + sprintf(out_file, "%s.c", argv[i]); + f = fopen (argv[i], "r"); + o = fopen (out_file, "w"); + + if (f == NULL || o == NULL) { + fprintf (stderr, "Failed to open %s or %s\n", argv[i], out_file); + continue; + + } else { + t = 1; + + /* Print boilerplate. */ + fprintf(o, "%s", BF_HEADER); + + /* If the file opened, then read characters from it one by one. */ + while ((c = fgetc (f)) != EOF) { + + /* Proccess the character. */ + switch (c) { + + case '.': + /* BF output instruction. */ + print_tabs (o, t); + fprintf(o, "putchar((int)tape[tape_ptr]);\n"); + print_tabs (o, t); + fprintf(o, "fflush(stdout);\n"); + break; + + case ',': + /* BF input instruction. */ + print_tabs (o, t); + fprintf(o, "tape[tape_ptr] = (unsigned char)getchar();\n"); + break; + + case '+': + /* BF tape increment instruction. */ + print_tabs (o, t); + fprintf(o, "tape[tape_ptr]++;\n"); + break; + + case '-': + /* BF Tape decrement instruction. */ + print_tabs (o, t); + fprintf(o, "tape[tape_ptr]--;\n"); + break; + + case '>': + /* BF move to next cell instruction. */ + print_tabs (o, t); + fprintf(o, "tape_ptr = (tape_ptr + 1) %% 30000;\n"); + break; + + case '<': + /* BF move to previous cell instruction. */ + print_tabs (o, t); + fprintf(o, "tape_ptr = (tape_ptr == 0) ? 29999: tape_ptr - 1;\n"); + break; + + case '[': + /* BF open loop instruction. */ + print_tabs (o, t++); + fprintf(o, "while (tape[tape_ptr]) {\n"); + break; + + case ']': + /* BF close loop instruction. */ + print_tabs (o, --t); + fprintf(o, "}\n"); + break; + + default: + continue; + } /* switch(c) */ + } /* while(c = fgetc(f)) */ + + /* Print boilerplate. */ + fprintf(o, "%s", BF_FOOTER); + + /* Done with this file. */ + fclose (f); + } + } + } + } + + return 0; +}