Added Brainf*ck to C translator.
This commit is contained in:
7
bf.c
7
bf.c
@@ -12,8 +12,7 @@ static long loop_stack[MAX_LOOPS]; /* Loop stack. */
|
|||||||
static unsigned int tape_ptr = 0; /* Current tape position. */
|
static unsigned int tape_ptr = 0; /* Current tape position. */
|
||||||
static unsigned int loop_ptr = 0; /* Loop stack top. */
|
static unsigned int loop_ptr = 0; /* Loop stack top. */
|
||||||
|
|
||||||
int
|
int main (int argc, char **argv) {
|
||||||
main (int argc, char **argv) {
|
|
||||||
FILE * f; /* The input file. */
|
FILE * f; /* The input file. */
|
||||||
unsigned int i; /* The current file being processed. */
|
unsigned int i; /* The current file being processed. */
|
||||||
unsigned int l; /* A counter for looping. */
|
unsigned int l; /* A counter for looping. */
|
||||||
@@ -39,7 +38,7 @@ main (int argc, char **argv) {
|
|||||||
f = fopen (argv[i], "r");
|
f = fopen (argv[i], "r");
|
||||||
|
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
fprintf (stderr, "Failed to open %s\n", argv[1]);
|
fprintf (stderr, "Failed to open %s\n", argv[i]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -113,7 +112,7 @@ main (int argc, char **argv) {
|
|||||||
switch(c) {
|
switch(c) {
|
||||||
case EOF:
|
case EOF:
|
||||||
/* Skip the file on 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;
|
goto skip;
|
||||||
break;
|
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