2 * Copyright 2020 Google LLC
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "include/sksl/DSLExpression.h"
10 #include "include/core/SkTypes.h"
11 #include "include/private/SkSLDefines.h"
12 #include "include/sksl/DSLCore.h"
13 #include "include/sksl/DSLType.h"
14 #include "include/sksl/DSLVar.h"
15 #include "include/sksl/SkSLOperator.h"
16 #include "src/sksl/SkSLThreadContext.h"
17 #include "src/sksl/dsl/priv/DSLWriter.h"
18 #include "src/sksl/ir/SkSLBinaryExpression.h"
19 #include "src/sksl/ir/SkSLExpression.h"
20 #include "src/sksl/ir/SkSLFieldAccess.h"
21 #include "src/sksl/ir/SkSLFunctionCall.h"
22 #include "src/sksl/ir/SkSLIndexExpression.h"
23 #include "src/sksl/ir/SkSLLiteral.h"
24 #include "src/sksl/ir/SkSLPoison.h"
25 #include "src/sksl/ir/SkSLPostfixExpression.h"
26 #include "src/sksl/ir/SkSLPrefixExpression.h"
27 #include "src/sksl/ir/SkSLVariableReference.h"
36 DSLExpression::DSLExpression() {}
38 DSLExpression::DSLExpression(DSLExpression&& other)
39 : fExpression(std::move(other.fExpression)) {}
41 DSLExpression::DSLExpression(std::unique_ptr<SkSL::Expression> expression)
42 : fExpression(std::move(expression)) {
43 SkASSERT(this->hasValue());
46 DSLExpression::DSLExpression(std::unique_ptr<SkSL::Expression> expression, Position pos)
47 : fExpression(expression ? std::move(expression)
48 : SkSL::Poison::Make(pos, ThreadContext::Context())) {
49 ThreadContext::ReportErrors(pos);
50 SkASSERTF(this->position() == pos, "expected expression position (%d-%d), but received (%d-%d)",
51 pos.startOffset(), pos.endOffset(), this->position().startOffset(),
52 this->position().endOffset());
55 DSLExpression::DSLExpression(float value, Position pos)
56 : fExpression(SkSL::Literal::MakeFloat(ThreadContext::Context(),
59 if (!isfinite(value)) {
61 ThreadContext::ReportError("floating point value is infinite");
62 } else if (isnan(value)) {
63 ThreadContext::ReportError("floating point value is NaN");
68 DSLExpression::DSLExpression(int value, Position pos)
69 : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
73 DSLExpression::DSLExpression(int64_t value, Position pos)
74 : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
78 DSLExpression::DSLExpression(unsigned int value, Position pos)
79 : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
83 DSLExpression::DSLExpression(bool value, Position pos)
84 : fExpression(SkSL::Literal::MakeBool(ThreadContext::Context(),
88 DSLExpression::DSLExpression(DSLVarBase& var, Position pos) {
89 fExpression = std::make_unique<SkSL::VariableReference>(pos, DSLWriter::Var(var),
90 SkSL::VariableReference::RefKind::kRead);
93 DSLExpression::DSLExpression(DSLVarBase&& var, Position pos)
94 : DSLExpression(var) {}
96 DSLExpression::DSLExpression(DSLPossibleExpression expr, Position pos) {
97 ThreadContext::ReportErrors(pos);
99 fExpression = std::move(expr.fExpression);
100 if (!this->position().valid()) {
101 fExpression->fPosition = pos;
104 fExpression = SkSL::Poison::Make(pos, ThreadContext::Context());
108 DSLExpression DSLExpression::Poison(Position pos) {
109 return DSLExpression(SkSL::Poison::Make(pos, ThreadContext::Context()));
112 DSLExpression::~DSLExpression() {}
114 bool DSLExpression::isValid() const {
115 return this->hasValue() && !fExpression->is<SkSL::Poison>();
118 void DSLExpression::swap(DSLExpression& other) {
119 std::swap(fExpression, other.fExpression);
122 std::unique_ptr<SkSL::Expression> DSLExpression::release() {
123 SkASSERT(this->hasValue());
124 return std::move(fExpression);
127 std::unique_ptr<SkSL::Expression> DSLExpression::releaseIfPossible() {
128 return std::move(fExpression);
131 DSLType DSLExpression::type() const {
132 if (!this->hasValue()) {
135 return &fExpression->type();
138 std::string DSLExpression::description() const {
139 SkASSERT(this->hasValue());
140 return fExpression->description();
143 Position DSLExpression::position() const {
144 SkASSERT(this->hasValue());
145 return fExpression->fPosition;
148 void DSLExpression::setPosition(Position pos) {
149 SkASSERT(this->hasValue());
150 fExpression->fPosition = pos;
153 DSLExpression DSLExpression::x(Position pos) {
154 return Swizzle(std::move(*this), X, pos);
157 DSLExpression DSLExpression::y(Position pos) {
158 return Swizzle(std::move(*this), Y, pos);
161 DSLExpression DSLExpression::z(Position pos) {
162 return Swizzle(std::move(*this), Z, pos);
165 DSLExpression DSLExpression::w(Position pos) {
166 return Swizzle(std::move(*this), W, pos);
169 DSLExpression DSLExpression::r(Position pos) {
170 return Swizzle(std::move(*this), R, pos);
173 DSLExpression DSLExpression::g(Position pos) {
174 return Swizzle(std::move(*this), G, pos);
177 DSLExpression DSLExpression::b(Position pos) {
178 return Swizzle(std::move(*this), B, pos);
181 DSLExpression DSLExpression::a(Position pos) {
182 return Swizzle(std::move(*this), A, pos);
185 DSLExpression DSLExpression::field(std::string_view name, Position pos) {
186 return DSLExpression(FieldAccess::Convert(ThreadContext::Context(), pos,
187 *ThreadContext::SymbolTable(), this->release(), name), pos);
190 DSLPossibleExpression DSLExpression::assign(DSLExpression right) {
191 Position pos = this->position().rangeThrough(right.position());
192 return BinaryExpression::Convert(ThreadContext::Context(), pos, this->release(),
193 SkSL::Operator::Kind::EQ, right.release());
196 DSLPossibleExpression DSLExpression::operator[](DSLExpression right) {
197 Position pos = this->position().rangeThrough(right.position());
198 return IndexExpression::Convert(ThreadContext::Context(), *ThreadContext::SymbolTable(), pos,
199 this->release(), right.release());
202 DSLExpression DSLExpression::index(DSLExpression index, Position pos) {
203 std::unique_ptr<SkSL::Expression> result = IndexExpression::Convert(ThreadContext::Context(),
204 *ThreadContext::SymbolTable(), pos, this->release(), index.release());
205 return DSLExpression(std::move(result), pos);
208 DSLPossibleExpression DSLExpression::operator()(SkTArray<DSLExpression> args, Position pos) {
209 ExpressionArray converted;
210 converted.reserve_back(args.count());
211 for (DSLExpression& arg : args) {
212 converted.push_back(arg.release());
214 return (*this)(std::move(converted), pos);
217 DSLPossibleExpression DSLExpression::operator()(ExpressionArray args, Position pos) {
218 return SkSL::FunctionCall::Convert(ThreadContext::Context(), pos, this->release(),
222 DSLExpression DSLExpression::prefix(Operator::Kind op, Position pos) {
223 std::unique_ptr<SkSL::Expression> result = PrefixExpression::Convert(ThreadContext::Context(),
224 pos, op, this->release());
225 return DSLExpression(std::move(result), pos);
228 DSLExpression DSLExpression::postfix(Operator::Kind op, Position pos) {
229 std::unique_ptr<SkSL::Expression> result = PostfixExpression::Convert(ThreadContext::Context(),
230 pos, this->release(), op);
231 return DSLExpression(std::move(result), pos);
234 DSLExpression DSLExpression::binary(Operator::Kind op, DSLExpression right, Position pos) {
235 std::unique_ptr<SkSL::Expression> result = BinaryExpression::Convert(ThreadContext::Context(),
236 pos, this->release(), op, right.release());
237 return DSLExpression(std::move(result), pos);
240 #define OP(op, token) \
241 DSLPossibleExpression operator op(DSLExpression left, DSLExpression right) { \
242 return BinaryExpression::Convert(ThreadContext::Context(), Position(), left.release(), \
243 Operator::Kind::token, right.release()); \
246 #define PREFIXOP(op, token) \
247 DSLPossibleExpression operator op(DSLExpression expr) { \
248 return PrefixExpression::Convert(ThreadContext::Context(), Position(), Operator::Kind::token, \
252 #define POSTFIXOP(op, token) \
253 DSLPossibleExpression operator op(DSLExpression expr, int) { \
254 return PostfixExpression::Convert(ThreadContext::Context(), Position(), expr.release(), \
255 Operator::Kind::token); \
280 DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right) {
281 return BinaryExpression::Convert(ThreadContext::Context(), Position(), left.release(),
282 SkSL::Operator::Kind::LOGICALXOR, right.release());
293 PREFIXOP(!, LOGICALNOT)
294 PREFIXOP(~, BITWISENOT)
295 PREFIXOP(++, PLUSPLUS)
296 POSTFIXOP(++, PLUSPLUS)
297 PREFIXOP(--, MINUSMINUS)
298 POSTFIXOP(--, MINUSMINUS)
300 DSLPossibleExpression operator,(DSLExpression left, DSLExpression right) {
301 return BinaryExpression::Convert(ThreadContext::Context(), Position(), left.release(),
302 SkSL::Operator::Kind::COMMA, right.release());
305 DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right) {
306 return BinaryExpression::Convert(ThreadContext::Context(), Position(),
307 DSLExpression(std::move(left)).release(), SkSL::Operator::Kind::COMMA, right.release());
310 DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right) {
311 return BinaryExpression::Convert(ThreadContext::Context(), Position(), left.release(),
312 SkSL::Operator::Kind::COMMA, DSLExpression(std::move(right)).release());
315 DSLPossibleExpression operator,(DSLPossibleExpression left, DSLPossibleExpression right) {
316 return BinaryExpression::Convert(ThreadContext::Context(), Position(),
317 DSLExpression(std::move(left)).release(), SkSL::Operator::Kind::COMMA,
318 DSLExpression(std::move(right)).release());
321 DSLPossibleExpression::DSLPossibleExpression(std::unique_ptr<SkSL::Expression> expr)
322 : fExpression(std::move(expr)) {}
324 DSLPossibleExpression::DSLPossibleExpression(DSLPossibleExpression&& other)
325 : fExpression(std::move(other.fExpression)) {}
327 DSLPossibleExpression::~DSLPossibleExpression() {}
329 void DSLPossibleExpression::reportErrors(Position pos) {
330 SkASSERT(!this->valid());
331 ThreadContext::ReportErrors(pos);
334 DSLType DSLPossibleExpression::type() const {
335 if (!this->valid()) {
338 return &fExpression->type();
341 std::string DSLPossibleExpression::description() const {
342 SkASSERT(this->valid());
343 return fExpression->description();
346 Position DSLPossibleExpression::position() const {
347 SkASSERT(this->valid());
348 return fExpression->fPosition;
351 DSLExpression DSLPossibleExpression::x(Position pos) {
352 return DSLExpression(this->release()).x(pos);
355 DSLExpression DSLPossibleExpression::y(Position pos) {
356 return DSLExpression(this->release()).y(pos);
359 DSLExpression DSLPossibleExpression::z(Position pos) {
360 return DSLExpression(this->release()).z(pos);
363 DSLExpression DSLPossibleExpression::w(Position pos) {
364 return DSLExpression(this->release()).w(pos);
367 DSLExpression DSLPossibleExpression::r(Position pos) {
368 return DSLExpression(this->release()).r(pos);
371 DSLExpression DSLPossibleExpression::g(Position pos) {
372 return DSLExpression(this->release()).g(pos);
375 DSLExpression DSLPossibleExpression::b(Position pos) {
376 return DSLExpression(this->release()).b(pos);
379 DSLExpression DSLPossibleExpression::a(Position pos) {
380 return DSLExpression(this->release()).a(pos);
383 DSLExpression DSLPossibleExpression::field(std::string_view name, Position pos) {
384 return DSLExpression(this->release()).field(name, pos);
387 DSLPossibleExpression DSLPossibleExpression::assign(DSLExpression expr) {
388 return DSLExpression(this->release()).assign(std::move(expr));
391 DSLPossibleExpression DSLPossibleExpression::assign(int expr) {
392 return this->assign(DSLExpression(expr));
395 DSLPossibleExpression DSLPossibleExpression::assign(float expr) {
396 return this->assign(DSLExpression(expr));
399 DSLPossibleExpression DSLPossibleExpression::assign(double expr) {
400 return this->assign(DSLExpression(expr));
403 DSLPossibleExpression DSLPossibleExpression::operator[](DSLExpression index) {
404 return DSLExpression(this->release())[std::move(index)];
407 DSLPossibleExpression DSLPossibleExpression::operator()(SkTArray<DSLExpression> args,
409 return DSLExpression(this->release())(std::move(args), pos);
412 DSLPossibleExpression DSLPossibleExpression::operator()(ExpressionArray args, Position pos) {
413 return DSLExpression(this->release())(std::move(args), pos);
416 DSLPossibleExpression DSLPossibleExpression::operator++() {
417 return ++DSLExpression(this->release());
420 DSLPossibleExpression DSLPossibleExpression::operator++(int) {
421 return DSLExpression(this->release())++;
424 DSLPossibleExpression DSLPossibleExpression::operator--() {
425 return --DSLExpression(this->release());
428 DSLPossibleExpression DSLPossibleExpression::operator--(int) {
429 return DSLExpression(this->release())--;
432 std::unique_ptr<SkSL::Expression> DSLPossibleExpression::release(Position pos) {
433 return DSLExpression(std::move(*this), pos).release();