前回に引き続きbrainf*ckインタプリタです。
今回は完全にC++の勉強用。クラスを使ってみたかっただけのものです。
以下、コード
それに'['の処理のネストが深すぎるのも悩みどころです……
今回は完全にC++の勉強用。クラスを使ってみたかっただけのものです。
以下、コード
#include <iostream>
#include <fstream>
#include <string>
#include <stack>
#define MAX_MEMORY 256
class brainfuckVM
{
private:
unsigned char memory[MAX_MEMORY];
unsigned char *pc;
public:
brainfuckVM(){
memset( memory, 0x00, MAX_MEMORY * sizeof(unsigned char) );
pc = memory;
}
void incValue() { ++(*pc); }
void decValue() { --(*pc); }
void incPointer()
{
if ( pc == &memory[MAX_MEMORY] ) {
std::cerr << "invaild error\n";
exit( 8 );
}
++pc;
}
void decPointer()
{
if ( pc == memory ) {
std::cerr << "invaild error\n";
exit( 8 );
}
--pc;
}
void input( unsigned char ch ){ *pc = ch; }
void output() { std::cout << *pc; }
bool isValue()
{
if ( *pc == 0 ) return false;
else return true;
}
void dumpMemory()
{
int i = 0;
for( pc = memory; i < MAX_MEMORY; ++i, ++pc )
{
printf("%02X ", *pc );
if ( !((i+1) % 16) )
printf( "\n" );
}
}
};
std::stack<int> st;
int main( int argc, char **argv )
{
unsigned char buffer;
int jump_pointer = NULL;
std::ifstream code;
brainfuckVM vm;
if( argc != 2 )
{
std::string filename;
std::getline( std::cin, filename );
code.open( filename.c_str() );
}
else code.open( argv[1] );
if( code.fail() )
{
std::cerr << "file open error\n";
exit( 8 );
}
while( code >> buffer ) std::cout << buffer;
printf( "\n\n" );
code.clear();
code.seekg( 0, std::ios::beg );
while( code >> buffer )
{
switch (buffer) {
case '+':
vm.incValue(); break;
case '-':
vm.decValue(); break;
case '>':
vm.incPointer(); break;
case '<':
vm.decPointer(); break;
case '.':
vm.output(); break;
case ',':
vm.input( static_cast<unsigned char>( getchar() ) );
break;
case ']':
jump_pointer = static_cast<int>( code.tellg() );
code.seekg( st.top() - 1 );
st.pop();
break;
case '[':
st.push( static_cast<int>( code.tellg() ));
if ( jump_pointer == NULL )
{
while ( code >> buffer )
{
if ( buffer == ']' )
{
jump_pointer = static_cast<int>( code.tellg() );
code.seekg( st.top() - 1 );
st.pop();
break;
}
}
if ( code.eof() )
{
std::cerr << "not found ']'\n";
exit( 8 );
}
}
else if ( !vm.isValue() )
{
st.pop();
code.seekg( jump_pointer );
jump_pointer = NULL;
}
break;
default:
break;
}
}
code.close();
printf("\n\n");
vm.dumpMemory();
std::cout << "\nPress Enter...";
getchar();
return 0;
}例外を使ってなかったり同じ記述が複数回出てたりしてますね。反省。それに'['の処理のネストが深すぎるのも悩みどころです……