lsnes rr0-β2
[lsnes.git] / memorywatch.cpp
blob3f6d0751b721063aa68021a6659ed4cce2efaf0b
1 #include "memorywatch.hpp"
2 #include "memorymanip.hpp"
3 #include <list>
4 #include <iomanip>
5 #include <stack>
6 #include <cmath>
7 #include <sstream>
9 std::string evaluate_watch(const std::string& expr) throw(std::bad_alloc)
11 std::stack<double> s;
12 size_t y;
13 std::string _expr = expr;
14 std::string t;
15 double a;
16 double b;
17 int d;
18 for(size_t i = 0; i < expr.length(); i++) {
19 switch(expr[i]) {
20 case 'C':
21 y = expr.find_first_of("z", i);
22 if(y > expr.length())
23 return "#syntax (noterm)";
24 t = _expr.substr(i + 1, y - i - 1);
25 if(t.length() > 2 && t.substr(0, 2) == "0x") {
26 char* end;
27 s.push(strtoull(t.c_str() + 2, &end, 16));
28 if(*end)
29 return "#syntax (badhex)";
30 } else {
31 char* end;
32 s.push(strtod(t.c_str(), &end));
33 if(*end)
34 return "#syntax (badnum)";
36 i = y;
37 break;
38 case 'R':
39 if(i + 1 == expr.length())
40 return "#syntax (noparam)";
41 d = expr[++i] - '0';
42 a = s.top();
43 s.pop();
44 b = pow(10, d);
45 s.push(floor(b * a + 0.5) / b);
46 break;
47 case 'a':
48 if(s.size() < 1)
49 return "#syntax (underflow)";
50 a = s.top();
51 s.pop();
52 s.push(atan(a));
53 break;
54 case 'A':
55 if(s.size() < 2)
56 return "#syntax (underflow)";
57 a = s.top();
58 s.pop();
59 b = s.top();
60 s.pop();
61 s.push(atan2(a, b));
62 break;
63 case 'c':
64 if(s.size() < 1)
65 return "#syntax (underflow)";
66 a = s.top();
67 s.pop();
68 s.push(cos(a));
69 break;
70 case 'r':
71 if(s.size() < 1)
72 return "#syntax (underflow)";
73 a = s.top();
74 s.pop();
75 s.push(sqrt(a));
76 break;
77 case 's':
78 if(s.size() < 1)
79 return "#syntax (underflow)";
80 a = s.top();
81 s.pop();
82 s.push(sin(a));
83 break;
84 case 't':
85 if(s.size() < 1)
86 return "#syntax (underflow)";
87 a = s.top();
88 s.pop();
89 s.push(tan(a));
90 break;
91 case 'u':
92 if(s.size() < 1)
93 return "#syntax (underflow)";
94 s.push(s.top());
95 break;
96 case 'p':
97 s.push(4 * atan(1));
98 break;
99 case '+':
100 if(s.size() < 2)
101 return "#syntax (underflow)";
102 a = s.top();
103 s.pop();
104 b = s.top();
105 s.pop();
106 s.push(a + b);
107 break;
108 case '-':
109 if(s.size() < 2)
110 return "#syntax (underflow)";
111 a = s.top();
112 s.pop();
113 b = s.top();
114 s.pop();
115 s.push(a - b);
116 break;
117 case '*':
118 if(s.size() < 2)
119 return "#syntax (underflow)";
120 a = s.top();
121 s.pop();
122 b = s.top();
123 s.pop();
124 s.push(a * b);
125 break;
126 case 'i':
127 if(s.size() < 2)
128 return "#syntax (underflow)";
129 a = s.top();
130 s.pop();
131 b = s.top();
132 s.pop();
133 s.push(a / b);
134 break;
135 case '/':
136 if(s.size() < 2)
137 return "#syntax (underflow)";
138 a = s.top();
139 s.pop();
140 b = s.top();
141 s.pop();
142 s.push(static_cast<int64_t>(a / b));
143 break;
144 case '%':
145 if(s.size() < 2)
146 return "#syntax (underflow)";
147 a = s.top();
148 s.pop();
149 b = s.top();
150 s.pop();
151 s.push(a - static_cast<int64_t>(a / b) * b);
152 break;
153 case 'b':
154 if(s.size() < 1)
155 return "#syntax (underflow)";
156 a = s.top();
157 s.pop();
158 s.push(static_cast<int8_t>(memory_read_byte(a)));
159 break;
160 case 'B':
161 if(s.size() < 1)
162 return "#syntax (underflow)";
163 a = s.top();
164 s.pop();
165 s.push(static_cast<uint8_t>(memory_read_byte(a)));
166 break;
167 case 'w':
168 if(s.size() < 1)
169 return "#syntax (underflow)";
170 a = s.top();
171 s.pop();
172 s.push(static_cast<int16_t>(memory_read_word(a)));
173 break;
174 case 'W':
175 if(s.size() < 1)
176 return "#syntax (underflow)";
177 a = s.top();
178 s.pop();
179 s.push(static_cast<uint16_t>(memory_read_word(a)));
180 break;
181 case 'd':
182 if(s.size() < 1)
183 return "#syntax (underflow)";
184 a = s.top();
185 s.pop();
186 s.push(static_cast<int32_t>(memory_read_dword(a)));
187 break;
188 case 'D':
189 if(s.size() < 1)
190 return "#syntax (underflow)";
191 a = s.top();
192 s.pop();
193 s.push(static_cast<uint32_t>(memory_read_dword(a)));
194 break;
195 case 'q':
196 if(s.size() < 1)
197 return "#syntax (underflow)";
198 a = s.top();
199 s.pop();
200 s.push(static_cast<int64_t>(memory_read_qword(a)));
201 break;
202 case 'Q':
203 if(s.size() < 1)
204 return "#syntax (underflow)";
205 a = s.top();
206 s.pop();
207 s.push(static_cast<uint64_t>(memory_read_qword(a)));
208 break;
209 default:
210 return "#syntax (illchar)";
213 if(s.empty())
214 return "#ERR";
215 else {
216 char buffer[512];
217 sprintf(buffer, "%f", s.top());
218 return buffer;