Skip to content

Instantly share code, notes, and snippets.

@b1ek
Last active August 7, 2023 22:24
Show Gist options
  • Save b1ek/bea2176e82df7e7e69530cacace45de2 to your computer and use it in GitHub Desktop.
Save b1ek/bea2176e82df7e7e69530cacace45de2 to your computer and use it in GitHub Desktop.
Brainfuck compiler

Brainfuck compiler

Pretty much the title. Array length is not limited to 30000 anymore, it is calculated on the compile time.
It passed all the tests

Input file: file.txt
Out file: out.c

It is compiled to c code

program.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "types.h" // scroll a bit down for this file

#define strapp(s) out = str_app(out, s)

#define OP_N  0
#define OP_I  1
#define OP_D  2

#define OP_NN 3
#define OP_IN 4
#define OP_OT 5
#define OP_OF 6

char *str_app(const char *s, const char *s2) {
    size_t len = strlen(s) + strlen(s2) + 1;
    char *s3 = malloc(len);
    sprintf(s3, "%s%s", s, s2);
    return s3;
}

int main(int argc, char** argv) {
	
	char* out = "";
	
	char c;
	unsigned char lop = OP_N;
	size_t opc = 0;
	size_t brackets = 0;
	
	size_t outsz = 1;
	char* in_filename;
	if (argc >= 2) {
		in_filename = malloc((strlen(argv[1])+1)*sizeof(char));
		strcpy(in_filename, argv[1]);
	} else {
		in_filename = malloc(9*sizeof(char));
		strcpy(in_filename, "file.txt");
	}
	
	FILE* file = fopen(in_filename, "r");
	
	char* trimmed = "";
	if (file) {
		printf("Parsing file\n");
		while ((c = getc(file)) != EOF) {
			switch (c) {
				case '>':
					outsz++;
					strapp("++p;");
					trimmed = str_app(trimmed, ">");
					break;
				case '<': 
					strapp("--p;");
					trimmed = str_app(trimmed, "<");
					break;
				case '.':
					strapp("o(*p);");
					trimmed = str_app(trimmed, ".");
					break;
				case ',':
					strapp("*p=i();");
					trimmed = str_app(trimmed, ",");
					break;
				case '[':
					strapp("\nwhile(*p){\n");
					trimmed = str_app(trimmed, "[");
					brackets++;
					break;
				case ']':
					strapp("\n}\n");
					trimmed = str_app(trimmed, "]");
					brackets--;
					break;
				case '+':
					strapp("++*p;");
					break;
				case '-':
					strapp("--*p;");
					break;
			}
		}
		if (brackets != 0) {
			printf("Error: unmatched [ or ]\n");
			exit(-1);
		}
		printf("Done parsing file, program buffer size: %llu\n", outsz);
		
		
		FILE *outf = fopen("out.c", "w+");
		if (outf) {
			fprintf(outf,
			"// This is generated by brainfuck compiler\n"
			"// so dont even expect to understand this code\n"
			"// -- Have fun! --\n"
			"#include <stdio.h>\n"
			"#define o(s) putchar(s)\n"
			"#define i() getchar()\n\n"
			
			"int main() {"
			"char b[%llu]={0};char*p=b;%s\n"
			"}\n"
			"/* Brainfuck source: \n\n%s\n*/"
			, outsz, out, trimmed);
			fseek(outf, 0L, SEEK_END);
			printf("Written %9.2f KB to out.c\n", (float)ftell(outf)/1000);
			fclose(outf);
		} else {
			fprintf(stderr, "ERR: Cant open out.c for writing\n");
			exit(-1);		
		}
		fclose(file);
	} else {
		fprintf(stderr, "ERR: Cannot open file %s!\n", in_filename);
		exit(-1);
	}
	free(out);
}

types.h

#ifndef __TYPESH
#define __TYPESH

// size_t
#ifdef size_t
#undef size_t
#define size_t long long int
#endif
#ifndef size_t
#define size_t long long int
#endif

// booleans
#ifndef true
#define true 1
#endif

#ifndef false
#define false 0
#endif

#endif // __TYPESH

brainfuck hello world

[,.[.],..,,,+,-,<>,[]..]++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment