Joshua Moerman (@Kassalade)
14 years ago
2 changed files with 77 additions and 0 deletions
@ -0,0 +1,65 @@ |
|||
#include <iostream> |
|||
#include <iterator> |
|||
#include <algorithm> |
|||
|
|||
/**
|
|||
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 <typename T, typename InputIterator, typename OutputIterator> |
|||
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 <typename T> |
|||
std::ostream_iterator<T> default_ostream_iterator(std::ostream& os = std::cout){ |
|||
return std::ostream_iterator<T>(os, ", "); |
|||
} |
|||
|
|||
// except for char's
|
|||
template <> |
|||
std::ostream_iterator<char> default_ostream_iterator<char>(std::ostream& os){ |
|||
return std::ostream_iterator<char>(os); |
|||
} |
|||
|
|||
} |
|||
|
|||
// Would be better if we used a smarter iterator for p... it is of fixed size now :(
|
|||
template <typename T = char, typename OutputIterator = std::ostream_iterator<T>> |
|||
void brainfuck(std::string prg, std::basic_string<T> inp = std::basic_string<T>(), OutputIterator it = brainfuck_details::default_ostream_iterator<T>()) { |
|||
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 T = char, typename InputIterator = std::istream_iterator<T>, typename OutputIterator = std::ostream_iterator<T>> |
|||
void brainfuck(std::string prg, InputIterator inp, OutputIterator it = brainfuck_details::default_ostream_iterator<T>()) { |
|||
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); |
|||
} |
@ -0,0 +1,12 @@ |
|||
#include <iostream> |
|||
#include <iterator> |
|||
|
|||
#include "brainfuck.hpp" |
|||
|
|||
int main() { |
|||
brainfuck<int>("+[,.]", std::istream_iterator<int>(std::cin)); |
|||
brainfuck<int>(">++++++++++++++++++++++++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]"); |
|||
|
|||
return 0; |
|||
} |
|||
|
Reference in new issue