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/private/base/SkTArray.h" 12 #include "include/sksl/SkSLOperator.h" 13 #include "include/sksl/SkSLPosition.h" 14 15 #include <cstdint> 16 #include <memory> 17 #include <string> 18 #include <string_view> 19 #include <type_traits> 20 21 #if defined(__has_cpp_attribute) && __has_cpp_attribute(clang::reinitializes) 22 #define SK_CLANG_REINITIALIZES [[clang::reinitializes]] 23 #else 24 #define SK_CLANG_REINITIALIZES 25 #endif 26 27 namespace SkSL { 28 29 class Expression; 30 class ExpressionArray; 31 32 namespace dsl { 33 34 class DSLType; 35 class DSLVarBase; 36 37 /** 38 * Represents an expression such as 'cos(x)' or 'a + b'. 39 */ 40 class DSLExpression { 41 public: 42 DSLExpression(const DSLExpression&) = delete; 43 44 DSLExpression(DSLExpression&&); 45 46 DSLExpression(); 47 48 /** 49 * Creates an expression representing a literal float. 50 */ 51 DSLExpression(float value, Position pos = {}); 52 53 /** 54 * Creates an expression representing a literal float. 55 */ 56 DSLExpression(double value, Position pos = {}) 57 : DSLExpression((float) value) {} 58 59 /** 60 * Creates an expression representing a literal int. 61 */ 62 DSLExpression(int value, Position pos = {}); 63 64 /** 65 * Creates an expression representing a literal int. 66 */ 67 DSLExpression(int64_t value, Position pos = {}); 68 69 /** 70 * Creates an expression representing a literal uint. 71 */ 72 DSLExpression(unsigned int value, Position pos = {}); 73 74 /** 75 * Creates an expression representing a literal bool. 76 */ 77 DSLExpression(bool value, Position pos = {}); 78 79 /** 80 * Creates an expression representing a variable reference. 81 */ 82 DSLExpression(DSLVarBase& var, Position pos = {}); 83 84 DSLExpression(DSLVarBase&& var, Position pos = {}); 85 86 // If expression is null, returns Poison 87 explicit DSLExpression(std::unique_ptr<SkSL::Expression> expression, Position pos = {}); 88 89 static DSLExpression Poison(Position pos = {}); 90 91 ~DSLExpression(); 92 93 DSLType type() const; 94 95 std::string description() const; 96 97 Position position() const; 98 99 void setPosition(Position pos); 100 101 /** 102 * Performs assignment, like the '=' operator. 103 */ 104 DSLExpression assign(DSLExpression other); 105 106 DSLExpression x(Position pos = {}); 107 108 DSLExpression y(Position pos = {}); 109 110 DSLExpression z(Position pos = {}); 111 112 DSLExpression w(Position pos = {}); 113 114 DSLExpression r(Position pos = {}); 115 116 DSLExpression g(Position pos = {}); 117 118 DSLExpression b(Position pos = {}); 119 120 DSLExpression a(Position pos = {}); 121 122 /** 123 * Creates an SkSL struct field access expression. 124 */ 125 DSLExpression field(std::string_view name, Position pos = {}); 126 127 /** 128 * Creates an SkSL array index expression. 129 */ 130 DSLExpression operator[](DSLExpression index); 131 132 DSLExpression operator()(SkTArray<DSLExpression, true> args, Position pos = {}); 133 134 DSLExpression operator()(ExpressionArray args, Position pos = {}); 135 136 /** 137 * Invokes a prefix operator. 138 */ 139 DSLExpression prefix(Operator::Kind op, Position pos); 140 141 /** 142 * Invokes a postfix operator. 143 */ 144 DSLExpression postfix(Operator::Kind op, Position pos); 145 146 /** 147 * Invokes a binary operator. 148 */ 149 DSLExpression binary(Operator::Kind op, DSLExpression right, Position pos); 150 151 /** 152 * Equivalent to operator[]. 153 */ 154 DSLExpression index(DSLExpression index, Position pos); 155 156 /** 157 * Returns true if this object contains an expression. DSLExpressions which were created with 158 * the empty constructor or which have already been release()ed do not have a value. 159 * DSLExpressions created with errors are still considered to have a value (but contain poison). 160 */ hasValue()161 bool hasValue() const { 162 return fExpression != nullptr; 163 } 164 165 /** 166 * Returns true if this object contains an expression which is not poison. 167 */ 168 bool isValid() const; 169 170 SK_CLANG_REINITIALIZES void swap(DSLExpression& other); 171 172 /** 173 * Invalidates this object and returns the SkSL expression it represents. It is an error to call 174 * this on an invalid DSLExpression. 175 */ 176 std::unique_ptr<SkSL::Expression> release(); 177 178 private: 179 /** 180 * Calls release if this expression has a value, otherwise returns null. 181 */ 182 std::unique_ptr<SkSL::Expression> releaseIfPossible(); 183 184 std::unique_ptr<SkSL::Expression> fExpression; 185 186 friend DSLExpression SampleChild(int index, DSLExpression coords); 187 188 friend class DSLCore; 189 friend class DSLVarBase; 190 friend class DSLWriter; 191 }; 192 193 DSLExpression operator+(DSLExpression left, DSLExpression right); 194 DSLExpression operator+(DSLExpression expr); 195 DSLExpression operator+=(DSLExpression left, DSLExpression right); 196 DSLExpression operator-(DSLExpression left, DSLExpression right); 197 DSLExpression operator-(DSLExpression expr); 198 DSLExpression operator-=(DSLExpression left, DSLExpression right); 199 DSLExpression operator*(DSLExpression left, DSLExpression right); 200 DSLExpression operator*=(DSLExpression left, DSLExpression right); 201 DSLExpression operator/(DSLExpression left, DSLExpression right); 202 DSLExpression operator/=(DSLExpression left, DSLExpression right); 203 DSLExpression operator%(DSLExpression left, DSLExpression right); 204 DSLExpression operator%=(DSLExpression left, DSLExpression right); 205 DSLExpression operator<<(DSLExpression left, DSLExpression right); 206 DSLExpression operator<<=(DSLExpression left, DSLExpression right); 207 DSLExpression operator>>(DSLExpression left, DSLExpression right); 208 DSLExpression operator>>=(DSLExpression left, DSLExpression right); 209 DSLExpression operator&&(DSLExpression left, DSLExpression right); 210 DSLExpression operator||(DSLExpression left, DSLExpression right); 211 DSLExpression operator&(DSLExpression left, DSLExpression right); 212 DSLExpression operator&=(DSLExpression left, DSLExpression right); 213 DSLExpression operator|(DSLExpression left, DSLExpression right); 214 DSLExpression operator|=(DSLExpression left, DSLExpression right); 215 DSLExpression operator^(DSLExpression left, DSLExpression right); 216 DSLExpression operator^=(DSLExpression left, DSLExpression right); 217 DSLExpression LogicalXor(DSLExpression left, DSLExpression right); 218 DSLExpression operator,(DSLExpression left, DSLExpression right); 219 DSLExpression operator==(DSLExpression left, DSLExpression right); 220 DSLExpression operator!=(DSLExpression left, DSLExpression right); 221 DSLExpression operator>(DSLExpression left, DSLExpression right); 222 DSLExpression operator<(DSLExpression left, DSLExpression right); 223 DSLExpression operator>=(DSLExpression left, DSLExpression right); 224 DSLExpression operator<=(DSLExpression left, DSLExpression right); 225 DSLExpression operator!(DSLExpression expr); 226 DSLExpression operator~(DSLExpression expr); 227 DSLExpression operator++(DSLExpression expr); 228 DSLExpression operator++(DSLExpression expr, int); 229 DSLExpression operator--(DSLExpression expr); 230 DSLExpression operator--(DSLExpression expr, int); 231 232 } // namespace dsl 233 234 } // namespace SkSL 235 236 template <typename T> struct sk_is_trivially_relocatable; 237 238 template <> 239 struct sk_is_trivially_relocatable<SkSL::dsl::DSLExpression> : std::true_type {}; 240 241 #endif 242