-
Notifications
You must be signed in to change notification settings - Fork 3
/
CalculatorEngine.h
178 lines (126 loc) · 4.68 KB
/
CalculatorEngine.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#ifndef CalculatorEngineH
#define CalculatorEngineH
// -----------------------------------------------------------------------------
// ---- various defines and enumeration types
#define RPNSTACK_MAX 50
enum eTrigMode {eTrigRad, eTrigDeg, eTrigGrad};
enum eBaseMode {eBaseHex, eBaseDec, eBaseOct, eBaseBin};
enum eCalcOperator {eOpNone,
eOpPlus, eOpMinus, eOpDiv, eOpMul, // Two value operators
eOpCHS, // Change sign
eOPRND, // random number
eOpMeanStddev, // calc mean and stddev of stack
eOpX2, eOpLN, eOpLOG, wOp1divX,
eOpSqrt, eOpeX, eOp10X, eOpyX,
eOpSin, eOpCos, eOpTan,
eOpSinh, eOpCosh, eOpTanh,
eOpToRAD,eOpToDEG, eOpToGrad, eOpFAC, eOpPercent,
eOpFrac, eOpeInt, eOpAbs, eOpSwapXY,
eOpArcSin, eOpArcCos, eOpArcTan,
eOpArcSinh, eOpArcCosh, eOpArcTanh,
// comp operators
eOpLSH, eOpRSH, eOpMOD, eOpBIT,
eOpAND, eOpOR, eOpNOT, eOpXOR
};
// -----------------------------------------------------------------------------
// ---- TRPNStackValue definition
class TRPNStackValue : public TObject
{
private:
long double m_double; // double presition value (used for decimal calculations
unsigned long long m_ulong; // unsigned 64 bit integer used for bin/oct and hex calculations
public:
__fastcall TRPNStackValue();
void Set(TRPNStackValue *v);
void SetD(long double d);
void SetI(unsigned long long ui);
void Set(AnsiString text, eBaseMode base);
long double GetD();
unsigned long long GetI();
};
// -----------------------------------------------------------------------------
// ---- TRPNStack definition
class TRPNStack : public TObjectList
{
private:
public:
__fastcall TRPNStack();
void Push(AnsiString value, eBaseMode base);
void Push(TRPNStackValue *v);
void PushD(long double d);
void PushI(unsigned long long ui);
bool Peek(int position, TRPNStackValue *v);
bool PeekD(int position, long double &d);
bool PeekI(int position, unsigned long long &ui);
bool Pop(TRPNStackValue *v);
bool PopD(long double &d);
bool PopI(unsigned long long &ui);
};
class TCalculatorEngine : public TObject
{
protected:
TRPNStack *m_stack;
bool m_request_sto;
bool m_request_rcl;
bool m_request_inverse;
bool m_request_hyperbolic;
AnsiString m_editor;
eTrigMode m_trig_mode;
eBaseMode m_base_mode;
int m_decimal_char;
bool m_last_key_was_e;
int m_significant_digits;
AnsiString m_last_error;
// memory
TRPNStackValue *m_memory[10];
// events
TNotifyEvent f_on_stack_change;
TNotifyEvent f_on_mode_change;
TNotifyEvent f_on_error;
protected:
AnsiString RPNStackValueToText(TRPNStackValue *v);
void PushKeyToEditor(int key);
bool PopRegister(TRPNStackValue *v);
inline bool PushRegister(TRPNStackValue *v) {m_stack->Push(v);};
bool CheckRequiredVarCount(int count, AnsiString error_message);
bool RequireBase(eBaseMode mode);
bool RealizeStack();
long double EnsureRAD(long double d);
long double EnsureTrigMode(long double d);
bool SetError(AnsiString err);
public:
__fastcall TCalculatorEngine();
__fastcall ~TCalculatorEngine();
// Memory handling
bool Store(int slot);
bool Recall(int slot);
AnsiString PeekMemory(int slot);
// Interface handlers
void ProcessChar(char key);
void ProcessKey(TShiftState shift, int key);
bool ProcessOperator(eCalcOperator op);
bool EnterDecimalSeperator();
void PushValueD(long double d);
void PushValueI(unsigned long long ui);
// property handlers
void __fastcall SetTrigMode(eTrigMode m);
void __fastcall SetBaseMode(eBaseMode m);
AnsiString __fastcall GetRegisterValue(int position);
void __fastcall SetRequestInverse(bool f);
void __fastcall SetRequestHyperbolic(bool f);
void __fastcall SetSignificantDigits(int n);
// properties
__property eTrigMode TrigMode = {read=m_trig_mode, write=SetTrigMode};
__property eBaseMode BaseMode = {read=m_base_mode, write=SetBaseMode};
__property bool RequestInverse = {read=m_request_inverse, write=SetRequestInverse};
__property bool RequestHyperbolic = {read=m_request_hyperbolic, write=SetRequestHyperbolic};
__property int SignificantDigits = {read=m_significant_digits, write=SetSignificantDigits};
__property AnsiString RegisterValue[int position] = {read=GetRegisterValue};
__property AnsiString LastError = {read=m_last_error};
__property int DecimalChar = {read=m_decimal_char};
// Events
__property TNotifyEvent OnStackChange = {read=f_on_stack_change, write=f_on_stack_change};
__property TNotifyEvent OnModeChange = {read=f_on_mode_change, write=f_on_mode_change};
__property TNotifyEvent OnError = {read=f_on_error, write=f_on_error};
};
#endif