Advertisement
fimas

Brainfuck interpreter w/ error checking

Aug 20th, 2014
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.08 KB | None | 0 0
  1. #include <vector>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <stdexcept>
  5. #include <cstdlib>
  6.  
  7. using namespace std;
  8.  
  9. class Memory
  10. {
  11. public:
  12.     Memory()
  13.     {
  14.         memory.reserve(MAX_MEMORY);
  15.         zeroMemory();
  16.         pointer = memory.begin();
  17.     }
  18.  
  19.     void forward()
  20.     {
  21.         ++pointer;
  22.  
  23.         if (pointer == memory.end())
  24.         {
  25.             // Exception: memory limit exceeded
  26.             throw runtime_error("Memory limit exceeded");
  27.         }
  28.     }
  29.  
  30.     void backward()
  31.     {
  32.         --pointer;
  33.     }
  34.  
  35.     void add()
  36.     {
  37.         ++(*pointer);
  38.     }
  39.  
  40.     void sub()
  41.     {
  42.         --(*pointer);
  43.     }
  44.  
  45.     void putchar()
  46.     {
  47.         cout << *pointer;
  48.     }
  49.  
  50.     void getchar()
  51.     {
  52.         cin >> *pointer;
  53.     }
  54.  
  55.     unsigned char getValue()
  56.     {
  57.         return *pointer;
  58.     }
  59. private:
  60.     const unsigned int MAX_MEMORY = 30000;
  61.     vector<unsigned char> memory;
  62.     vector<unsigned char>::iterator pointer;
  63.  
  64.     void zeroMemory()
  65.     {
  66.         for (size_t i = 0; i < MAX_MEMORY; i++)
  67.         {
  68.             memory.push_back(0);
  69.         }
  70.     }
  71. };
  72.  
  73. class Brainfuck
  74. {
  75. public:
  76.     static const unsigned char addition    = '+';
  77.     static const unsigned char subtraction = '-';
  78.     static const unsigned char forward     = '>';
  79.     static const unsigned char backward    = '<';
  80.     static const unsigned char putchar     = '.';
  81.     static const unsigned char getchar     = ',';
  82.     static const unsigned char loopStart   = '[';
  83.     static const unsigned char loopEnd     = ']';
  84.  
  85.     Brainfuck(string input) : code(input)
  86.     {
  87.         buffer = code.begin();
  88.     }
  89.  
  90.     void run()
  91.     {
  92.         for (; buffer != code.end(); ++buffer)
  93.         {
  94.             switch (*buffer)
  95.             {
  96.             case Brainfuck::addition:
  97.                 mem.add();
  98.                 break;
  99.             case Brainfuck::subtraction:
  100.                 mem.sub();
  101.                 break;
  102.             case Brainfuck::forward:
  103.                 mem.forward();
  104.                 break;
  105.             case Brainfuck::backward:
  106.                 mem.backward();
  107.                 break;
  108.             case Brainfuck::putchar:
  109.                 mem.putchar();
  110.                 break;
  111.             case Brainfuck::getchar:
  112.                 mem.getchar();
  113.                 break;
  114.             case Brainfuck::loopStart:
  115.                 startLoop();
  116.                 break;
  117.             case Brainfuck::loopEnd:
  118.                 endLoop();
  119.                 break;
  120.             default:
  121.                 break;
  122.             }
  123.         }
  124.     }
  125.  
  126. private:
  127.     Memory mem;
  128.     string code;
  129.     string::iterator buffer;
  130.     vector<string::iterator> loopPosition;
  131.  
  132.     void startLoop()
  133.     {
  134.         if (mem.getValue())
  135.         {
  136.             loopPosition.push_back(buffer);
  137.         }
  138.         else
  139.         {
  140.             while (*buffer != Brainfuck::loopEnd)
  141.                 ++buffer;
  142.         }
  143.     }
  144.  
  145.     void endLoop()
  146.     {
  147.         if (loopPosition.empty())
  148.         {
  149.             // Exception: unbalanced brackets
  150.             throw runtime_error("Unbalanced brackets");
  151.         }
  152.  
  153.         if (mem.getValue())
  154.         {
  155.             buffer = loopPosition.back();
  156.         }
  157.         else
  158.         {
  159.             loopPosition.pop_back();
  160.         }
  161.     }
  162. };
  163.  
  164. int main(int argc, char* argv[])
  165. {
  166.     string inData;
  167.     if (argc == 2)
  168.     {
  169.         wstring codeFile = argv[1];
  170.         ifstream file(codeFile, ios::in);
  171.         char buff;
  172.  
  173.         file >> skipws;
  174.  
  175.         while (file >> buff)
  176.             inData += buff;
  177.        
  178.         file.close();
  179.     }
  180.     else
  181.     {
  182.         cout << "Useage: " << argv[0] << " <source file>" << endl;
  183.         std::cin.get(); // Press enter to exit
  184.         exit(0);
  185.     }
  186.  
  187.     try
  188.     {
  189.         Brainfuck bf(inData);
  190.         bf.run();
  191.     }
  192.     catch (exception &e)
  193.     {
  194.         cerr << e.what() << endl;
  195.     }
  196.  
  197.  
  198.     std::cin.get(); // Press enter to exit
  199.  
  200.     return 0;
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement