Advertisement
kenpusney

brainfuck.cpp

Jan 19th, 2022 (edited)
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.25 KB | None | 0 0
  1. template<int first, int... rest>
  2. struct memory;
  3.  
  4. struct empty {
  5.     template<int val>
  6.     using append = memory<val>;
  7.  
  8.     using next = empty;
  9.  
  10.     constexpr static int value = 0;
  11. };
  12.  
  13. template<class l, class r>
  14. struct same_t {
  15.     constexpr static bool value = false;
  16. };
  17.  
  18. template<class t>
  19. struct same_t<t, t> {
  20.     constexpr static bool value = true;
  21. };
  22.  
  23. template<class l, class r>
  24. constexpr bool same_v = same_t<l, r>::value;
  25.  
  26. template<class C, class M, class I, class O, int IP, int DP>
  27. struct state {
  28.     using commands = C;
  29.     using memory = M;
  30.     using input = I;
  31.     using output = O;
  32.     constexpr static int ip = IP;
  33.     constexpr static int dp = DP;
  34. };
  35.  
  36. template<int first, int... rest>
  37. struct commands {
  38.     constexpr static int current = first;
  39.     using next = commands<rest...>;
  40. };
  41.  
  42. template<int first>
  43. struct commands<first>{
  44.     constexpr static int current = first;
  45.     using next = empty;
  46. };
  47.  
  48. template<class commands>
  49. constexpr int at(int index) {
  50.     if constexpr (!same_v<commands, empty>) {
  51.         if (index == 0) {
  52.             return commands::current;
  53.         }
  54.         return at<typename commands::next>(index - 1);
  55.     }
  56.     return 0;
  57. }
  58.  
  59. template<int first, int... rest>
  60. struct memory {
  61.  
  62.     template<int cell>
  63.     using append = memory<first, rest..., cell>;
  64.  
  65.     constexpr static int value = first;
  66.  
  67.     using next = memory<rest...>;
  68. };
  69.  
  70. template<int first>
  71. struct memory<first>{
  72.     template<int cell>
  73.     using append = memory<first, cell>;
  74.  
  75.     constexpr static int value = first;
  76.  
  77.     using next = empty;
  78. };
  79.  
  80. template<int index, class memory, class part = empty>
  81. struct locate;
  82.  
  83. template<class l, class r>
  84. struct merge;
  85.  
  86. template<class l, class r>
  87. struct merge {
  88.     using result = typename merge<typename l::template append<r::value>, typename r::next>::result;
  89. };
  90.  
  91. template<class l>
  92. struct merge<l, empty> {
  93.     using result = l;
  94. };
  95.  
  96. template<class r>
  97. struct merge<empty, r> {
  98.     using result = r;
  99. };
  100.  
  101. template<int index, class memory, class part>
  102. struct locate {
  103.     using result = locate<index - 1, typename memory::next, typename part::template append<memory::value>>;
  104.  
  105.     using left = typename result::left;
  106.     constexpr static int value = result::value;
  107.     using right = typename result::right;
  108.  
  109.     template<int new_value>
  110.     using replace = typename merge<typename left::template append<new_value>, right>::result;
  111. };
  112.  
  113. template<class memory, class part>
  114. struct locate<0, memory, part> {
  115.     using left = part;
  116.     using right = typename memory::next;
  117.     constexpr static int value = memory::value;
  118.  
  119.     template<int new_value>
  120.     using replace = typename merge<typename left::template append<new_value>, right>::result;
  121. };
  122.  
  123.  
  124. template<int first, int...values>
  125. struct input {
  126.     constexpr static int current = first;
  127.     using next = input<values...>;
  128. };
  129.  
  130. template<int... values>
  131. struct output {
  132.     template<int val>
  133.     using put = output<values..., val>;
  134. };
  135.  
  136. template<class state>
  137. constexpr void run() {
  138.     constexpr int command = at<typename state::commands>(state::ip);
  139.     if constexpr(command != 0) {
  140.         if (command == '+') {
  141.             using located = locate<state::dp, typename state::memory>;
  142.             constexpr int result = located::value;
  143.             return run<
  144.                 ::state<
  145.                     typename state::commands,
  146.                     typename located::template replace<result + 1>,
  147.                     typename state::input,
  148.                     typename state::output,
  149.                     state::ip + 1,
  150.                     state::dp
  151.                 >
  152.             >();
  153.         }
  154.  
  155.         if (command == '>') {
  156.             return run<
  157.                 ::state<
  158.                     typename state::commands,
  159.                     typename state::memory,
  160.                     typename state::input,
  161.                     typename state::output,
  162.                     state::ip + 1,
  163.                     state::dp + 1
  164.                 >
  165.             >();
  166.         }
  167.     }
  168. }
  169.  
  170. int main() {
  171.     run<
  172.         state<
  173.             commands<'+', '+', '+', '>', '+'>,
  174.             memory<0, 0, 0>,
  175.             input<0, 0, 0>,
  176.             output<0, 0, 0>,
  177.             0,
  178.             0
  179.         >
  180.     >();
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement