BrainFuck解释器


#include<string>
#include<iostream>
#include <fstream>
#include <limits> 
#include<map>

using namespace std;

typedef string bf_string;
typedef  const char token_type;
typedef  unsigned int circular_times_type;
typedef unsigned int bf_int;

token_type circular_left = '[';
token_type circular_right = ']';
token_type less_than = '<';
token_type greater_than = '>';
token_type reduce = '-';
token_type add = '+';
token_type output = '.';
token_type input = ',';

const bf_int  ram_max = 1024;


/*
Hello World!
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
*/
/*
circular times test
+++++++++++++++++++.[+++++-------]
*/




int main(int argc, char* argv[])
{
     cout << "BrainFuck interpreter by karakapi" << endl << endl;
     cout << ">      means     ++p; " << endl;
     cout << "<      means     --p;" << endl;
     cout << "+      means     ++*p;" << endl;
     cout << "-      means      --*p;" << endl;
     cout << ".     means      putchar(*p);" << endl;
     cout << ",      means      *p = getchar();" << endl;
     cout << "[     means      while (*p) { " << endl;
     cout << "]     means      }" << endl;
     cout  << "The memory is persistence" << endl;
     cout << "Especially,this interpreter  provide operators" << endl;

     cout << "~ does clear memory" << endl;
     cout << "! does forcibly stop running when it  is inputting" << endl;
     cout << "@ does change the limit circular times " << endl;
     cout << "# as a key does close this interpreter " << endl;
     cout << "% does show the pointer" << endl;

     cout << "$ is a tag that is to open the function of inputting character directly" << endl
          << " You can input the ASCII" << endl << " to the location of the  pointer is pointing to  directly" << endl
          << "For example," << endl
          << "$" << endl
          << "a." << endl
          << "when you press enter, it will store the last one and show it" << endl
          << "a" << endl
          << "and when you do not input $,it is closed," << endl << "when you input $,it opens until you input $ again." << endl << endl
          << "If you want to input file to interprete ,you can command :" << endl
          << "brainfuck file " << endl << endl
          << "Pay attention to" << endl
          << "when pointer equals 1023,you use >,it will be change to 0" << endl
          << "when pointer equals 0,you use <,it will be change to 1023" << endl << endl
    
          << "Hello World  in BrainFuck" << endl
          << "++++++++++[>+++++++>++++++++++>+++>+<<<<-]" << endl
          << ">++.>+.+++++++..+++.>++.<<+++++++++++++++." << endl
          << ">.++ + .------.--------.>+.>." << endl;

     int interpreter(bf_string &token, char* array_ram, int ram_size, bool&  s, int& pointer, bf_int& limit_circular_times);

     bf_string token;
     char*array_ram = new char[ram_max + 1];
     if (array_ram == 0){
          cout << "Error cannot storage allocation" << endl;
          return false;
     }
     memset(array_ram, 0, (ram_max+1)*sizeof(char));
     int state = 0;
     bool sp = false;
     int pointer = 0;
     circular_times_type limit_circular_times = 65534;

     if (argc < 2){

     }
     else{
         
          ifstream file(argv[1]);
          while (!file.eof()){
               file >> token;

          }
          file.close();
          state = interpreter(token, array_ram,ram_max,  sp, pointer, limit_circular_times);
     }

     while (state < 2){

          cout << endl << ">> ";
          token.clear();
          cin >> token;

          state = interpreter(token, array_ram, ram_max,  sp, pointer, limit_circular_times);


     }

     delete[]array_ram;

     return 0;
}

int interpreter(bf_string &token, char * array_ram, int ram_size, bool& s, int&pointer, bf_int &limit_circular_times){
     int  circular_layers = 0;

     int fix_ram_size = ram_size - 1;

     map<bf_int, circular_times_type> circular_map;

    


     /*Loop syntax check*/
     bf_int index = 0;
     for (; index < token.length(); ++index){
          if (token[index] == circular_left){
               ++circular_layers;
          }
          if (token[index] == circular_right){
               if (circular_layers > 0){
                    --circular_layers;
               }
               else{
                    cout << "Error:Expect token '[' but not found" << " possible position:" << index << endl;
                    return false;
               }
          }
     }
     if (circular_layers != 0){
          if (circular_layers <0){


               for (; circular_layers<0; ++circular_layers){
                    for (; index>0; --index){
                         if (token[index] == circular_left){

                              break;

                         }

                    }
                    ++index;
               }
               cout << "Error:Expect token '[' but not found," << " possible position:" << index << endl;
               return false;
          }
          else {

               for (; circular_layers>0; --circular_layers){
                    for (; index > 0; --index){
                   
                         if (token[index] == circular_left){
                              break;
                         }
                    }
                    ++index;
               }

               cout << "Error:Expect token ']' but not found," << " possible position:" << index << endl;
               return false;

          }
     }
     /*running*/
     for (bf_int index = 0; index < token.length(); ++index){


          switch (token[index])
          {
          case circular_left:{
                                      if (pointer>fix_ram_size || pointer<0){
                                           cout << "Error:" << "circular_left" << "    " << "pointer:" << pointer << " " << "position:" << index << endl;

                                           return false;
                                      }
                                  
                                     
                                      circular_layers = 1;

                                      if (array_ram[pointer] == 0){
                                           break;
                                      }

                                      while (circular_layers){
                                           ++index;
                                           if (circular_left == token[index])
                                           {
                                                ++circular_layers;
                                           }
                                           if (circular_right == token[index])
                                           {
                                                --circular_layers;
                                           }

                                      }


                                      --index;
                                      break;

          }
          case circular_right:{
                                        if (pointer > fix_ram_size || pointer<0){
                                             cout << "Error:" << "circular_right" << "    " << "pointer:" << pointer << " " << "position:" << index << endl;

                                             return false;
                                        }
                                        circular_times_type times = circular_map[index];
                                        ++circular_map[index];
                                        if (times> limit_circular_times){
                                             cout << endl << "Error:" << "circular tail " << token[index] << "  " << "position:" << index << "  circular is more than " << limit_circular_times << " times" << endl;


                                             return false;
                                        }
                                        circular_layers = 1;
                                        if (!array_ram[pointer]){
                                             break;
                                        }
                                        while (circular_layers){
                                             --index;
                                             if (circular_right == token[index])
                                             {
                                                  ++circular_layers;
                                             }
                                             if (circular_left == token[index])
                                             {
                                                  --circular_layers;
                                             }


                                        }
                                        break;


          }
          case less_than:{
                                 if (pointer > 0){

                                      --pointer;
                                 }
                                 else {
                                      cout << "Warnning:" << "less_than" << "    " << "pointer:" << pointer << " " << "position:" << index << endl;
                                      cout << "pointer reset " << fix_ram_size << endl;
                                      pointer = fix_ram_size;

                                 }
                                 break;

          }
          case greater_than:{
                                     if (pointer == fix_ram_size){
                                          cout << "Warnning:" << "greater_than" << "    " << "pointer:" << pointer << " " << "position:" << index << endl;
                                          cout << "pointer reset " << 0 << endl;
                                          pointer = 0;

                                     }
                                     else if (pointer<fix_ram_size){
                                          ++pointer;
                                     }

                                     break;
          }
          case add:{
                         if (pointer>fix_ram_size || pointer<0){
                              cout << "Error:" << "add" << "    " << "pointer:" << pointer << " " << "position:" << index << endl;

                              return false;
                         }
                         ++array_ram[pointer];
                         break;

          }
          case reduce:{
                              if (pointer>fix_ram_size || pointer<0){
                                   cout << "Error:" << "reduce" << "    " << "pointer:" << pointer << " " << "position:" << index << endl;

                                   return false;
                              }
                              --array_ram[pointer];
                              break;
          }
          case input:{
                            if (pointer>fix_ram_size || pointer < 0){
                                 cout << "Error:" << "input" << "    " << "pointer:" << pointer << " " << "position:" << index << endl;

                                 return false;
                            }

                            cin.clear();
                            cin.sync();
                            char tmp;

                            cin.get(tmp);
                            if (tmp == '!'){
                                 cout << "Stop!" << endl;
                                 return false;
                            }
                            array_ram[pointer] = tmp;

                            break;
          }
          case output:{
                              if (pointer > fix_ram_size || pointer < 0){
                                   cout << "Error:" << "output" << "    " << "pointer:" << pointer << endl;

                                   return false;
                              }
                              cout << array_ram[pointer];
                              break;
          }

          case ' ':{
                         break;
          }
          case'r':{
                         break;
          }
          case'n':{
                         break;
          }
          case'#': {
                         cout << "closing" << endl;
                         return 2;
          }
          case'~':{

                         memset(array_ram, 0, (fix_ram_size+1)*sizeof(char));
                         cout << "clear memory" << endl;
                         break;
          }
          case'$':{
                         if (s == false){
                              s = true;
                         }
                         else{
                              s = false;
                         }
                         break;

          }


          case'%':{
                         cout << "point:" << pointer << endl;
                         break;
          }
          case '@':{
                         cin.clear();
                         cin.sync();
                         circular_times_type tmp, limit_circular_times_max = UINT_MAX - 1;

                         cout << "input  circular limit times" << endl;
                         cout << "The number  must be in the range of " << 0 << " to " << limit_circular_times_max << endl;
                         cin >> tmp;
                         if (tmp <= limit_circular_times_max){
                              limit_circular_times = tmp;
                              cout << "limit circular limit times : " << limit_circular_times << endl;
                         }
                         else{
                              cout << "The number is beyond the range of " << 0 << " to " << limit_circular_times_max << endl;
                              cout << "limit circular limit times : " << limit_circular_times << endl;
                         }

                         break;

          }
         

          default:
               if (s == false){
                    cout << "Error: " << token[index] << " is not token " << ' ' << "position:" << index << endl;
                    return false;
               }
               array_ram[pointer] = token[index];
               break;
          }
     }

     return true;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值