1 /* 2 * Copyright 2020 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SKSL_DSL_EXPRESSION 9 #define SKSL_DSL_EXPRESSION 10 11 #include "include/core/SkStringView.h" 12 #include "include/core/SkTypes.h" 13 #include "include/private/SkTArray.h" 14 #include "include/sksl/DSLWrapper.h" 15 #include "include/sksl/SkSLErrorReporter.h" 16 17 #include <cstdint> 18 #include <memory> 19 20 #if defined(__has_cpp_attribute) && __has_cpp_attribute(clang::reinitializes) 21 #define SK_CLANG_REINITIALIZES [[clang::reinitializes]] 22 #else 23 #define SK_CLANG_REINITIALIZES 24 #endif 25 26 namespace SkSL { 27 28 class Expression; 29 class Type; 30 31 namespace dsl { 32 33 class DSLPossibleExpression; 34 class DSLStatement; 35 class DSLType; 36 class DSLVarBase; 37 38 /** 39 * Represents an expression such as 'cos(x)' or 'a + b'. 40 */ 41 class DSLExpression { 42 public: 43 DSLExpression(const DSLExpression&) = delete; 44 45 DSLExpression(DSLExpression&&); 46 47 DSLExpression(); 48 49 /** 50 * Creates an expression representing a literal float. 51 */ 52 DSLExpression(float value, PositionInfo pos = PositionInfo::Capture()); 53 54 /** 55 * Creates an expression representing a literal float. 56 */ 57 DSLExpression(double value, PositionInfo pos = PositionInfo::Capture()) 58 : DSLExpression((float) value) {} 59 60 /** 61 * Creates an expression representing a literal int. 62 */ 63 DSLExpression(int value, PositionInfo pos = PositionInfo::Capture()); 64 65 /** 66 * Creates an expression representing a literal int. 67 */ 68 DSLExpression(int64_t value, PositionInfo pos = PositionInfo::Capture()); 69 70 /** 71 * Creates an expression representing a literal uint. 72 */ 73 DSLExpression(unsigned int value, PositionInfo pos = PositionInfo::Capture()); 74 75 /** 76 * Creates an expression representing a literal bool. 77 */ 78 DSLExpression(bool value, PositionInfo pos = PositionInfo::Capture()); 79 80 /** 81 * Creates an expression representing a variable reference. 82 */ 83 DSLExpression(DSLVarBase& var, PositionInfo pos = PositionInfo::Capture()); 84 85 DSLExpression(DSLVarBase&& var, PositionInfo pos = PositionInfo::Capture()); 86 87 DSLExpression(DSLPossibleExpression expr, PositionInfo pos = PositionInfo::Capture()); 88 89 explicit DSLExpression(std::unique_ptr<SkSL::Expression> expression); 90 91 static DSLExpression Poison(PositionInfo pos = PositionInfo::Capture()); 92 93 ~DSLExpression(); 94 95 DSLType type(); 96 97 /** 98 * Overloads the '=' operator to create an SkSL assignment statement. 99 */ 100 DSLPossibleExpression operator=(DSLExpression other); 101 102 DSLExpression x(PositionInfo pos = PositionInfo::Capture()); 103 104 DSLExpression y(PositionInfo pos = PositionInfo::Capture()); 105 106 DSLExpression z(PositionInfo pos = PositionInfo::Capture()); 107 108 DSLExpression w(PositionInfo pos = PositionInfo::Capture()); 109 110 DSLExpression r(PositionInfo pos = PositionInfo::Capture()); 111 112 DSLExpression g(PositionInfo pos = PositionInfo::Capture()); 113 114 DSLExpression b(PositionInfo pos = PositionInfo::Capture()); 115 116 DSLExpression a(PositionInfo pos = PositionInfo::Capture()); 117 118 /** 119 * Creates an SkSL struct field access expression. 120 */ 121 DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo::Capture()); 122 123 /** 124 * Creates an SkSL array index expression. 125 */ 126 DSLPossibleExpression operator[](DSLExpression index); 127 128 DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args, 129 PositionInfo pos = PositionInfo::Capture()); 130 131 DSLPossibleExpression operator()(ExpressionArray args, 132 PositionInfo pos = PositionInfo::Capture()); 133 134 /** 135 * Returns true if this object contains an expression. DSLExpressions which were created with 136 * the empty constructor or which have already been release()ed do not have a value. 137 * DSLExpressions created with errors are still considered to have a value (but contain poison). 138 */ hasValue()139 bool hasValue() const { 140 return fExpression != nullptr; 141 } 142 143 /** 144 * Returns true if this object contains an expression which is not poison. 145 */ 146 bool isValid() const; 147 148 SK_CLANG_REINITIALIZES void swap(DSLExpression& other); 149 150 /** 151 * Invalidates this object and returns the SkSL expression it represents. It is an error to call 152 * this on an invalid DSLExpression. 153 */ 154 std::unique_ptr<SkSL::Expression> release(); 155 156 private: 157 /** 158 * Calls release if this expression has a value, otherwise returns null. 159 */ 160 std::unique_ptr<SkSL::Expression> releaseIfPossible(); 161 162 std::unique_ptr<SkSL::Expression> fExpression; 163 164 friend DSLExpression SampleChild(int index, DSLExpression coords); 165 166 friend class DSLCore; 167 friend class DSLFunction; 168 friend class DSLPossibleExpression; 169 friend class DSLType; 170 friend class DSLVarBase; 171 friend class DSLWriter; 172 template<typename T> friend class DSLWrapper; 173 }; 174 175 DSLPossibleExpression operator+(DSLExpression left, DSLExpression right); 176 DSLPossibleExpression operator+(DSLExpression expr); 177 DSLPossibleExpression operator+=(DSLExpression left, DSLExpression right); 178 DSLPossibleExpression operator-(DSLExpression left, DSLExpression right); 179 DSLPossibleExpression operator-(DSLExpression expr); 180 DSLPossibleExpression operator-=(DSLExpression left, DSLExpression right); 181 DSLPossibleExpression operator*(DSLExpression left, DSLExpression right); 182 DSLPossibleExpression operator*=(DSLExpression left, DSLExpression right); 183 DSLPossibleExpression operator/(DSLExpression left, DSLExpression right); 184 DSLPossibleExpression operator/=(DSLExpression left, DSLExpression right); 185 DSLPossibleExpression operator%(DSLExpression left, DSLExpression right); 186 DSLPossibleExpression operator%=(DSLExpression left, DSLExpression right); 187 DSLPossibleExpression operator<<(DSLExpression left, DSLExpression right); 188 DSLPossibleExpression operator<<=(DSLExpression left, DSLExpression right); 189 DSLPossibleExpression operator>>(DSLExpression left, DSLExpression right); 190 DSLPossibleExpression operator>>=(DSLExpression left, DSLExpression right); 191 DSLPossibleExpression operator&&(DSLExpression left, DSLExpression right); 192 DSLPossibleExpression operator||(DSLExpression left, DSLExpression right); 193 DSLPossibleExpression operator&(DSLExpression left, DSLExpression right); 194 DSLPossibleExpression operator&=(DSLExpression left, DSLExpression right); 195 DSLPossibleExpression operator|(DSLExpression left, DSLExpression right); 196 DSLPossibleExpression operator|=(DSLExpression left, DSLExpression right); 197 DSLPossibleExpression operator^(DSLExpression left, DSLExpression right); 198 DSLPossibleExpression operator^=(DSLExpression left, DSLExpression right); 199 DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right); 200 DSLPossibleExpression operator,(DSLExpression left, DSLExpression right); 201 DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right); 202 DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right); 203 DSLPossibleExpression operator,(DSLPossibleExpression left, DSLPossibleExpression right); 204 DSLPossibleExpression operator==(DSLExpression left, DSLExpression right); 205 DSLPossibleExpression operator!=(DSLExpression left, DSLExpression right); 206 DSLPossibleExpression operator>(DSLExpression left, DSLExpression right); 207 DSLPossibleExpression operator<(DSLExpression left, DSLExpression right); 208 DSLPossibleExpression operator>=(DSLExpression left, DSLExpression right); 209 DSLPossibleExpression operator<=(DSLExpression left, DSLExpression right); 210 DSLPossibleExpression operator!(DSLExpression expr); 211 DSLPossibleExpression operator~(DSLExpression expr); 212 DSLPossibleExpression operator++(DSLExpression expr); 213 DSLPossibleExpression operator++(DSLExpression expr, int); 214 DSLPossibleExpression operator--(DSLExpression expr); 215 DSLPossibleExpression operator--(DSLExpression expr, int); 216 217 /** 218 * Represents an Expression which may have failed and/or have pending errors to report. Converting a 219 * PossibleExpression into an Expression requires PositionInfo so that any pending errors can be 220 * reported at the correct position. 221 * 222 * PossibleExpression is used instead of Expression in situations where it is not possible to 223 * capture the PositionInfo at the time of Expression construction (notably in operator overloads, 224 * where we cannot add default parameters). 225 */ 226 class DSLPossibleExpression { 227 public: 228 DSLPossibleExpression(std::unique_ptr<SkSL::Expression> expression); 229 230 DSLPossibleExpression(DSLPossibleExpression&& other); 231 232 ~DSLPossibleExpression(); 233 valid()234 bool valid() const { 235 return fExpression != nullptr; 236 } 237 238 /** 239 * Reports any pending errors at the specified position. 240 */ 241 void reportErrors(PositionInfo pos); 242 243 DSLType type(); 244 245 DSLExpression x(PositionInfo pos = PositionInfo::Capture()); 246 247 DSLExpression y(PositionInfo pos = PositionInfo::Capture()); 248 249 DSLExpression z(PositionInfo pos = PositionInfo::Capture()); 250 251 DSLExpression w(PositionInfo pos = PositionInfo::Capture()); 252 253 DSLExpression r(PositionInfo pos = PositionInfo::Capture()); 254 255 DSLExpression g(PositionInfo pos = PositionInfo::Capture()); 256 257 DSLExpression b(PositionInfo pos = PositionInfo::Capture()); 258 259 DSLExpression a(PositionInfo pos = PositionInfo::Capture()); 260 261 DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo::Capture()); 262 263 DSLPossibleExpression operator=(DSLExpression expr); 264 265 DSLPossibleExpression operator=(int expr); 266 267 DSLPossibleExpression operator=(float expr); 268 269 DSLPossibleExpression operator=(double expr); 270 271 DSLPossibleExpression operator[](DSLExpression index); 272 273 DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args, 274 PositionInfo pos = PositionInfo::Capture()); 275 276 DSLPossibleExpression operator()(ExpressionArray args, 277 PositionInfo pos = PositionInfo::Capture()); 278 279 DSLPossibleExpression operator++(); 280 281 DSLPossibleExpression operator++(int); 282 283 DSLPossibleExpression operator--(); 284 285 DSLPossibleExpression operator--(int); 286 287 std::unique_ptr<SkSL::Expression> release(PositionInfo pos = PositionInfo::Capture()); 288 289 private: 290 std::unique_ptr<SkSL::Expression> fExpression; 291 292 friend class DSLExpression; 293 }; 294 295 } // namespace dsl 296 297 } // namespace SkSL 298 299 #endif 300