Browse Source

brainfucklib, made with irc-use (geordi-irc) in mind

master
Joshua Moerman (@Kassalade) 13 years ago
parent
commit
4037103431
  1. 65
      brainfuck/brainfuck.hpp
  2. 12
      brainfuck/main.cpp

65
brainfuck/brainfuck.hpp

@ -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);
}

12
brainfuck/main.cpp

@ -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;
}