1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef DEBUGGER_EXPRESSIONS_HXX
19#define DEBUGGER_EXPRESSIONS_HXX
20
21#include <functional>
22
23#include "bspf.hxx"
24#include "CartDebug.hxx"
25#include "CpuDebug.hxx"
26#include "TIADebug.hxx"
27#include "Debugger.hxx"
28#include "Expression.hxx"
29
30/**
31 All expressions currently supported by the debugger.
32 @author B. Watson and Stephen Anthony
33*/
34
35// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
36class BinAndExpression : public Expression
37{
38 public:
39 BinAndExpression(Expression* left, Expression* right) : Expression(left, right) { }
40 Int32 evaluate() const override
41 { return myLHS->evaluate() & myRHS->evaluate(); }
42};
43
44// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
45class BinNotExpression : public Expression
46{
47 public:
48 BinNotExpression(Expression* left) : Expression(left) { }
49 Int32 evaluate() const override
50 { return ~(myLHS->evaluate()); }
51};
52
53// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
54class BinOrExpression : public Expression
55{
56 public:
57 BinOrExpression(Expression* left, Expression* right) : Expression(left, right) { }
58 Int32 evaluate() const override
59 { return myLHS->evaluate() | myRHS->evaluate(); }
60};
61
62// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
63class BinXorExpression : public Expression
64{
65 public:
66 BinXorExpression(Expression* left, Expression* right) : Expression(left, right) { }
67 Int32 evaluate() const override
68 { return myLHS->evaluate() ^ myRHS->evaluate(); }
69};
70
71// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
72class ByteDerefExpression : public Expression
73{
74 public:
75 ByteDerefExpression(Expression* left): Expression(left) { }
76 Int32 evaluate() const override
77 { return Debugger::debugger().peek(myLHS->evaluate()); }
78};
79
80// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81class ByteDerefOffsetExpression : public Expression
82{
83 public:
84 ByteDerefOffsetExpression(Expression* left, Expression* right) : Expression(left, right) { }
85 Int32 evaluate() const override
86 { return Debugger::debugger().peek(myLHS->evaluate() + myRHS->evaluate()); }
87};
88
89// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
90class ConstExpression : public Expression
91{
92 public:
93 ConstExpression(const int value) : Expression(), myValue(value) { }
94 Int32 evaluate() const override
95 { return myValue; }
96
97 private:
98 int myValue;
99};
100
101// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
102class CpuMethodExpression : public Expression
103{
104 public:
105 CpuMethodExpression(CpuMethod method) : Expression(), myMethod(std::mem_fn(method)) { }
106 Int32 evaluate() const override
107 { return myMethod(Debugger::debugger().cpuDebug()); }
108
109 private:
110 std::function<int(const CpuDebug&)> myMethod;
111};
112
113// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
114class DivExpression : public Expression
115{
116 public:
117 DivExpression(Expression* left, Expression* right) : Expression(left, right) { }
118 Int32 evaluate() const override
119 { int denom = myRHS->evaluate();
120 return denom == 0 ? 0 : myLHS->evaluate() / denom; }
121};
122
123// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
124class EqualsExpression : public Expression
125{
126 public:
127 EqualsExpression(Expression* left, Expression* right) : Expression(left, right) { }
128 Int32 evaluate() const override
129 { return myLHS->evaluate() == myRHS->evaluate(); }
130};
131
132// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133class EquateExpression : public Expression
134{
135 public:
136 EquateExpression(const string& label) : Expression(), myLabel(label) { }
137 Int32 evaluate() const override
138 { return Debugger::debugger().cartDebug().getAddress(myLabel); }
139
140 private:
141 string myLabel;
142};
143
144// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
145class FunctionExpression : public Expression
146{
147 public:
148 FunctionExpression(const string& label) : Expression(), myLabel(label) { }
149 Int32 evaluate() const override
150 { return Debugger::debugger().getFunction(myLabel).evaluate(); }
151
152 private:
153 string myLabel;
154};
155
156// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
157class GreaterEqualsExpression : public Expression
158{
159 public:
160 GreaterEqualsExpression(Expression* left, Expression* right) : Expression(left, right) { }
161 Int32 evaluate() const override
162 { return myLHS->evaluate() >= myRHS->evaluate(); }
163};
164
165// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
166class GreaterExpression : public Expression
167{
168 public:
169 GreaterExpression(Expression* left, Expression* right) : Expression(left, right) { }
170 Int32 evaluate() const override
171 { return myLHS->evaluate() > myRHS->evaluate(); }
172};
173
174// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
175class HiByteExpression : public Expression
176{
177 public:
178 HiByteExpression(Expression* left) : Expression(left) { }
179 Int32 evaluate() const override
180 { return 0xff & (myLHS->evaluate() >> 8); }
181};
182
183// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
184class LessEqualsExpression : public Expression
185{
186 public:
187 LessEqualsExpression(Expression* left, Expression* right) : Expression(left, right) { }
188 Int32 evaluate() const override
189 { return myLHS->evaluate() <= myRHS->evaluate(); }
190};
191
192// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
193class LessExpression : public Expression
194{
195 public:
196 LessExpression(Expression* left, Expression* right) : Expression(left, right) { }
197 Int32 evaluate() const override
198 { return myLHS->evaluate() < myRHS->evaluate(); }
199};
200
201// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202class LoByteExpression : public Expression
203{
204 public:
205 LoByteExpression(Expression* left) : Expression(left) { }
206 Int32 evaluate() const override
207 { return 0xff & myLHS->evaluate(); }
208};
209
210// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
211class LogAndExpression : public Expression
212{
213 public:
214 LogAndExpression(Expression* left, Expression* right) : Expression(left, right) { }
215 Int32 evaluate() const override
216 { return myLHS->evaluate() && myRHS->evaluate(); }
217};
218
219// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
220class LogNotExpression : public Expression
221{
222 public:
223 LogNotExpression(Expression* left) : Expression(left) { }
224 Int32 evaluate() const override
225 { return !(myLHS->evaluate()); }
226};
227
228// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
229class LogOrExpression : public Expression
230{
231 public:
232 LogOrExpression(Expression* left, Expression* right) : Expression(left, right) { }
233 Int32 evaluate() const override
234 { return myLHS->evaluate() || myRHS->evaluate(); }
235};
236
237// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
238class MinusExpression : public Expression
239{
240 public:
241 MinusExpression(Expression* left, Expression* right) : Expression(left, right) { }
242 Int32 evaluate() const override
243 { return myLHS->evaluate() - myRHS->evaluate(); }
244};
245
246// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
247class ModExpression : public Expression
248{
249 public:
250 ModExpression(Expression* left, Expression* right) : Expression(left, right) { }
251 Int32 evaluate() const override
252 { int rhs = myRHS->evaluate();
253 return rhs == 0 ? 0 : myLHS->evaluate() % rhs; }
254};
255
256// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
257class MultExpression : public Expression
258{
259 public:
260 MultExpression(Expression* left, Expression* right) : Expression(left, right) { }
261 Int32 evaluate() const override
262 { return myLHS->evaluate() * myRHS->evaluate(); }
263};
264
265// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
266class NotEqualsExpression : public Expression
267{
268 public:
269 NotEqualsExpression(Expression* left, Expression* right) : Expression(left, right) { }
270 Int32 evaluate() const override
271 { return myLHS->evaluate() != myRHS->evaluate(); }
272};
273
274// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
275class PlusExpression : public Expression
276{
277 public:
278 PlusExpression(Expression* left, Expression* right) : Expression(left, right) { }
279 Int32 evaluate() const override
280 { return myLHS->evaluate() + myRHS->evaluate(); }
281};
282
283// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
284class CartMethodExpression : public Expression
285{
286 public:
287 CartMethodExpression(CartMethod method) : Expression(), myMethod(std::mem_fn(method)) { }
288 Int32 evaluate() const override
289 { return myMethod(Debugger::debugger().cartDebug()); }
290
291 private:
292 std::function<int(CartDebug&)> myMethod;
293};
294
295// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
296class ShiftLeftExpression : public Expression
297{
298 public:
299 ShiftLeftExpression(Expression* left, Expression* right) : Expression(left, right) { }
300 Int32 evaluate() const override
301 { return myLHS->evaluate() << myRHS->evaluate(); }
302};
303
304// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
305class ShiftRightExpression : public Expression
306{
307 public:
308 ShiftRightExpression(Expression* left, Expression* right) : Expression(left, right) { }
309 Int32 evaluate() const override
310 { return myLHS->evaluate() >> myRHS->evaluate(); }
311};
312
313// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
314class TiaMethodExpression : public Expression
315{
316 public:
317 TiaMethodExpression(TiaMethod method) : Expression(), myMethod(std::mem_fn(method)) { }
318 Int32 evaluate() const override
319 { return myMethod(Debugger::debugger().tiaDebug()); }
320
321 private:
322 std::function<int(const TIADebug&)> myMethod;
323};
324
325// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
326class UnaryMinusExpression : public Expression
327{
328 public:
329 UnaryMinusExpression(Expression* left) : Expression(left) { }
330 Int32 evaluate() const override
331 { return -(myLHS->evaluate()); }
332};
333
334// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
335class WordDerefExpression : public Expression
336{
337 public:
338 WordDerefExpression(Expression* left) : Expression(left) { }
339 Int32 evaluate() const override
340 { return Debugger::debugger().dpeekAsInt(myLHS->evaluate()); }
341};
342
343#endif
344