// Emulator of Subleq language (and its derivatives) // Oleg Mazonka, 10 Nov 2006, 19 Jan 2009 // addleq 22 Sept 2009 // p1eq 28 Sept 2009 #include #include #include #include #include #include using namespace std; struct Mem { vector v; int & operator[](int i); int size(){ return v.size(); } void dump(); }; void Mem::dump() { for( int i=0; i=v.size() ) v.resize(i+1,0); return v[i]; } Mem mem; string sout="OUT", sin="IN"; int iout=-1, iin=-1; enum { IOCHAR, IOINT } io_type = IOCHAR; int ip=0; bool addleq=false; bool p1eq=false; bool loadfrom(istream &in) { while(1) { string s; in>>s; if( !in ) break; if( s.size() < 1 ) break; if( s[0]=='#' ) { if( s.size()==sout.size()+1 && s.substr(1)==sout ) mem[ip++] = iout; else if( s.size()==sin.size()+1 && s.substr(1)==sin ) mem[ip++] = iin; else { cerr<<"Unresolved register "<9 && s.substr(1,8)=="outname=" ) sout = s.substr(9); else if( s.size()>9 && s.substr(1,8)=="outaddr=" ) iout = atoi(s.substr(9).c_str()); else if( s.size()>8 && s.substr(1,7)=="inname=" ) sin = s.substr(8); else if( s.size()>8 && s.substr(1,7)=="inaddr=" ) iin = atoi(s.substr(8).c_str()); else if( s.size()==6 && s.substr(1,5)=="trace" ) trace=true; else if( s.size()==6 && s.substr(1,5)=="steps" ) steps=true; else if( s.size()==6 && s.substr(1,5)=="stdin" ) bcin=true; else if( s.size()==2 && s.substr(1,1)=="a" ) addleq=true; else if( s.size()==2 && s.substr(1,1)=="p" ) p1eq=true; else if( s.size()==9 && s.substr(1,6)=="iotype" ) { if( s[8] == 'c' ) io_type = IOCHAR; if( s[8] == 'i' ) io_type = IOINT; } else { cerr<<"Unknown option ["<>x; if(cin)cout<>x; if( !p1eq ) { if(cin) mem[b] += x; else mem[b] -= 1; if( mem[b]<=0 ) ip=c; } else { if( mem[b] == x ) ip=c; mem[b] = x; } if( trace ) cout<<" \tinput [b]="<