#include <stdio.h> #include <stdlib.h> int isvalidchar ( char c ) ; char * loadsrc ( char * filename ) ; size_t srcsize ( FILE * fsrc ) ; void run ( char * code ) ; int main ( int argc , char ** argv ) { if ( argc < 2 || argc > 2 ) { printf ( "Usage: brainfuck sourcefile" ) ; return 0 ; } char * code = loadsrc ( argv [ 1 ] ) ; if ( code != NULL ) run ( code ) ; return 0 ; } void run ( char * code ) { char bfarray [ 9999 ] = { 0 } ; int cp = 0 ; int ap = 0 ; int cpsp = 0 ; int cpstack [ 1000 ] = { 0 } ; while ( code [ cp ] != ' \0 ' ) { if ( code [ cp ] == '+' ) bfarray [ ap ] ++; if ( code [ cp ] == '-' ) bfarray [ ap ] --; if ( code [ cp ] == '.' ) putchar ( bfarray [ ap ] ) ; bfarrayap if ( code [ cp ] == ',' ) [ ap ] = getchar ( ) ; bfarrayap if ( code [ cp ] == '>' ) ap ++; if ( code [ cp ] == '<' ) ap --; if ( code [ cp ] == '[' ) { cpstack [ cpsp ] = cp ; cpsp ++; } if ( code [ cp ] == ']' ) { cpsp --; if ( ! bfarray [ ap ] == 0 ) { cp = cpstack [ cpsp ] ; cp --; } } cp ++; } } char * loadsrc ( char * filename ) { * fsrc = fopen ( filename , "r" ) ; FILEfsrcfilename if ( fsrc == NULL ) return NULL ; char * code = ( char * ) malloc ( srcsize ( fsrc ) ) ; codesrcsizefsrc if ( code == NULL ) { fclose ( fsrc ) ; fsrc return NULL ; } char c = EOF ; int index = 0 ; while ( ( c = fgetc ( fsrc ) ) != EOF ) fsrcEOF if ( ! isvalidchar ( c ) ) code [ index ++ ] = c ; code [ index ] = ' \0 ' ; return code ; } int isvalidchar ( char c ) { if ( c == '.' || c == ',' || c == '>' || c == '<' || c == '[' || c == ']' || c == '+' || c == '-' ) return 0 ; return 1 ; } size_t srcsize ( FILE * fsrc ) { size_t length = 0 ; while ( fgetc ( fsrc ) != EOF ) fsrcEOF length ++; rewind ( fsrc ) ; fsrc return length ; }

I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCmludCBpc3ZhbGlkY2hhcihjaGFyIGMpOwpjaGFyKiBsb2Fkc3JjKGNoYXIgKiBmaWxlbmFtZSk7CnNpemVfdCBzcmNzaXplKEZJTEUgKmZzcmMpOwp2b2lkIHJ1biAoY2hhciAqY29kZSk7CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqKiBhcmd2KQp7CiAgICBpZiAoYXJnYyA8IDIgfHwgYXJnYyA+IDIpewogICAgICAgIHByaW50ZigiVXNhZ2U6IGJyYWluZnVjayBzb3VyY2VmaWxlIik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgY2hhciAqIGNvZGUgPSBsb2Fkc3JjKGFyZ3ZbMV0pOwogICAgaWYgKGNvZGUgIT0gTlVMTCkKICAgIAlydW4oY29kZSk7CgogICAgcmV0dXJuIDA7Cn0KCnZvaWQgcnVuIChjaGFyICpjb2RlKQp7CiAgICBjaGFyIGJmYXJyYXkgWzk5OTldID0gezB9OwogICAgaW50IGNwID0gMDsKICAgIGludCBhcCA9IDA7CiAgICBpbnQgY3BzcD0gMDsKICAgIGludCBjcHN0YWNrWzEwMDBdID0gezB9OwoKICAgIHdoaWxlIChjb2RlW2NwXSAhPSAnXDAnKXsKCiAgICAgICAgICAgIGlmKGNvZGVbY3BdID09ICcrJykKICAgICAgICAgICAgICAgIGJmYXJyYXlbYXBdKys7CgogICAgICAgICAgICBpZihjb2RlW2NwXT09ICctJykKICAgICAgICAgICAgICAgIGJmYXJyYXlbYXBdLS07CgogICAgICAgICAgICBpZihjb2RlW2NwXSA9PSAnLicpCiAgICAgICAgICAgICAgICBwdXRjaGFyKGJmYXJyYXlbYXBdKTsKCiAgICAgICAgICAgIGlmKGNvZGVbY3BdID09ICcsJykKICAgICAgICAgICAgICAgIGJmYXJyYXlbYXBdID0gZ2V0Y2hhcigpOwoKICAgICAgICAgICAgaWYoY29kZSBbY3BdID09ICc+JykKICAgICAgICAgICAgICAgIGFwKys7CgogICAgICAgICAgICBpZihjb2RlW2NwXSA9PSAnPCcpCiAgICAgICAgICAgICAgICBhcC0tOwoKICAgICAgICAgICAgaWYoY29kZVtjcF0gPT0gJ1snKXsKICAgICAgICAgICAgICAgIGNwc3RhY2tbY3BzcF0gPSBjcDsKICAgICAgICAgICAgICAgIGNwc3ArKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoY29kZVtjcF0gPT0gJ10nKXsKICAgICAgICAgICAgICAgIGNwc3AtLTsKICAgICAgICAgICAgICAgIGlmKCFiZmFycmF5W2FwXSA9PSAwKXsKICAgICAgICAgICAgICAgICAgICBjcCA9IGNwc3RhY2tbY3BzcF07CiAgICAgICAgICAgICAgICAgICAgY3AtLTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjcCsrOwogICAgfQp9CgpjaGFyKiBsb2Fkc3JjKGNoYXIgKiBmaWxlbmFtZSkKewogICAgRklMRSAqIGZzcmMgPSBmb3BlbihmaWxlbmFtZSwgInIiKTsKICAgIGlmKGZzcmMgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIGNoYXIgKiBjb2RlID0gKGNoYXIqKSBtYWxsb2Moc3Jjc2l6ZShmc3JjKSk7CiAgICBpZiAoY29kZSA9PSBOVUxMKXsKICAgICAgICBmY2xvc2UoZnNyYyk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBjaGFyIGMgPSBFT0Y7CiAgICBpbnQgaW5kZXggPSAwOwogICAgd2hpbGUoKGM9IGZnZXRjKGZzcmMpKSAhPSBFT0YpCiAgICAgICAgaWYgKCFpc3ZhbGlkY2hhcihjKSkKICAgICAgICAgICAgY29kZVtpbmRleCsrXSA9IGM7CiAgICBjb2RlW2luZGV4XSA9ICdcMCc7CnJldHVybiBjb2RlOwoKfQoKaW50IGlzdmFsaWRjaGFyKGNoYXIgYykKewogICAgaWYoYyA9PSAnLicgfHwgYyA9PSAnLCcgfHwKICAgICAgIGMgPT0gJz4nIHx8IGMgPT0gJzwnIHx8CiAgICAgICBjID09ICdbJyB8fCBjID09ICddJyB8fAogICAgICAgYyA9PSAnKycgfHwgYyA9PSAnLScpCiAgICAgICByZXR1cm4gMDsKCiAgICByZXR1cm4gMTsKfQoKc2l6ZV90IHNyY3NpemUoRklMRSAqZnNyYykKewogICAgc2l6ZV90IGxlbmd0aD0gMDsKICAgIHdoaWxlKGZnZXRjKGZzcmMpICE9IEVPRikKICAgICAgICBsZW5ndGgrKzsKICAgIHJld2luZChmc3JjKTsKICAgIHJldHVybiBsZW5ndGg7Cn0=