Advertisement
Guest User

Turing-complete RPN

a guest
Dec 4th, 2012
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <sstream>
  3. #include <string>
  4. #include <vector>
  5. #include <cmath>
  6.  
  7. struct command{
  8.     bool is_push;
  9.     double x;
  10.     std::string name;
  11.     command(double x):is_push(1),x(x){}
  12.     command(const std::string &s):is_push(0),name(s){}
  13. };
  14.  
  15. class RPN{
  16.     std::vector<double> stack;
  17.     std::vector<command> code;
  18.     std::vector<size_t> code_stack;
  19.     int skip,
  20.         simulation;
  21.     size_t ip;
  22. public:
  23.     RPN():skip(0),ip(0),simulation(0){}
  24.     void push_back(double x){
  25.         if (this->skip){
  26.             this->skip--;
  27.             return;
  28.         }
  29.         if (this->code_stack.size() && this->simulation<=0)
  30.             this->code.push_back(x);
  31.         this->stack.push_back(x);
  32.         this->print_stack();
  33.     }
  34.     void eval(const std::string &s){
  35.         if (this->code_stack.size() && this->simulation<=0)
  36.             this->code.push_back(s);
  37.         if (this->skip){
  38.             this->skip--;
  39.             return;
  40.         }
  41.         std::cout <<s<<std::endl;
  42.         if (s=="+"){
  43.             if (this->stack.size()<2)
  44.                 return;
  45.             double b=this->stack.back();
  46.             this->stack.pop_back();
  47.             double a=this->stack.back();
  48.             this->stack.pop_back();
  49.             this->stack.push_back(a+b);
  50.         }else if (s=="-"){
  51.             if (this->stack.size()<2)
  52.                 return;
  53.             double b=this->stack.back();
  54.             this->stack.pop_back();
  55.             double a=this->stack.back();
  56.             this->stack.pop_back();
  57.             this->stack.push_back(a-b);
  58.         }else if (s=="neg"){
  59.             if (this->stack.size()<1)
  60.                 return;
  61.             double a=this->stack.back();
  62.             this->stack.pop_back();
  63.             this->stack.push_back(-a);
  64.         }else if (s=="bneg"){
  65.             if (this->stack.size()<1)
  66.                 return;
  67.             double a=this->stack.back();
  68.             this->stack.pop_back();
  69.             this->stack.push_back(a>=0?-1:1);
  70.         }else if (s=="*"){
  71.             if (this->stack.size()<2)
  72.                 return;
  73.             double b=this->stack.back();
  74.             this->stack.pop_back();
  75.             double a=this->stack.back();
  76.             this->stack.pop_back();
  77.             this->stack.push_back(a*b);
  78.         }else if (s=="/"){
  79.             if (this->stack.size()<2)
  80.                 return;
  81.             double b=this->stack.back();
  82.             this->stack.pop_back();
  83.             double a=this->stack.back();
  84.             this->stack.pop_back();
  85.             this->stack.push_back(a/b);
  86.         }else if (s=="^"){
  87.             if (this->stack.size()<2)
  88.                 return;
  89.             double b=this->stack.back();
  90.             this->stack.pop_back();
  91.             double a=this->stack.back();
  92.             this->stack.pop_back();
  93.             this->stack.push_back(pow(a,b));
  94.         }else if (s=="sqrt"){
  95.             if (this->stack.size()<1)
  96.                 return;
  97.             double a=this->stack.back();
  98.             this->stack.pop_back();
  99.             this->stack.push_back(sqrt(a));
  100.         }else if (s=="e"){
  101.             this->stack.push_back(2.7182818284590452353602874713527);
  102.         }else if (s=="pi"){
  103.             this->stack.push_back(3.1415926535897932384626433832795);
  104.         }else if (s=="exp"){
  105.             if (this->stack.size()<1)
  106.                 return;
  107.             double a=this->stack.back();
  108.             this->stack.pop_back();
  109.             this->stack.push_back(exp(a));
  110.         }else if (s=="log"){
  111.             if (this->stack.size()<1)
  112.                 return;
  113.             double a=this->stack.back();
  114.             this->stack.pop_back();
  115.             this->stack.push_back(log(a));
  116.         }else if (s=="sin"){
  117.             if (this->stack.size()<1)
  118.                 return;
  119.             double a=this->stack.back();
  120.             this->stack.pop_back();
  121.             this->stack.push_back(sin(a));
  122.         }else if (s=="cos"){
  123.             if (this->stack.size()<1)
  124.                 return;
  125.             double a=this->stack.back();
  126.             this->stack.pop_back();
  127.             this->stack.push_back(cos(a));
  128.         }else if (s=="tan"){
  129.             if (this->stack.size()<1)
  130.                 return;
  131.             double a=this->stack.back();
  132.             this->stack.pop_back();
  133.             this->stack.push_back(tan(a));
  134.         }else if (s=="asin"){
  135.             if (this->stack.size()<1)
  136.                 return;
  137.             double a=this->stack.back();
  138.             this->stack.pop_back();
  139.             this->stack.push_back(asin(a));
  140.         }else if (s=="acos"){
  141.             if (this->stack.size()<1)
  142.                 return;
  143.             double a=this->stack.back();
  144.             this->stack.pop_back();
  145.             this->stack.push_back(acos(a));
  146.         }else if (s=="atan"){
  147.             if (this->stack.size()<1)
  148.                 return;
  149.             double a=this->stack.back();
  150.             this->stack.pop_back();
  151.             this->stack.push_back(atan(a));
  152.         }else if (s=="atan2"){
  153.             if (this->stack.size()<2)
  154.                 return;
  155.             double b=this->stack.back();
  156.             this->stack.pop_back();
  157.             double a=this->stack.back();
  158.             this->stack.pop_back();
  159.             this->stack.push_back(atan2(a,b));
  160.         }else if (s=="pop"){
  161.             if (this->stack.size()<1)
  162.                 return;
  163.             this->stack.pop_back();
  164.         }else if (s=="dup"){
  165.             if (this->stack.size()<1)
  166.                 return;
  167.             this->stack.push_back(this->stack.back());
  168.         }else if (s=="swap"){
  169.             if (this->stack.size()<2)
  170.                 return;
  171.             double b=this->stack.back();
  172.             this->stack.pop_back();
  173.             double a=this->stack.back();
  174.             this->stack.pop_back();
  175.             this->stack.push_back(b);
  176.             this->stack.push_back(a);
  177.         }else if (s=="rot"){
  178.             if (this->stack.size()<1)
  179.                 return;
  180.             int n=(int)this->stack.back();
  181.             this->stack.pop_back();
  182.             if (this->stack.size()<n || n<2)
  183.                 return;
  184.             double *temp=new double[n];
  185.             for (int a=0;a<n;a++){
  186.                 temp[n-a-1]=this->stack.back();
  187.                 this->stack.pop_back();
  188.             }
  189.             for (int a=1;a<n;a++)
  190.                 this->stack.push_back(temp[a]);
  191.             this->stack.push_back(temp[0]);
  192.             delete[] temp;
  193.         }else if (s=="if"){
  194.             if (this->stack.size()<1)
  195.                 return;
  196.             int times=(int)this->stack.back();
  197.             this->stack.pop_back();
  198.             double condition=this->stack.back();
  199.             this->stack.pop_back();
  200.             if (condition<0)
  201.                 this->skip=times;
  202.         }else if (s=="begin"){
  203.             if (this->simulation<=0){
  204.                 this->code_stack.push_back(this->code.size());
  205.                 this->simulation--;
  206.             }else
  207.                 this->simulation++;
  208.         }else if (s=="leave"){
  209.             if (this->simulation<=0){
  210.                 this->simulation++;
  211.                 if (!this->simulation)
  212.                     this->exec();
  213.             }else
  214.                 this->simulation--;
  215.         }else if (s=="end"){
  216.             if (this->simulation>0){
  217.                 if (!this->code_stack.size())
  218.                     return;
  219.                 this->ip=this->code_stack[this->simulation-1];
  220.             }
  221.         }else if (s=="$"){
  222.             if (this->stack.size()<1)
  223.                 return;
  224.             std::cout <<this->stack.back()<<std::endl;
  225.         }
  226.         this->print_stack();
  227.     }
  228.     void exec(){
  229.         this->simulation=1;
  230.         this->ip=0;
  231.         while (this->simulation){
  232.             command &c=this->code[this->ip];
  233.             int ip=this->ip;
  234.             if (c.is_push)
  235.                 this->push_back(c.x);
  236.             else
  237.                 this->eval(c.name);
  238.             if (this->ip==ip)
  239.                 this->ip++;
  240.         }
  241.         this->code.clear();
  242.         this->code_stack.clear();
  243.     }
  244.     void print_stack(){
  245.         std::cout <<'[';
  246.         if (this->stack.size()){
  247.             for (int a=0;;){
  248.                 std::cout <<this->stack[a];
  249.                 a++;
  250.                 if (a==this->stack.size())
  251.                     break;
  252.                 std::cout <<',';
  253.             }
  254.         }
  255.         std::cout <<"]\n";
  256.     }
  257. };
  258.  
  259. int main(){
  260.     RPN rpn;
  261.     while (std::cin.good()){
  262.         std::string s;
  263.         double x;
  264.         std::cin >>s;
  265.         std::stringstream stream;
  266.         stream <<s;
  267.         if (stream >>x)
  268.             rpn.push_back(x);
  269.         else{
  270.             if (s=="exit")
  271.                 break;
  272.             rpn.eval(s);
  273.         }
  274.     }
  275.     return 0;
  276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement