1 // -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi:tw=80:et:ts=2:sts=2 3 // 4 // ----------------------------------------------------------------------- 5 // 6 // This file is part of libreallive, a dependency of RLVM. 7 // 8 // ----------------------------------------------------------------------- 9 // 10 // Copyright (c) 2006 Peter Jolly 11 // Copyright (c) 2007 Elliot Glaysher 12 // 13 // Permission is hereby granted, free of charge, to any person 14 // obtaining a copy of this software and associated documentation 15 // files (the "Software"), to deal in the Software without 16 // restriction, including without limitation the rights to use, copy, 17 // modify, merge, publish, distribute, sublicense, and/or sell copies 18 // of the Software, and to permit persons to whom the Software is 19 // furnished to do so, subject to the following conditions: 20 // 21 // The above copyright notice and this permission notice shall be 22 // included in all copies or substantial portions of the Software. 23 // 24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 // SOFTWARE. 32 // 33 // ----------------------------------------------------------------------- 34 35 #ifndef SRC_LIBREALLIVE_EXPRESSION_H_ 36 #define SRC_LIBREALLIVE_EXPRESSION_H_ 37 38 #include <memory> 39 #include <string> 40 #include <vector> 41 42 #include "machine/reference.h" 43 44 class RLMachine; 45 46 namespace libreallive { 47 48 // Size of expression functions 49 size_t NextToken(const char* src); 50 size_t NextExpression(const char* src); 51 size_t NextString(const char* src); 52 size_t NextData(const char* src); 53 54 // Parse expression functions 55 class ExpressionPiece; 56 ExpressionPiece GetExpressionToken(const char*& src); 57 ExpressionPiece GetExpressionTerm(const char*& src); 58 ExpressionPiece GetExpressionArithmatic(const char*& src); 59 ExpressionPiece GetExpressionCondition(const char*& src); 60 ExpressionPiece GetExpressionBoolean(const char*& src); 61 ExpressionPiece GetExpression(const char*& src); 62 ExpressionPiece GetAssignment(const char*& src); 63 ExpressionPiece GetData(const char*& src); 64 ExpressionPiece GetComplexParam(const char*& src); 65 66 std::string EvaluatePRINT(RLMachine& machine, const std::string& in); 67 68 // Converts a parameter string (as read from the binary SEEN.TXT file) 69 // into a human readable (and printable) format. 70 std::string ParsableToPrintableString(const std::string& src); 71 72 // Converts a printable string (i.e., "$ 05 [ $ FF EE 03 00 00 ]") 73 // into one that can be parsed by all the get_expr family of functions. 74 std::string PrintableToParsableString(const std::string& src); 75 76 enum ExpressionValueType { 77 ValueTypeInteger, 78 ValueTypeString 79 }; 80 81 enum ExpressionPieceType { 82 TYPE_STORE_REGISTER, 83 TYPE_INT_CONSTANT, 84 TYPE_STRING_CONSTANT, 85 TYPE_MEMORY_REFERENCE, 86 TYPE_SIMPLE_MEMORY_REFERENCE, 87 TYPE_UNIARY_EXPRESSION, 88 TYPE_BINARY_EXPRESSION, 89 TYPE_SIMPLE_ASSIGNMENT, 90 TYPE_COMPLEX_EXPRESSION, 91 TYPE_SPECIAL_EXPRESSION, 92 TYPE_INVALID 93 }; 94 95 struct invalid_expression_piece_t {}; 96 97 class ExpressionPiece { 98 public: 99 static ExpressionPiece StoreRegister(); 100 static ExpressionPiece IntConstant(const int constant); 101 static ExpressionPiece StrConstant(const std::string constant); 102 static ExpressionPiece MemoryReference(const int type, 103 ExpressionPiece location); 104 static ExpressionPiece UniaryExpression(const char operation, 105 ExpressionPiece operand); 106 static ExpressionPiece BinaryExpression(const char operation, 107 ExpressionPiece lhs, 108 ExpressionPiece rhs); 109 static ExpressionPiece ComplexExpression(); 110 static ExpressionPiece SpecialExpression(const int tag); 111 112 ExpressionPiece(invalid_expression_piece_t); 113 ExpressionPiece(const ExpressionPiece& rhs); 114 ExpressionPiece(ExpressionPiece&& rhs); 115 ~ExpressionPiece(); 116 117 ExpressionPiece& operator=(const ExpressionPiece& rhs); 118 ExpressionPiece& operator=(ExpressionPiece&& rhs); 119 is_valid()120 bool is_valid() const { return piece_type != TYPE_INVALID; } 121 122 // Capability method; returns false by default. Override when 123 // ExpressionPiece subclass accesses a piece of memory. 124 bool IsMemoryReference() const; 125 126 // Capability method; returns false by default. Override only in 127 // classes that represent a complex parameter to the type system. 128 // @see Complex_T 129 bool IsComplexParameter() const; 130 131 // Capability method; returns false by default. Override only in 132 // classes that represent a special parameter to the type system. 133 // @see Special_T 134 bool IsSpecialParameter() const; 135 136 // Returns the value type of this expression (i.e. string or 137 // integer) 138 ExpressionValueType GetExpressionValueType() const; 139 140 // Assigns the value into the memory location represented by the 141 // current expression. Not all ExpressionPieces can do this, so 142 // there is a default implementation which does nothing. 143 void SetIntegerValue(RLMachine& machine, int rvalue); 144 145 // Returns the integer value of this expression; this can either be 146 // a memory access or a calculation based on some subexpressions. 147 int GetIntegerValue(RLMachine& machine) const; 148 149 void SetStringValue(RLMachine& machine, const std::string& rvalue); 150 const std::string& GetStringValue(RLMachine& machine) const; 151 152 // I used to be able to just static cast any ExpressionPiece to a 153 // MemoryReference if I wanted/needed a corresponding iterator. Haeleth's 154 // rlBabel library instead uses the store register as an argument to a 155 // function that takes a integer reference. So this needs to be here now. 156 IntReferenceIterator GetIntegerReferenceIterator(RLMachine& machine) const; 157 StringReferenceIterator GetStringReferenceIterator(RLMachine& machine) const; 158 159 // A persistable version of this value. This method should return RealLive 160 // bytecode equal to this ExpressionPiece with all references returned. 161 std::string GetSerializedExpression(RLMachine& machine) const; 162 163 // A printable representation of the expression itself. Used to dump our 164 // parsing of the bytecode to the console. 165 std::string GetDebugString() const; 166 167 // In the case of Complex and Special types, adds an expression piece to the 168 // list. 169 void AddContainedPiece(ExpressionPiece piece); 170 171 const std::vector<ExpressionPiece>& GetContainedPieces() const; 172 173 int GetOverloadTag() const; 174 175 private: 176 ExpressionPiece(); 177 178 // Frees all possible memory and sets |piece_type| to TYPE_INVALID. 179 void Invalidate(); 180 181 // Implementations of some of the public interface where they aren't one 182 // liners. 183 std::string GetComplexSerializedExpression(RLMachine& machine) const; 184 std::string GetSpecialSerializedExpression(RLMachine& machine) const; 185 186 std::string GetMemoryDebugString(int type, 187 const std::string& location) const; 188 std::string GetUniaryDebugString() const; 189 std::string GetBinaryDebugString(char operation, 190 const std::string& lhs, 191 const std::string& rhs) const; 192 std::string GetComplexDebugString() const; 193 std::string GetSpecialDebugString() const; 194 195 int PerformUniaryOperationOn(int int_operand) const; 196 static int PerformBinaryOperationOn(char operand, int lhs, int rhs); 197 198 ExpressionPieceType piece_type; 199 200 union { 201 // TYPE_INT_CONSTANT 202 int int_constant; 203 204 // TYPE_STRING_CONSTANT 205 std::string str_constant; 206 207 // TYPE_MEMORY_REFERENCE 208 struct { 209 int type; 210 ExpressionPiece* location; 211 } mem_reference; 212 213 // TYPE_SIMPLE_MEMORY_REFERENCE 214 struct { 215 int type; 216 int location; 217 } simple_mem_reference; 218 219 // TYPE_UNIARY_EXPRESSION 220 struct { 221 char operation; 222 ExpressionPiece* operand; 223 } uniary_expression; 224 225 // TYPE_BINARY_EXPRESSION 226 struct { 227 char operation; 228 ExpressionPiece* left_operand; 229 ExpressionPiece* right_operand; 230 } binary_expression; 231 232 // TYPE_SIMPLE_ASSIGNMENT 233 struct { 234 int type; 235 int location; 236 int value; 237 } simple_assignment; 238 239 // TYPE_COMPLEX_EXPRESSION 240 std::vector<ExpressionPiece> complex_expression; 241 242 // TYPE_SPECIAL_EXPRESSION 243 struct { 244 int overload_tag; 245 std::vector<ExpressionPiece> pieces; 246 } special_expression; 247 }; 248 }; 249 250 typedef std::vector<libreallive::ExpressionPiece> ExpressionPiecesVector; 251 252 } // namespace libreallive 253 254 #endif // SRC_LIBREALLIVE_EXPRESSION_H_ 255