diff --git a/brainfuck/brainfuck.hpp b/brainfuck/brainfuck.hpp new file mode 100644 index 0000000..187826d --- /dev/null +++ b/brainfuck/brainfuck.hpp @@ -0,0 +1,65 @@ +#include +#include +#include + +/** + T is the memory-type (normally bytes aka char) + OutputIterator is where to write (normally cout) +*/ + +namespace brainfuck_details { + +// recursive funtion (from http://www.xs4all.nl/~weegen/eelis/geordi/) but templated +template +void b(char * c, InputIterator& in, T * & p, OutputIterator out){ + for(; *c&&*c!=']'; ++c) { + (*((p+=*c=='>')-=*c=='<')+=*c=='+') -=*c=='-'; + if(*c=='.') *out++ = *p; + if(*c==',') *p = *in++; + if(*c=='[') { + for(++c; *p;)b(c,in,p,out); + for(int d=0; *c!=']'||d--; ++c)d+=*c=='['; + } + } +} + +// normally we want a comma between values +template +std::ostream_iterator default_ostream_iterator(std::ostream& os = std::cout){ + return std::ostream_iterator(os, ", "); +} + +// except for char's +template <> +std::ostream_iterator default_ostream_iterator(std::ostream& os){ + return std::ostream_iterator(os); +} + +} + +// Would be better if we used a smarter iterator for p... it is of fixed size now :( +template > +void brainfuck(std::string prg, std::basic_string inp = std::basic_string(), OutputIterator it = brainfuck_details::default_ostream_iterator()) { + char * c = new char[prg.length() + 1]; + std::copy(prg.begin(), prg.end(), c); + + T * i = new T[inp.length() + 1]; + std::copy(inp.begin(), inp.end(), i); + + T * p = new T[512]; + std::fill_n(p, 512, T(0)); + + brainfuck_details::b(c,i,p,it); +} + +// we can't put a default on the InputIterator, because that would be ambigious +template , typename OutputIterator = std::ostream_iterator> +void brainfuck(std::string prg, InputIterator inp, OutputIterator it = brainfuck_details::default_ostream_iterator()) { + char * c = new char[prg.length() + 1]; + std::copy(prg.begin(), prg.end(), c); + + T * p = new T[512]; + std::fill_n(p, 512, T(0)); + + brainfuck_details::b(c,inp,p,it); +} diff --git a/brainfuck/main.cpp b/brainfuck/main.cpp new file mode 100644 index 0000000..e1ba6e0 --- /dev/null +++ b/brainfuck/main.cpp @@ -0,0 +1,12 @@ +#include +#include + +#include "brainfuck.hpp" + +int main() { + brainfuck("+[,.]", std::istream_iterator(std::cin)); + brainfuck(">++++++++++++++++++++++++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]"); + + return 0; +} +