Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- brainfuck compiler in C
- This code outputs C code, that can be fed into a C compiler.
- Both, this code and its output compile with the -pedantic and -ansi setting.
- */
- #define NORMAL 0
- #define OPTIMIZE 1
- #define FILTER 2
- /*
- NOTE
- "\n" is usually automatically replaced with "\r\n" in Windows.
- If it is not (and your output is fucked up), switch the commented define statement below.
- This only affects readability of the generated code. With \r\n it looks fine in the console,
- because it discards \r, but files will have double line breaks in them.
- */
- #ifdef _WIN32
- /*#define LE "\r\n"*/
- #define LE "\n"
- #else
- #define LE "\n"
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- /*shows the help text*/
- void help();
- /*counts, how many identical chars follow*/
- int howmany(char*,int);
- int main(int argc,char* argv[])
- {
- int c,i,j;
- int size;
- int numc=0;
- int ident=0;
- int optimize=0;
- char* mem;
- FILE* bf;
- if(argc==2 || argc==3)
- {
- if(argc==3)
- {
- /*primitive argument checking without string.h*/
- if((argv[2][0]=='/' || argv[2][0]=='-') && (argv[2][2]=='\0'))
- {
- switch(argv[2][1])
- {
- /*optimization*/
- case 'O':
- case 'o':
- optimize=OPTIMIZE;
- break;
- /*only filter code*/
- case 'F':
- case 'f':
- optimize=FILTER;
- break;
- /*displays help (undocumented, but user might try it)*/
- case '?':
- help();
- return 1;
- /*err*/
- default:
- printf("Invalid argument: %s"LE,argv[2]);
- help();
- return 1;
- }
- }
- else
- {
- printf("Error parsing argument: %s"LE,argv[2]);
- help();
- return 1;
- }
- }
- /*read entire file, but process only valid chars*/
- bf=fopen(argv[1],"rb");
- if(bf!=NULL)
- {
- fseek(bf,0L,SEEK_END);
- size=ftell(bf);
- fseek(bf,0L,SEEK_SET);
- mem=malloc(size+1);
- do
- {
- c=fgetc(bf);
- switch(c)
- {
- case '.':
- case ',':
- case '+':
- case '-':
- case '[':
- case ']':
- case '<':
- case '>':
- mem[numc++]=c;
- break;
- default:
- break;
- }
- }while(c!=EOF);
- fclose(bf);
- /*reduce memory to number of brainfuck chars and add 0 padding*/
- mem=realloc(mem,numc+2);
- mem[numc]=mem[numc+1]='\0';
- /*if filtering only, just print the mem array*/
- if(optimize==FILTER)
- {
- printf("%s"LE,mem);
- }
- else
- {
- /*print C code*/
- printf(
- "/*Generated using bfc by AyrA*/"LE
- LE
- "#define MEMSIZE 30000"LE
- "#include <string.h>"LE
- "#include <stdio.h>"LE
- "#include <conio.h>"LE
- LE
- "char get(){"LE
- " int c=getch();"LE
- " return c==27?0:(char)c;"LE
- "}"LE
- ""LE
- "int main(){"LE
- " char mem[MEMSIZE];"LE
- " int ptr=0;"LE
- " memset(mem,0,MEMSIZE);"LE);
- size=1;
- for(i=0;i<numc;i++)
- {
- /*only scan in advance, if we are optimizing the code*/
- if(optimize==OPTIMIZE)
- {
- size=howmany(mem,i);
- }
- /*nice indent of code*/
- for(j=0;j<ident;j++)
- {
- printf(" ");
- }
- /*
- print C code according to brainfuck symbol
- optimize if specified by the user
- */
- switch(mem[i])
- {
- case '.':
- printf(" putchar(mem[ptr]);"LE);
- break;
- case ',':
- printf(" mem[ptr]=get();"LE);
- break;
- case '+':
- if(size>1 && optimize==OPTIMIZE)
- {
- printf(" mem[ptr]+=%i;"LE,size);
- i+=size-1;
- }
- else
- {
- printf(" ++mem[ptr];"LE);
- }
- break;
- case '-':
- if(size>1 && optimize==OPTIMIZE)
- {
- printf(" mem[ptr]-=%i;"LE,size);
- i+=size-1;
- }
- else
- {
- printf(" --mem[ptr];"LE);
- }
- break;
- case '[':
- if((mem[i+1]=='+' || mem[i+1]=='-') && mem[i+2]==']' && optimize==OPTIMIZE)
- {
- printf(" mem[ptr]=0;"LE);
- i+=2;
- }
- else
- {
- printf(" while(mem[ptr]){"LE);
- ++ident;
- }
- break;
- case ']':
- printf("}"LE);
- --ident;
- break;
- case '<':
- if(size>1 && optimize==OPTIMIZE)
- {
- printf(" ptr-=%i;"LE,size);
- i+=size-1;
- }
- else
- {
- printf(" --ptr;"LE);
- }
- break;
- case '>':
- if(size>1 && optimize==OPTIMIZE)
- {
- printf(" ptr+=%i;"LE,size);
- i+=size-1;
- }
- else
- {
- printf(" ++ptr;"LE);
- }
- break;
- }
- }
- printf(" return mem[ptr];"LE"}"LE);
- free(mem);
- }
- }
- else
- {
- fprintf(stderr,"Cannot open %s for reading"LE,argv[1]);
- return 1;
- }
- }
- else
- {
- help();
- return 1;
- }
- return 0;
- }
- /*
- counts how many chars are identical to the one in start position.
- includes the start char as well*/
- int howmany(char* chars, int start)
- {
- char c=chars[start];
- int count=1;
- while(c==chars[++start])
- {
- ++count;
- }
- return count;
- }
- /*
- display help text
- This is called when the user gives
- */
- void help()
- {
- printf(
- "Brainfuck compiler"LE
- "=================="LE
- "bfc.exe <filename> [-o | -f]"LE
- "filename: Name of brainfuck file to compile into C code"LE
- "/o Optimizes code"LE
- "/f Prints filtered brainfuck instead of C code"LE
- " This removes all non-brainfuck chars from the code"LE);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement