BrainF**k
某スレにネタがあったので、具象化してみる。
BrainF**kテンプレート。
以下仕様。
BidirectionalIterator1の型は以下の4つの実装が必要、
- operator *(単項演算子)
- operator ++,--(単項演算子)
- operator <<(*BidirectionalIterator1), operator >>(*BidirectionalIterator1)
BidirectionalIterator2の型は、
- char型の+ - > < . , [ ]との比較ができること。
- char型との引き算で0になるときは両者が等しいこと。
とかが必要っぽい。
なんか型の制限が気持悪いので、改造予定。
(生ポインタしか満たさない風味だし。)
#include <iosfwd> template< typename BidirectionalIterator1, typename BidirectionalIterator2, typename CharType, typename CharTraits > //BidirectionalIterator void brainfuck( BidirectionalIterator1 mem_begin, BidirectionalIterator1 mem_end, BidirectionalIterator2 code_begin, BidirectionalIterator2 code_end, std::basic_istream<CharType,CharTraits>& in, std::basic_ostream<CharType,CharTraits>& out ) { BidirectionalIterator1 p = mem_begin; BidirectionalIterator2 ip = code_begin; while(*ip && ip != code_end){ switch(*ip){ case '>' : ++p; break; case '<' : --p; break; case '+' : ++*p; break; case '-' : --*p; break; case '.' : out<<*p; break; case ',' : in >>*p; break; case '[' : if(!*p) for(int c=0; (*ip-']' || --c) && ip != code_end; ++ip) *ip == '[' && ++c; break; case ']' : if(*p) for(int c=0; (*ip-'[' || --c) && ip != code_begin; --ip) *ip == ']' && ++c; break; default : goto bad_command_error; } if(!(mem_begin<=p && p<mem_end)) goto bad_pointer_error; ip++; } return; bad_command_error: out << "\n\n" "invalid code. [" << (*ip) << "]\n"; dump(mem_begin, mem_end, out); return; bad_pointer_error: out << "\n\n" "memory buffer overrun.\n"; dump(mem_begin, mem_end, out); return; } template< typename BidirectionalIterator1, typename CharType, typename CharTraits > void dump( BidirectionalIterator1 mem_begin, BidirectionalIterator1 mem_end, std::basic_ostream<CharType,CharTraits>& out ) { out << "memory dump\n"; for(BidirectionalIterator1 i = mem_begin; i != mem_end; ++i) out << (int)(*i) << ' '; }