Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <vector>
- #include <cmath>
- struct command{
- bool is_push;
- double x;
- std::string name;
- command(double x):is_push(1),x(x){}
- command(const std::string &s):is_push(0),name(s){}
- };
- class RPN{
- std::vector<double> stack;
- std::vector<command> code;
- std::vector<size_t> code_stack;
- int skip,
- simulation;
- size_t ip;
- public:
- RPN():skip(0),ip(0),simulation(0){}
- void push_back(double x){
- if (this->skip){
- this->skip--;
- return;
- }
- if (this->code_stack.size() && this->simulation<=0)
- this->code.push_back(x);
- this->stack.push_back(x);
- this->print_stack();
- }
- void eval(const std::string &s){
- if (this->code_stack.size() && this->simulation<=0)
- this->code.push_back(s);
- if (this->skip){
- this->skip--;
- return;
- }
- std::cout <<s<<std::endl;
- if (s=="+"){
- if (this->stack.size()<2)
- return;
- double b=this->stack.back();
- this->stack.pop_back();
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(a+b);
- }else if (s=="-"){
- if (this->stack.size()<2)
- return;
- double b=this->stack.back();
- this->stack.pop_back();
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(a-b);
- }else if (s=="neg"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(-a);
- }else if (s=="bneg"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(a>=0?-1:1);
- }else if (s=="*"){
- if (this->stack.size()<2)
- return;
- double b=this->stack.back();
- this->stack.pop_back();
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(a*b);
- }else if (s=="/"){
- if (this->stack.size()<2)
- return;
- double b=this->stack.back();
- this->stack.pop_back();
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(a/b);
- }else if (s=="^"){
- if (this->stack.size()<2)
- return;
- double b=this->stack.back();
- this->stack.pop_back();
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(pow(a,b));
- }else if (s=="sqrt"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(sqrt(a));
- }else if (s=="e"){
- this->stack.push_back(2.7182818284590452353602874713527);
- }else if (s=="pi"){
- this->stack.push_back(3.1415926535897932384626433832795);
- }else if (s=="exp"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(exp(a));
- }else if (s=="log"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(log(a));
- }else if (s=="sin"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(sin(a));
- }else if (s=="cos"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(cos(a));
- }else if (s=="tan"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(tan(a));
- }else if (s=="asin"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(asin(a));
- }else if (s=="acos"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(acos(a));
- }else if (s=="atan"){
- if (this->stack.size()<1)
- return;
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(atan(a));
- }else if (s=="atan2"){
- if (this->stack.size()<2)
- return;
- double b=this->stack.back();
- this->stack.pop_back();
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(atan2(a,b));
- }else if (s=="pop"){
- if (this->stack.size()<1)
- return;
- this->stack.pop_back();
- }else if (s=="dup"){
- if (this->stack.size()<1)
- return;
- this->stack.push_back(this->stack.back());
- }else if (s=="swap"){
- if (this->stack.size()<2)
- return;
- double b=this->stack.back();
- this->stack.pop_back();
- double a=this->stack.back();
- this->stack.pop_back();
- this->stack.push_back(b);
- this->stack.push_back(a);
- }else if (s=="rot"){
- if (this->stack.size()<1)
- return;
- int n=(int)this->stack.back();
- this->stack.pop_back();
- if (this->stack.size()<n || n<2)
- return;
- double *temp=new double[n];
- for (int a=0;a<n;a++){
- temp[n-a-1]=this->stack.back();
- this->stack.pop_back();
- }
- for (int a=1;a<n;a++)
- this->stack.push_back(temp[a]);
- this->stack.push_back(temp[0]);
- delete[] temp;
- }else if (s=="if"){
- if (this->stack.size()<1)
- return;
- int times=(int)this->stack.back();
- this->stack.pop_back();
- double condition=this->stack.back();
- this->stack.pop_back();
- if (condition<0)
- this->skip=times;
- }else if (s=="begin"){
- if (this->simulation<=0){
- this->code_stack.push_back(this->code.size());
- this->simulation--;
- }else
- this->simulation++;
- }else if (s=="leave"){
- if (this->simulation<=0){
- this->simulation++;
- if (!this->simulation)
- this->exec();
- }else
- this->simulation--;
- }else if (s=="end"){
- if (this->simulation>0){
- if (!this->code_stack.size())
- return;
- this->ip=this->code_stack[this->simulation-1];
- }
- }else if (s=="$"){
- if (this->stack.size()<1)
- return;
- std::cout <<this->stack.back()<<std::endl;
- }
- this->print_stack();
- }
- void exec(){
- this->simulation=1;
- this->ip=0;
- while (this->simulation){
- command &c=this->code[this->ip];
- int ip=this->ip;
- if (c.is_push)
- this->push_back(c.x);
- else
- this->eval(c.name);
- if (this->ip==ip)
- this->ip++;
- }
- this->code.clear();
- this->code_stack.clear();
- }
- void print_stack(){
- std::cout <<'[';
- if (this->stack.size()){
- for (int a=0;;){
- std::cout <<this->stack[a];
- a++;
- if (a==this->stack.size())
- break;
- std::cout <<',';
- }
- }
- std::cout <<"]\n";
- }
- };
- int main(){
- RPN rpn;
- while (std::cin.good()){
- std::string s;
- double x;
- std::cin >>s;
- std::stringstream stream;
- stream <<s;
- if (stream >>x)
- rpn.push_back(x);
- else{
- if (s=="exit")
- break;
- rpn.eval(s);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement