1 /* 2 * The Doomsday Engine Project -- libcore 3 * 4 * Copyright © 2004-2017 Jaakko Keränen <jaakko.keranen@iki.fi> 5 * 6 * @par License 7 * LGPL: http://www.gnu.org/licenses/lgpl.html 8 * 9 * <small>This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU Lesser General Public License as published by 11 * the Free Software Foundation; either version 3 of the License, or (at your 12 * option) any later version. This program is distributed in the hope that it 13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15 * General Public License for more details. You should have received a copy of 16 * the GNU Lesser General Public License along with this program; if not, see: 17 * http://www.gnu.org/licenses</small> 18 */ 19 20 #ifndef LIBDENG2_EXPRESSION_H 21 #define LIBDENG2_EXPRESSION_H 22 23 #include "../ISerializable" 24 25 #include <QFlags> 26 27 namespace de { 28 29 class Evaluator; 30 class Value; 31 class Record; 32 33 /** 34 * Base class for expressions. 35 * 36 * @note All expression classes must call the serialization methods of this class 37 * so that the expression flags are properly serialized. 38 * 39 * @ingroup script 40 */ 41 class DENG2_PUBLIC Expression : public ISerializable 42 { 43 public: 44 /// Deserialization of an expression failed. @ingroup errors 45 DENG2_ERROR(DeserializationError); 46 47 // Flags for evaluating expressions. 48 // Note: these are serialized as is, so don't change the existing values. 49 enum Flag 50 { 51 /// Evaluates to a value. In conjunction with IMPORT, causes the imported 52 /// record to be copied to the local namespace. 53 ByValue = 0x1, 54 55 /// Evaluates to a reference. 56 ByReference = 0x2, 57 58 /// If missing, create a new variable. 59 NewVariable = 0x4, 60 61 /// If missing, create a new subrecord (i.e., Variable that owns a Record). 62 NewSubrecord = 0x8, 63 64 /// Identifier must exist and will be deleted. 65 //Delete = 0x10, 66 67 /// Imports an external namespace into the local namespace (as a reference). 68 Import = 0x20, 69 70 /// Look for object in local namespace only. 71 LocalOnly = 0x40, 72 73 /// If the identifier is in scope, returns a reference to the process's 74 /// throwaway variable. 75 ThrowawayIfInScope = 0x80, 76 77 /// Identifier must not already exist in scope. 78 NotInScope = 0x100, 79 80 /// Variable will be set to read-only mode. 81 ReadOnly = 0x200, 82 83 // Variable will be raised into a higher namespace. 84 //Export = 0x400, 85 86 /// If missing, create a new subrecord. Otherwise, reuse the existing record. 87 NewSubrecordIfNotInScope = 0x800 88 }; 89 Q_DECLARE_FLAGS(Flags, Flag) 90 91 public: 92 Expression(); 93 94 virtual ~Expression(); 95 96 virtual void push(Evaluator &evaluator, Value *scope = 0) const; 97 98 virtual Value *evaluate(Evaluator &evaluator) const = 0; 99 100 /** 101 * Returns the flags of the expression. 102 */ 103 Flags const &flags () const; 104 105 /** 106 * Sets the flags of the expression. 107 * 108 * @param f Flags to set. 109 * @param operation Operation to perform on the flags. 110 */ 111 void setFlags(Flags f, FlagOp operation = ReplaceFlags); 112 113 /** 114 * Subclasses must call this in their serialization method. 115 */ 116 void operator >> (Writer &to) const; 117 118 /** 119 * Subclasses must call this in their deserialization method. 120 */ 121 void operator << (Reader &from); 122 123 public: 124 /** 125 * Constructs an expression by deserializing one from a reader. 126 * 127 * @param reader Reader. 128 * 129 * @return The deserialized expression. Caller gets ownership. 130 */ 131 static Expression *constructFrom(Reader &reader); 132 133 protected: 134 typedef dbyte SerialId; 135 136 enum SerialIds { 137 ARRAY, 138 BUILT_IN, 139 CONSTANT, 140 DICTIONARY, 141 NAME, 142 OPERATOR 143 }; 144 145 private: 146 Flags _flags; 147 }; 148 149 Q_DECLARE_OPERATORS_FOR_FLAGS(Expression::Flags) 150 151 } // namespace de 152 153 #endif /* LIBDENG2_EXPRESSION_H */ 154