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 | } |