Added Brainf*ck to C translator.
This commit is contained in:
9
bf.c
9
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;
|
||||
|
||||
|
125
bf2c.c
Normal file
125
bf2c.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define EXIT_NO_INPUT 4
|
||||
|
||||
static const char * BF_HEADER = "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\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;
|
||||
}
|
Reference in New Issue
Block a user