1 /*
2 * This file is part of HexEditor plugin for Code::Blocks Studio
3 * Copyright (C) 2008-2009 Bartlomiej Swiecki
4 *
5 * HexEditor plugin is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * HexEditor pluging is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with HexEditor. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * $Revision: 7109 $
19 * $Id: ExpressionPreprocessed.h 7109 2011-04-15 11:53:16Z mortenmacfly $
20 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/plugins/contrib/HexEditor/ExpressionPreprocessed.h $
21 */
22 
23 #ifndef EXPRESSIONPREPROCESSED_H
24 #define EXPRESSIONPREPROCESSED_H
25 
26 #include <vector>
27 #include <ostream>
28 #include <wx/string.h>
29 
30 namespace Expression
31 {
32     /** \brief Errors which may occur on the execution */
33     enum executionError
34     {
35         executedSuccessfully,
36         errorArgumentIndex,
37         errorOperationIndex,
38         errorStackIndex,
39         errorContentIndex,
40         errorOperation,
41         errorDivByZero,
42         errorType,
43         errorScript,
44     };
45 
46     /** \brief Holder for value type */
47     class Value
48     {
49         public:
50 
Value(signed char v)51             Value( signed char v        ) { SetSignedInt( v ); }
Value(signed short v)52             Value( signed short v       ) { SetSignedInt( v ); }
Value(signed int v)53             Value( signed int v         ) { SetSignedInt( v ); }
Value(signed long v)54             Value( signed long v        ) { SetSignedInt( v ); }
Value(signed long long v)55             Value( signed long long v   ) { SetSignedInt( v ); }
Value(unsigned char v)56             Value( unsigned char v      ) { SetUnsignedInt( v ); }
Value(unsigned short v)57             Value( unsigned short v     ) { SetUnsignedInt( v ); }
Value(unsigned int v)58             Value( unsigned int v       ) { SetUnsignedInt( v ); }
Value(unsigned long v)59             Value( unsigned long v      ) { SetUnsignedInt( v ); }
Value(unsigned long long v)60             Value( unsigned long long v ) { SetUnsignedInt( v ); }
Value(float v)61             Value( float v              ) { SetFloat( v ); }
Value(double v)62             Value( double v             ) { SetFloat( v ); }
Value(long double v)63             Value( long double v        ) { SetFloat( v ); }
64 
65             //Value( const Value& copyFrom );
66 
IsSignedInt()67             inline bool IsSignedInt()   { return m_Type == tSignedInt; }
IsUnsignedInt()68             inline bool IsUnsignedInt() { return m_Type == tUnsignedInt; }
IsFloat()69             inline bool IsFloat()       { return m_Type == tFloat; }
70 
GetSignedInt()71             inline signed long long   GetSignedInt()   { if ( !IsSignedInt()   ) throw errorType; return m_SignedInt; }
GetUnsignedInt()72             inline unsigned long long GetUnsignedInt() { if ( !IsUnsignedInt() ) throw errorType; return m_UnsignedInt; }
GetFloat()73             inline long double        GetFloat()       { if ( !IsFloat()       ) throw errorType; return m_Float; }
74 
75             //Value& operator= ( const Value& copyFrom );
76             bool operator< ( const Value& second ) const;
77 
78             template< typename T >
79             inline bool operator== ( T value )
80             {
81                 if ( IsSignedInt()   ) return value == (T)m_SignedInt;
82                 if ( IsUnsignedInt() ) return value == (T)m_UnsignedInt;
83                 if ( IsFloat()       ) return value == (T)m_Float;
84                 return false;
85             }
86 
87             template< typename T >
88             inline bool operator< ( T value )
89             {
90                 if ( IsSignedInt()   ) return value > (T)m_SignedInt;
91                 if ( IsUnsignedInt() ) return value > (T)m_UnsignedInt;
92                 if ( IsFloat()       ) return value > (T)m_Float;
93                 return false;
94             }
95 
96             template< typename T >
97             inline bool operator<= ( T value )
98             {
99                 if ( IsSignedInt()   ) return value >= (T)m_SignedInt;
100                 if ( IsUnsignedInt() ) return value >= (T)m_UnsignedInt;
101                 if ( IsFloat()       ) return value >= (T)m_Float;
102                 return false;
103             }
104 
105             template< typename T >
106             inline bool operator> ( T value )
107             {
108                 return !operator<= ( value );
109             }
110 
111             template< typename T >
112             inline bool operator>= ( T value )
113             {
114                 return !operator< ( value );
115             }
116 
117             friend inline std::ostream& operator<< ( std::ostream& out, Value& v )
118             {
119                 if ( v.IsSignedInt()   ) out << v.m_SignedInt << "(sint)";
120                 if ( v.IsUnsignedInt() ) out << v.m_UnsignedInt << "(uint)";
121                 if ( v.IsFloat()       ) out << v.m_Float << "(float)";
122                 return out;
123             }
124 
125         private:
126 
127             enum TypeT
128             {
129                 tSignedInt,
130                 tUnsignedInt,
131                 tFloat
132             };
133 
134             TypeT m_Type;
135 
136             union
137             {
138                 signed   long long m_SignedInt;
139                 unsigned long long m_UnsignedInt;
140                 long double        m_Float;
141             };
142 
SetSignedInt(T v)143             template< typename T > inline void SetSignedInt( T v )
144             {
145                 m_Type = tSignedInt;
146                 m_SignedInt = v;
147             }
148 
SetUnsignedInt(T v)149             template< typename T > inline void SetUnsignedInt( T v )
150             {
151                 m_Type = tUnsignedInt;
152                 m_SignedInt = v;
153             }
154 
SetFloat(T v)155             template< typename T > inline void SetFloat( T v )
156             {
157                 m_Type = tFloat;
158                 m_Float = v;
159             }
160     };
161 
162     /** \brief Structure of one opcode */
163     struct Operation
164     {
165         /** \brief Operation's code */
166         enum opCode
167         {
168             // Notyfi aboud the end of the script
169             endScript = 0,
170 
171             // Push "current" address onto stack top modified with const argument
172             pushCurrent,
173 
174             // load value from memory at address given at the stack top
175             // and push the result back onto the stack
176             loadMem,
177 
178             // get address from const argument,
179             // read proper value from the memory and push it onto the stack
180             // value is loaded from the code arguments array
181             loadArg,
182 
183             // Simple arithmetic operations, pops two operands from stack top
184             // and push the result onto the stack
185             add,
186             mul,
187             div,
188             mod,
189 
190             // Unary operators, pops operand from stack top and push the result
191             neg,
192             conv,
193 
194             // Call to function with one argument, arg popped from the stack, result pushed back
195             fnSin,
196             fnCos,
197             fnTan,
198             fnLn,
199 
200             // Call to function with two arguments
201             fnPow,
202 
203         };
204 
205         // Argument modifiers
206         enum modifier
207         {
208             modNone,
209             modArg,
210             modChar,
211             modByte,
212             modShort,
213             modWord,
214             modLong,
215             modDword,
216             modLongLong,
217             modQword,
218             modFloat,
219             modDouble,
220             modLongDouble,
221         };
222 
223         unsigned m_OpCode: 8;
224         unsigned m_Mod1:   4;
225         unsigned m_Mod2:   4;
226 
227         short m_ConstArgument;
228     };
229 
230 
231     /** \brief Preprocessed expression */
232     class Preprocessed
233     {
234         public:
235 
236             /** \brief Ctor */
237             Preprocessed();
238 
239             /** \brief Dctor */
240             ~Preprocessed();
241 
242             /** \brief Clearing the code */
Clear()243             inline void Clear()
244             {
245                 m_CodeArguments.clear();
246                 m_Code.clear();
247             }
248 
249             /** \brief Push operation onto the end of code */
PushOperation(const Operation & op)250             inline int PushOperation( const Operation& op )
251             {
252                 m_Code.push_back( op );
253                 return (int)m_Code.size()-1;
254             }
255 
256             /** \brief Push argumet onto the end of constant arguments list */
PushArgument(const Value & v)257             inline int PushArgument( const Value& v )
258             {
259                 m_CodeArguments.push_back( v );
260                 return (int)m_CodeArguments.size()-1;
261             }
262 
263             /** \brief Get operation at given position */
GetOperation(int pos)264             inline const Operation& GetOperation( int pos ) const
265             {
266                 if ( (size_t)pos >= m_Code.size() ) throw errorOperationIndex;
267                 return m_Code[ pos ];
268             }
269 
270             /** \brief Get argument at given position */
GetArgument(int pos)271             inline const Value& GetArgument( int pos ) const
272             {
273                 if ( (size_t)pos >= m_CodeArguments.size() ) throw errorArgumentIndex;
274                 return m_CodeArguments[ pos ];
275             }
276 
277             /** \brief Dump the code as asm into human-readable form */
278             wxString DumpCode();
279 
280             /** \brief Dump arguments into himan-readable form */
281             wxString DumpArgs();
282 
283         private:
284 
285             std::vector< Value >     m_CodeArguments;       ///< \brief list of arguments
286             std::vector< Operation > m_Code;                ///< \brief the code
287     };
288 }
289 
290 #endif
291