Skip to content

Instantly share code, notes, and snippets.

@zeaga
Created August 7, 2022 16:50
Show Gist options
  • Save zeaga/134a94de614f83e9d829754cb27c868a to your computer and use it in GitHub Desktop.
Save zeaga/134a94de614f83e9d829754cb27c868a to your computer and use it in GitHub Desktop.
Simple brainfuck compiler in less than 100 lines of C
#include <stdio.h>
#include <stdlib.h>
char* read_file( char* file_name ) {
FILE* file = fopen( file_name, "r" );
if ( file == NULL ) {
printf( "Could not open input file `%s`.\n", file_name );
exit( 1 );
}
// Get file size
fseek( file, 0, SEEK_END );
long file_size = ftell( file );
fseek( file, 0, SEEK_SET );
// Allocate memory for file data
char* code = malloc( file_size );
// Read file data
int c;
size_t n = 0;
while ( ( c = fgetc( file ) ) != EOF ) {
code[n++] = (char)c;
}
// Terminate c-string with null character
code[n] = '\0';
return code;
}
void generate_output( char* code, char* output_path ) {
FILE* file = fopen( output_path, "w" );
if ( file == NULL ) {
printf( "Could not open output file `%s`.\n", output_path );
exit( 1 );
}
// Write header with defines to slim down final file size
fprintf( file,
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#define A ++p\n"
"#define B --p\n"
"#define C ++*p\n"
"#define D --*p\n"
"#define E putchar(*p)\n"
"#define F *p=getchar()\n"
"#define G while(*p)\n"
"int main(){char*p=malloc(1024*sizeof(char));" );
// Write code to file
for ( char c = *code; c != '\0'; c = *++code ) {
switch ( c ) {
case '>':
fprintf( file, "A;" );
break;
case '<':
fprintf( file, "B;" );
break;
case '+':
fprintf( file, "C;" );
break;
case '-':
fprintf( file, "D;" );
break;
case '.':
fprintf( file, "E;" );
break;
case ',':
fprintf( file, "F;" );
break;
case '[':
fprintf( file, "G{" );
break;
case ']':
fprintf( file, "}" );
break;
default:
break;
}
}
// Write footer and close
fprintf( file, "return 0;}" );
fclose( file );
}
int main( int argc, char* argv[] ) {
if ( argc < 2 ) {
printf( "Usage: %s <input_file> [output_file]\n", argv[0] );
exit( 1 );
}
char* code = read_file( argv[1] );
// Write output to output.c (unless a second argument is given)
generate_output( code, argc >= 3 ? argv[2] : "output.c" );
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment