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