namespace Prelude { struct Nil; template struct List; template struct ListInt; template struct ListChar; template struct tail; template struct splitAt; template struct concat; template struct at; /* tail (_:xs) = xs */ template struct tail> { typedef xs type; }; /**********/ template<> struct tail { typedef Nil type; }; /**********/ /* splitAt 0 xs = ([],xs) splitAt n (x:xs) = let (a,b) = splitAt (n-1) xs in (x:a,b) */ template struct splitAt<0, xs, true> { typedef Nil before; typedef xs after; }; template struct splitAt, false> { static_assert(n > 0, "splitAt: negative index"); typedef splitAt next; typedef ListInt before; typedef typename next::after after; }; /**********/ template struct splitAt { static_assert(n > 0, "splitAt: negative index"); typedef splitAt<(n-1), Nil> next; typedef ListInt<0, typename next::before> before; typedef Nil after; }; /**********/ /* [] ++ ys = ys (x:xs) ++ ys = x:(xs ++ ys) */ template struct concat { typedef ys type; }; template struct concat, ys> { typedef ListInt::type> type; }; /* (x:_) !! 0 = x (_:xs) !! n = xs !! (n-1) */ template struct at, 0> { static const int value = x; }; template struct at, n> : at { static_assert(n > 0, "at: negative index"); }; /**********/ template struct at { static const int value = 0; }; /**********/ } // namespace Prelude namespace bf { using namespace Prelude; template struct Val; template struct Ptr; struct Get; struct Put; template struct While; template struct parseBF; template struct evalBF; template struct interpretBF; template struct changeAt { typedef splitAt s; typedef typename tail::type a; typedef typename concat>::type type; }; template struct interpretBF { typedef parseBF p; template struct hoge { static_assert(_, "extra ']'"); }; template struct hoge { typedef evalBF e; typedef typename e::output type; }; typedef typename hoge::type type; }; template<> struct parseBF { typedef Nil op; typedef Nil rest; }; template struct parseBF> { template struct hoge { static_assert(_, "']' missing"); }; template struct hoge, _> { typedef T type; }; typedef typename parseBF::op o; typedef typename hoge::rest>::type t; typedef typename parseBF::op p; typedef List, p> op; typedef typename parseBF::rest rest; }; template struct parseBF> { typedef Nil op; typedef ListChar<']', xs> rest; }; #define P(c,v) \ template struct \ parseBF> : parseBF { \ typedef List::op> op; \ }; P('+',Val<1>) P('-',Val<-1>) P('>',Ptr<1>) P('<',Ptr<-1>) P(',',Get) P('.',Put) #undef P template struct evalBF { static const int ptr = p; typedef a array; typedef i input; typedef Nil output; }; template struct evalBF, cs>, p, a, i> : evalBF::value) % 256)>::type, i> {}; template struct evalBF, cs>, p, a, i> : evalBF {}; template struct evalBF, p, a, ListInt> : evalBF::type, xs> {}; template struct evalBF, p, a, Nil> : evalBF {}; template struct evalBF, p, a, i> : evalBF { typedef ListInt::value, typename evalBF::output> output; }; template struct evalBF, cs2>, p, a, i0> { typedef List, cs2> cs0; template struct hoge; template struct hoge { typedef evalBF type; }; template struct hoge { typedef evalBF k0; typedef evalBF k1; struct type : k1 { typedef typename concat< typename k0::output, typename k1::output >::type output; }; }; typedef typename hoge<(at::value == 0)>::type next; static const int ptr = next::ptr; typedef typename next::array array; typedef typename next::input input; typedef typename next::output output; }; } // namespace bf /////////////////////////////////////////////////////////////////////////////// #include using namespace Prelude; using namespace bf; template struct print_impl; template struct print_impl> { static std::ostream& p(std::ostream& out) { return out << x; } }; template struct print_impl> { static std::ostream& p(std::ostream& out) { return print_impl::p(out << x << ","); } }; template std::ostream& print(std::ostream& out) { return print_impl::p(out << "[") << "]"; } template<> std::ostream& print(std::ostream& out) { return out << "[]"; } template struct string_; template<> struct string_<> { typedef Nil type; }; template struct string_ { typedef ListChar::type> type; }; template struct int_; template<> struct int_<> { typedef Nil type; }; template struct int_ { typedef ListInt::type> type; }; int main() { { // "+++." typedef string_<'+', '+', '+', '.'>::type code; typedef interpretBF::type output; print(std::cout) << std::endl; } { // ",+.,+.,+." typedef string_<',', '+', '.', ',', '+', '.', ',', '+', '.'>::type code; typedef interpretBF::type>::type output; print(std::cout) << std::endl; } { // "+++[-]." typedef string_<'+', '+', '+', '[', '-', ']', '.'>::type code; typedef interpretBF::type output; print(std::cout) << std::endl; } { // ",[.[-],]" typedef string_<',', '[', '.', '[', '-', ']', ',', ']'>::type code; typedef interpretBF::type>::type output; print(std::cout) << std::endl; } { // "+++++[>+++<-]>." typedef string_<'+', '+', '+', '+', '+', '[', '>', '+', '+', '+', '<', '-', ']', '>', '.'>::type code; typedef interpretBF::type output; print(std::cout) << std::endl; } }