View difference between Paste ID: ehNr36XY and 3kEBnWHh
SHOW: | | - or go back to the newest paste.
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
}