• 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/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