brainfucklib, made with irc-use (geordi-irc) in mind
This commit is contained in:
parent
39318cf12b
commit
4037103431
2 changed files with 77 additions and 0 deletions
65
brainfuck/brainfuck.hpp
Normal file
65
brainfuck/brainfuck.hpp
Normal file
|
@ -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
Normal file
12
brainfuck/main.cpp
Normal file
|
@ -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 a new issue