Skip to content

Instantly share code, notes, and snippets.

@angelcaru
Created February 28, 2024 19:37
Show Gist options
  • Save angelcaru/0cc8fdd0e931bee9f96c49ea92e704f5 to your computer and use it in GitHub Desktop.
Save angelcaru/0cc8fdd0e931bee9f96c49ea92e704f5 to your computer and use it in GitHub Desktop.
Brainf**k transpiler in C
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
void usage(const char *program_name) {
printf("Usage: %s <input-file>\n", program_name);
}
void bf_header(FILE *out) {
fprintf(out, "#include <stdio.h>\n");
fprintf(out, "unsigned char tape[640000]; // should be enough for everyone\n");
fprintf(out, "int main() {\n");
fprintf(out, " unsigned char *ptr = &tape[0];\n");
}
void bf_footer(FILE *out) {
fprintf(out, "}\n");
}
void compile_char(FILE *out, char ch) {
switch (ch) {
case '+': {
fprintf(out, " ++*ptr;\n");
} break;
case '-': {
fprintf(out, " --*ptr;\n");
} break;
case '<': {
fprintf(out, " ptr--;\n");
} break;
case '>': {
fprintf(out, " ptr++;\n");
} break;
case '.': {
fprintf(out, " putchar(*ptr);\n");
} break;
case ',': {
fprintf(out, " *ptr = getchar();\n");
} break;
case '[': {
fprintf(out, " while (*ptr) {\n");
} break;
case ']': {
fprintf(out, " }\n");
} break;
}
}
int main(int argc, char *argv[]) {
if (argc != 2) {
usage(argv[0]);
fprintf(stderr, "ERROR: no input file provided\n");
return 1;
}
argv++;
FILE *infile = fopen(*argv, "r");
if (infile == NULL) {
fprintf(stderr, "ERROR: could not open file %s: %s\n", *argv, strerror(errno));
return 1;
}
const char *out_file_path = "out.c";
FILE *outfile = fopen(out_file_path, "w");
if (outfile == NULL) {
fprintf(stderr, "ERROR: could not open file %s: %s\n", out_file_path, strerror(errno));
return 1;
}
bf_header(outfile);
char ch;
while (fread(&ch, 1, 1, infile) != 0) {
compile_char(outfile, ch);
}
puts("");
fclose(infile);
bf_footer(outfile);
fclose(outfile);
int code = execlp("gcc", "cc", "-o", "out", "out.c", NULL);
if (code != 0) {
fprintf(stderr, "ERROR: gcc exited with non-zero code: %d", code);
return code;
}
execlp("rm", "out.c", NULL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment