• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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