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