diff --git a/ddx/cow.cpp b/ddx/cow.cpp index 8d7429b..6039f13 100644 --- a/ddx/cow.cpp +++ b/ddx/cow.cpp @@ -11,6 +11,22 @@ //-------------------------------------------- #include #include +#include +#include + +template +inline void apply_all_stomachs_impl( Fn&& fn ) +{ + fn( I ); + if constexpr( I + 1 < N ) + apply_all_stomachs_impl( (Fn&&)fn ); +} + +template +inline void apply_all_stomachs( Fn&& fn ) +{ + apply_all_stomachs_impl<0, N>( (Fn&&)fn ); +} int const num_stomachs = 7; @@ -211,21 +227,19 @@ bool exec( int instruction ) // Oom case 14: { - for( int i=0; i( [&]( int i ) { if( mem_poses[i] == memory[i].begin() ) quit( true ); else mem_poses[i]--; - } + } ); break; } // oOm case 15: { - for( int i=0; i( [&]( int i ) { mem_poses[i]++; if( mem_poses[i] == memory[i].end() ) { @@ -233,37 +247,34 @@ bool exec( int instruction ) mem_poses[i] = memory[i].end(); mem_poses[i]--; } - } + } ); break; } // OoM case 16: { - for( int i=0; i( [&]( int i ) { (*mem_poses[i])--; - } + } ); break; } // oOM case 17: { - for( int i=0; i( [&]( int i ) { (*mem_poses[i])++; - } + } ); break; } // ooo case 18: { - for( int i=0; i( [&]( int i ) { (*mem_poses[i]) = 0; - } + } ); break; } @@ -421,4 +432,3 @@ int main( int argc, char** argv ) return 0; } - diff --git a/source/cow.cpp b/source/cow.cpp index 1ec58e8..c6d2f03 100644 --- a/source/cow.cpp +++ b/source/cow.cpp @@ -9,12 +9,16 @@ #include #include #include +#include +typedef std::uint8_t instruction_t; +typedef std::vector program_t; typedef std::vector mem_t; -mem_t program; + +program_t program; +std::vector jump_table; mem_t memory; -mem_t::iterator mem_pos; -mem_t::iterator prog_pos; +size_t mem_pos = 0; int register_val; bool has_register_val = false; @@ -26,231 +30,325 @@ void quit( bool error ) printf( "\nERROR!\n" ); exit(1); } - + #ifndef NO_GREETINGS printf( "\nDone.\n" ); #endif exit(0); } -bool exec( int instruction ) +int decode_instruction( const char* token ) { -// printf( "EXEC: %d\n", instruction ); - - switch( instruction ) + switch( token[0] ) { - // moo - case 0: - { - if( prog_pos == program.begin() ) - quit( true ); + case 'm': + if( token[1] == 'o' && token[2] == 'o' ) return 0; + if( token[1] == 'O' && token[2] == 'o' ) return 1; + if( token[1] == 'o' && token[2] == 'O' ) return 2; + if( token[1] == 'O' && token[2] == 'O' ) return 3; + break; + case 'M': + if( token[1] == 'o' && token[2] == 'o' ) return 4; + if( token[1] == 'O' && token[2] == 'o' ) return 5; + if( token[1] == 'o' && token[2] == 'O' ) return 6; + if( token[1] == 'O' && token[2] == 'O' ) return 7; + if( token[1] == 'M' && token[2] == 'M' ) return 9; + break; + case 'O': + if( token[1] == 'O' && token[2] == 'O' ) return 8; + if( token[1] == 'O' && token[2] == 'M' ) return 10; + break; + case 'o': + if( token[1] == 'o' && token[2] == 'm' ) return 11; + break; + }; - prog_pos--; // skip previous command. - int level = 1; - while( level > 0 ) - { - if( prog_pos == program.begin() ) - break; + return -1; +} - prog_pos--; - - if( (*prog_pos) == 0 ) - level++; - else - if( (*prog_pos) == 7 ) // look for MOO - level--; - } +void execute_program( long long max_steps ) +{ + const instruction_t* prog = program.data(); + const int program_size = (int)program.size(); + int pc = 0; + long long steps = 0; + +#if defined(__GNUC__) || defined(__clang__) + static void* dispatch[] = { + &&op_moo, &&op_mOo, &&op_moO, &&op_mOO, + &&op_Moo, &&op_MOo, &&op_MoO, &&op_MOO, + &&op_OOO, &&op_MMM, &&op_OOM, &&op_oom + }; + if( program_size == 0 ) return; + instruction_t instruction = prog[pc]; - if( level != 0 ) - quit(true); + while( pc < program_size ) + { + if( max_steps > 0 && ++steps > max_steps ) + quit( true ); + if( instruction >= 12 ) + quit( false ); + goto *dispatch[instruction]; - return exec( *prog_pos ); - } - - // mOo - case 1: - if( mem_pos == memory.begin() ) +op_moo: + if( pc == 0 || jump_table[pc] < 0 ) quit( true ); - else - mem_pos--; - break; + pc = jump_table[pc]; + instruction = prog[pc]; + continue; - // moO - case 2: - mem_pos++; - if( mem_pos == memory.end() ) - { - memory.push_back(0); - mem_pos = memory.end(); - mem_pos--; - } - break; - - // mOO - case 3: - if( (*mem_pos) == 3 ) +op_mOo: + if( mem_pos == 0 ) + quit( true ); + --mem_pos; + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; + +op_moO: + ++mem_pos; + if( mem_pos == memory.size() ) + memory.push_back( 0 ); + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; + +op_mOO: + if( memory[mem_pos] == 3 ) + quit( false ); + if( memory[mem_pos] < 0 || memory[mem_pos] > 11 ) quit( false ); - return exec(*mem_pos); - - // Moo - case 4: - if( (*mem_pos) != 0 ) - printf( "%c", *mem_pos ); + instruction = (instruction_t)memory[mem_pos]; + continue; + +op_Moo: + if( memory[mem_pos] != 0 ) + printf( "%c", memory[mem_pos] ); else { - (*mem_pos) = getchar(); + memory[mem_pos] = getchar(); while( getchar() != '\n' ); } - break; - - // MOo - case 5: - (*mem_pos)--; - break; - - // MoO - case 6: - (*mem_pos)++; - break; - - // MOO - case 7: - if( (*mem_pos) == 0 ) + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; + +op_MOo: + memory[mem_pos]--; + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; + +op_MoO: + memory[mem_pos]++; + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; + +op_MOO: + if( memory[mem_pos] == 0 ) { - int level = 1; - int prev = 0; - prog_pos++; // have to skip past next command when looking for next moo. - if( prog_pos == program.end() ) - break; - while( level > 0 ) - { - prev = *prog_pos; - prog_pos++; - - if( prog_pos == program.end() ) - break; - - if( (*prog_pos) == 7 ) - level++; - else - if( (*prog_pos) == 0 ) // look for moo command. - { - level--; - if( prev == 7 ) - level--; - } - } - if( level != 0 ) + if( jump_table[pc] < 0 ) quit( true ); + pc = jump_table[pc]; } - break; - - // OOO - case 8: - (*mem_pos) = 0; - break; + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; + +op_OOO: + memory[mem_pos] = 0; + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; - // MMM - case 9: +op_MMM: if( has_register_val ) - (*mem_pos) = register_val; + memory[mem_pos] = register_val; else - register_val = (*mem_pos); + register_val = memory[mem_pos]; has_register_val = !has_register_val; - break; + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; - // OOM - case 10: - printf( "%d\n", *mem_pos ); - break; - - // oom - case 11: +op_OOM: + printf( "%d\n", memory[mem_pos] ); + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; + +op_oom: { char buf[100]; int c = 0; - while( c < sizeof(buf)-1 ) + while( c < (int)sizeof(buf)-1 ) { buf[c] = getchar(); c++; buf[c] = 0; - + if( buf[c-1] == '\n' ) break; } - // swallow, just in case. - if( c == sizeof(buf) ) + if( c == (int)sizeof(buf) ) while( getchar() != '\n' ); - - (*mem_pos) = atoi( buf ); - break; + memory[mem_pos] = atoi( buf ); + ++pc; + if( pc < program_size ) instruction = prog[pc]; + continue; } + } +#else + while( pc < program_size ) + { + if( max_steps > 0 && ++steps > max_steps ) + quit( true ); - // bad stuff - default: - quit( false ); - }; - - prog_pos++; + int instruction = prog[pc]; + bool redispatch = true; - return true; + while( redispatch ) + { + redispatch = false; + switch( instruction ) + { + case 0: + if( pc == 0 || jump_table[pc] < 0 ) + quit( true ); + pc = jump_table[pc]; + instruction = prog[pc]; + redispatch = true; + break; + case 1: + if( mem_pos == 0 ) + quit( true ); + --mem_pos; + ++pc; + break; + case 2: + ++mem_pos; + if( mem_pos == memory.size() ) + memory.push_back( 0 ); + ++pc; + break; + case 3: + if( memory[mem_pos] == 3 ) + quit( false ); + if( memory[mem_pos] < 0 || memory[mem_pos] > 11 ) + quit( false ); + instruction = memory[mem_pos]; + redispatch = true; + break; + case 4: + if( memory[mem_pos] != 0 ) + printf( "%c", memory[mem_pos] ); + else + { + memory[mem_pos] = getchar(); + while( getchar() != '\n' ); + } + ++pc; + break; + case 5: + memory[mem_pos]--; + ++pc; + break; + case 6: + memory[mem_pos]++; + ++pc; + break; + case 7: + if( memory[mem_pos] == 0 ) + { + if( jump_table[pc] < 0 ) + quit( true ); + pc = jump_table[pc]; + } + ++pc; + break; + case 8: + memory[mem_pos] = 0; + ++pc; + break; + case 9: + if( has_register_val ) + memory[mem_pos] = register_val; + else + register_val = memory[mem_pos]; + has_register_val = !has_register_val; + ++pc; + break; + case 10: + printf( "%d\n", memory[mem_pos] ); + ++pc; + break; + case 11: + { + char buf[100]; + int c = 0; + while( c < (int)sizeof(buf)-1 ) + { + buf[c] = getchar(); + c++; + buf[c] = 0; + + if( buf[c-1] == '\n' ) + break; + } + if( c == (int)sizeof(buf) ) + while( getchar() != '\n' ); + + memory[mem_pos] = atoi( buf ); + ++pc; + break; + } + default: + quit( false ); + } + } + } +#endif } - int main( int argc, char** argv ) { - if( argc < 2 ) - { - printf( "Usage: %s program.cow\n\n", argv[0] ); - exit( 1 ); - } + if( argc < 2 ) + { + printf( "Usage: %s program.cow\n\n", argv[0] ); + exit( 1 ); + } - FILE* f = fopen( argv[1], "rb" ); + FILE* f = fopen( argv[1], "rb" ); - if( f == NULL ) - { - printf( "Cannot open source file [%s].\n", argv[1] ); + if( f == NULL ) + { + printf( "Cannot open source file [%s].\n", argv[1] ); exit( 1 ); - } + } + + fseek( f, 0, SEEK_END ); + const long size = ftell( f ); + rewind( f ); - char buf[3]; - memset( buf, 0, 3 ); - int pos = 0; + std::vector source( size > 0 ? (size_t)size : 0 ); + if( !source.empty() ) + { + const size_t bytes_read = fread( &source[0], 1, source.size(), f ); + source.resize( bytes_read ); + } - while( !feof(f) ) + char buf[3] = {0,0,0}; + for( size_t i = 0; i < source.size(); ++i ) { - int found = 0; - buf[2] = fgetc( f ); - - if( found = !strncmp( "moo", buf, 3 ) ) - program.push_back( 0 ); - else if( found = !strncmp( "mOo", buf, 3 ) ) - program.push_back( 1 ); - else if( found = !strncmp( "moO", buf, 3 ) ) - program.push_back( 2 ); - else if( found = !strncmp( "mOO", buf, 3 ) ) - program.push_back( 3 ); - else if( found = !strncmp( "Moo", buf, 3 ) ) - program.push_back( 4 ); - else if( found = !strncmp( "MOo", buf, 3 ) ) - program.push_back( 5 ); - else if( found = !strncmp( "MoO", buf, 3 ) ) - program.push_back( 6 ); - else if( found = !strncmp( "MOO", buf, 3 ) ) - program.push_back( 7 ); - else if( found = !strncmp( "OOO", buf, 3 ) ) - program.push_back( 8 ); - else if( found = !strncmp( "MMM", buf, 3 ) ) - program.push_back( 9 ); - else if( found = !strncmp( "OOM", buf, 3 ) ) - program.push_back( 10 ); - else if( found = !strncmp( "oom", buf, 3 ) ) - program.push_back( 11 ); - - if( found ) + buf[2] = source[i]; + const int instruction = decode_instruction( buf ); + + if( instruction >= 0 ) { - memset( buf, 0, 3 ); + program.push_back( (instruction_t)instruction ); + memset( buf, 0, sizeof(buf) ); } else { @@ -260,24 +358,41 @@ int main( int argc, char** argv ) } } - fclose( f ); + fclose( f ); #ifndef NO_GREETINGS - printf( "Welcome to COW!\n\nExecuting [%s]...\n\n", argv[1] ); + printf( "Welcome to COW!\n\nExecuting [%s]...\n\n", argv[1] ); #endif - // init main memory. + jump_table.assign( program.size(), -1 ); + std::vector stack; + for( size_t i = 0; i < program.size(); ++i ) + { + if( program[i] == 7 ) + stack.push_back( i ); + else if( program[i] == 0 ) + { + if( stack.empty() ) + quit( true ); + + const size_t open = stack.back(); + stack.pop_back(); + jump_table[open] = (int)i; + jump_table[i] = (int)open; + } + } + if( !stack.empty() ) + quit( true ); + + memory.reserve( 1024 ); memory.push_back( 0 ); - mem_pos = memory.begin(); - prog_pos = program.begin(); - while( prog_pos != program.end() ) - if( !exec( *prog_pos ) ) - break; + long long max_steps = 0; + if( const char* max_steps_env = getenv( "COW_MAX_STEPS" ) ) + max_steps = atoll( max_steps_env ); + execute_program( max_steps ); quit( false ); - return 0; + return 0; } - - diff --git a/source/cowcomp.cpp b/source/cowcomp.cpp index 7a958a1..18dcfec 100644 --- a/source/cowcomp.cpp +++ b/source/cowcomp.cpp @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #define COMPILER "g++" #define FLAGS "-O3 -x c++" @@ -17,14 +20,15 @@ #define OUTPUT_CPP "cow.out.cpp" -//#define PRETTY(s) fprintf( output, "\t\t\t// %s\n", s ); +//#define PRETTY(s) emit( "\t\t\t// %s\n", s ); #define PRETTY(s) -typedef std::vector mem_t; +typedef std::uint8_t instruction_t; +typedef std::vector mem_t; mem_t program; mem_t::iterator prog_pos; -FILE* output; +std::string output; int moocount(0); int MOOcount(0); @@ -36,6 +40,59 @@ void quit() exit(1); } +void emit( const char* fmt, ... ) +{ + char local[512]; + va_list args; + va_start( args, fmt ); + int n = vsnprintf( local, sizeof(local), fmt, args ); + va_end( args ); + + if( n <= 0 ) + return; + + if( n < (int)sizeof(local) ) + { + output.append( local, (size_t)n ); + return; + } + + std::vector dynamic_buf( (size_t)n + 1 ); + va_start( args, fmt ); + vsnprintf( &dynamic_buf[0], dynamic_buf.size(), fmt, args ); + va_end( args ); + output.append( &dynamic_buf[0], (size_t)n ); +} + +int decode_instruction( const char* token ) +{ + switch( token[0] ) + { + case 'm': + if( token[1] == 'o' && token[2] == 'o' ) return 0; + if( token[1] == 'O' && token[2] == 'o' ) return 1; + if( token[1] == 'o' && token[2] == 'O' ) return 2; + if( token[1] == 'O' && token[2] == 'O' ) return 3; + break; + case 'M': + if( token[1] == 'o' && token[2] == 'o' ) return 4; + if( token[1] == 'O' && token[2] == 'o' ) return 5; + if( token[1] == 'o' && token[2] == 'O' ) return 6; + if( token[1] == 'O' && token[2] == 'O' ) return 7; + if( token[1] == 'M' && token[2] == 'M' ) return 9; + break; + case 'O': + if( token[1] == 'O' && token[2] == 'O' ) return 8; + if( token[1] == 'O' && token[2] == 'M' ) return 10; + break; + case 'o': + if( token[1] == 'o' && token[2] == 'm' ) return 11; + break; + }; + + return -1; +} + bool compile( int instruction, bool advance ) { switch( instruction ) @@ -74,13 +131,13 @@ bool compile( int instruction, bool advance ) quit(); else if( level != 0 ) { - fprintf( output, "rterr();" ); + emit( "rterr();" ); break; } moocount++; - fprintf( output, "goto M%d;", num ); - fprintf( output, "m%d:", moocount ); + emit( "goto M%d;", num ); + emit( "m%d:", moocount ); PRETTY( "moo" ); } break; @@ -88,13 +145,13 @@ bool compile( int instruction, bool advance ) // mOo case 1: - fprintf( output, "if(p==m.begin()){rterr();}else{p--;}" ); + emit( "if(p==m.begin()){rterr();}else{p--;}" ); PRETTY( "mOo" ); break; // moO case 2: - fprintf( output, "p++; if(p==m.end()){m.push_back(0);p=m.end();p--;}" ); + emit( "p++; if(p==m.end()){m.push_back(0);p=m.end();p--;}" ); PRETTY( "moO" ); break; @@ -104,37 +161,37 @@ bool compile( int instruction, bool advance ) // use the compile function itself to fill in the possibilities. // printf( "NOT IMPLEMENTED: mOO\n\n" ); // quit(); - fprintf( output, "switch(*p){" ); - fprintf( output, "case 0:{" ); compile( 0, false ); fprintf( output, "}break;" ); - fprintf( output, "case 1:{" ); compile( 1, false ); fprintf( output, "}break;" ); - fprintf( output, "case 2:{" ); compile( 2, false ); fprintf( output, "}break;" ); - fprintf( output, "case 4:{" ); compile( 4, false ); fprintf( output, "}break;" ); - fprintf( output, "case 5:{" ); compile( 5, false ); fprintf( output, "}break;" ); - fprintf( output, "case 6:{" ); compile( 6, false ); fprintf( output, "}break;" ); - fprintf( output, "case 7:{" ); compile( 7, false ); fprintf( output, "}break;" ); - fprintf( output, "case 8:{" ); compile( 8, false ); fprintf( output, "}break;" ); - fprintf( output, "case 9:{" ); compile( 9, false ); fprintf( output, "}break;" ); - fprintf( output, "case 10:{" ); compile( 10, false ); fprintf( output, "}break;" ); - fprintf( output, "case 11:{" ); compile( 11, false ); fprintf( output, "}break;" ); - fprintf( output, "default:{goto x;}};" ); + emit( "switch(*p){" ); + emit( "case 0:{" ); compile( 0, false ); emit( "}break;" ); + emit( "case 1:{" ); compile( 1, false ); emit( "}break;" ); + emit( "case 2:{" ); compile( 2, false ); emit( "}break;" ); + emit( "case 4:{" ); compile( 4, false ); emit( "}break;" ); + emit( "case 5:{" ); compile( 5, false ); emit( "}break;" ); + emit( "case 6:{" ); compile( 6, false ); emit( "}break;" ); + emit( "case 7:{" ); compile( 7, false ); emit( "}break;" ); + emit( "case 8:{" ); compile( 8, false ); emit( "}break;" ); + emit( "case 9:{" ); compile( 9, false ); emit( "}break;" ); + emit( "case 10:{" ); compile( 10, false ); emit( "}break;" ); + emit( "case 11:{" ); compile( 11, false ); emit( "}break;" ); + emit( "default:{goto x;}};" ); PRETTY( "mOO" ); break; // Moo case 4: - fprintf( output, "if((*p)!=0){putchar(*p);}else{(*p)=getchar();while(getchar()!='\\n');}" ); + emit( "if((*p)!=0){putchar(*p);}else{(*p)=getchar();while(getchar()!='\\n');}" ); PRETTY( "Moo" ); break; // MOo case 5: - fprintf( output, "(*p)--;" ); + emit( "(*p)--;" ); PRETTY( "MOo" ); break; // MoO case 6: - fprintf( output, "(*p)++;" ); + emit( "(*p)++;" ); PRETTY( "MoO" ); break; @@ -180,40 +237,40 @@ bool compile( int instruction, bool advance ) quit(); else if( level != 0 ) { - fprintf( output, "rterr();" ); + emit( "rterr();" ); break; } MOOcount++; - fprintf( output, "M%d:", MOOcount ); - fprintf( output, "if(!(*p))goto m%d;", num ); + emit( "M%d:", MOOcount ); + emit( "if(!(*p))goto m%d;", num ); PRETTY( "MOO" ); } break; // OOO case 8: - fprintf( output, "(*p)=0;" ); + emit( "(*p)=0;" ); PRETTY( "OOO" ); break; // MMM case 9: - fprintf( output, "if(h){(*p)=r;}else{r=(*p);}h=!h;" ); + emit( "if(h){(*p)=r;}else{r=(*p);}h=!h;" ); PRETTY( "MMM" ); break; // OOM case 10: - fprintf( output, "printf(\"%%d\\n\",*p);" ); + emit( "printf(\"%%d\\n\",*p);" ); PRETTY( "OOM" ); break; // oom case 11: - fprintf( output, "char b[100];int c=0;" ); - fprintf( output, "while(c source( size > 0 ? (size_t)size : 0 ); + if( !source.empty() ) { - int found = 0; - buf[2] = fgetc( f ); - - if( found = !strncmp( "moo", buf, 3 ) ) - program.push_back( 0 ); - else if( found = !strncmp( "mOo", buf, 3 ) ) - program.push_back( 1 ); - else if( found = !strncmp( "moO", buf, 3 ) ) - program.push_back( 2 ); - else if( found = !strncmp( "mOO", buf, 3 ) ) - program.push_back( 3 ); - else if( found = !strncmp( "Moo", buf, 3 ) ) - program.push_back( 4 ); - else if( found = !strncmp( "MOo", buf, 3 ) ) - program.push_back( 5 ); - else if( found = !strncmp( "MoO", buf, 3 ) ) - program.push_back( 6 ); - else if( found = !strncmp( "MOO", buf, 3 ) ) - program.push_back( 7 ); - else if( found = !strncmp( "OOO", buf, 3 ) ) - program.push_back( 8 ); - else if( found = !strncmp( "MMM", buf, 3 ) ) - program.push_back( 9 ); - else if( found = !strncmp( "OOM", buf, 3 ) ) - program.push_back( 10 ); - else if( found = !strncmp( "oom", buf, 3 ) ) - program.push_back( 11 ); - - if( found ) + const size_t bytes_read = fread( &source[0], 1, source.size(), f ); + source.resize( bytes_read ); + } + + char buf[3] = {0,0,0}; + for( size_t i = 0; i < source.size(); ++i ) + { + buf[2] = source[i]; + const int instruction = decode_instruction( buf ); + + if( instruction >= 0 ) { - memset( buf, 0, 3 ); + program.push_back( (instruction_t)instruction ); + memset( buf, 0, sizeof(buf) ); } else { @@ -301,14 +342,15 @@ int main( int argc, char** argv ) mem_pos = memory.begin(); */ - output = fopen( "cow.out.cpp", "wb" ); - fprintf( output, "#include \n" ); - fprintf( output, "#include \n" ); - fprintf( output, "typedef std::vector t_;t_ m;t_::iterator p;\n" ); - fprintf( output, "bool h;int r;\n" ); - fprintf( output, "void rterr(){puts(\"Runtime error.\\n\");}\n" ); - fprintf( output, "int main(int a,char** v){\n" ); - fprintf( output, "m.push_back(0);p=m.begin();h=false;\n" ); + output.clear(); + output.reserve( 64 * 1024 ); + emit( "#include \n" ); + emit( "#include \n" ); + emit( "typedef std::vector t_;t_ m;t_::iterator p;\n" ); + emit( "bool h;int r;\n" ); + emit( "void rterr(){puts(\"Runtime error.\\n\");}\n" ); + emit( "int main(int a,char** v){\n" ); + emit( "m.push_back(0);p=m.begin();h=false;\n" ); prog_pos = program.begin(); while( prog_pos != program.end() ) @@ -318,8 +360,16 @@ int main( int argc, char** argv ) break; } - fprintf( output, "x:return(0);}\n" ); - fclose( output ); + emit( "x:return(0);}\n" ); + + FILE* out_file = fopen( "cow.out.cpp", "wb" ); + if( out_file == NULL ) + { + printf( "Could not write output file.\n" ); + exit( 1 ); + } + fwrite( output.data(), 1, output.size(), out_file ); + fclose( out_file ); printf( "C++ source code: cow.out.cpp\n" ); @@ -342,4 +392,3 @@ int main( int argc, char** argv ) return 0; } -