blob: 9ee0f6d2057dde2d16a9865cdcc893a43ba4fe3d [file] [log] [blame]
Ethan Nicholas95046142021-01-07 10:57:27 -05001/*
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
Ethan Nicholasd0f4d0d2021-06-23 13:51:55 -040011#include "include/core/SkStringView.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050012#include "include/core/SkTypes.h"
Ethan Nicholas722cb672021-05-06 10:47:06 -040013#include "include/private/SkTArray.h"
Ethan Nicholas722cb672021-05-06 10:47:06 -040014#include "include/sksl/DSLWrapper.h"
Ethan Nicholas4a5e22a2021-08-13 17:29:51 -040015#include "include/sksl/SkSLErrorReporter.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050016
17#include <cstdint>
18#include <memory>
19
Ethan Nicholas5b1ae4b2021-09-16 10:08:20 -040020#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
Ethan Nicholas95046142021-01-07 10:57:27 -050026namespace SkSL {
27
28class Expression;
Ethan Nicholasdaed2592021-03-04 14:30:25 -050029class Type;
Ethan Nicholas95046142021-01-07 10:57:27 -050030
31namespace dsl {
32
Ethan Nicholasb9563042021-02-25 09:45:49 -050033class DSLPossibleExpression;
Ethan Nicholascfefec02021-02-09 15:22:57 -050034class DSLStatement;
Ethan Nicholas722cb672021-05-06 10:47:06 -040035class DSLType;
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040036class DSLVarBase;
Ethan Nicholas95046142021-01-07 10:57:27 -050037
38/**
39 * Represents an expression such as 'cos(x)' or 'a + b'.
40 */
41class DSLExpression {
42public:
43 DSLExpression(const DSLExpression&) = delete;
44
Ethan Nicholasdaed2592021-03-04 14:30:25 -050045 DSLExpression(DSLExpression&&);
Ethan Nicholas95046142021-01-07 10:57:27 -050046
47 DSLExpression();
48
49 /**
50 * Creates an expression representing a literal float.
51 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040052 DSLExpression(float value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas95046142021-01-07 10:57:27 -050053
54 /**
55 * Creates an expression representing a literal float.
56 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040057 DSLExpression(double value, PositionInfo pos = PositionInfo::Capture())
Ethan Nicholas95046142021-01-07 10:57:27 -050058 : DSLExpression((float) value) {}
59
60 /**
61 * Creates an expression representing a literal int.
62 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040063 DSLExpression(int value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas95046142021-01-07 10:57:27 -050064
65 /**
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -040066 * Creates an expression representing a literal int.
67 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040068 DSLExpression(int64_t value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -040069
70 /**
Ethan Nicholasb83199e2021-05-03 14:25:35 -040071 * Creates an expression representing a literal uint.
72 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040073 DSLExpression(unsigned int value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb83199e2021-05-03 14:25:35 -040074
75 /**
Ethan Nicholas95046142021-01-07 10:57:27 -050076 * Creates an expression representing a literal bool.
77 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040078 DSLExpression(bool value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas95046142021-01-07 10:57:27 -050079
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050080 /**
81 * Creates an expression representing a variable reference.
82 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040083 DSLExpression(DSLVarBase& var, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas707d3152021-03-25 17:49:08 -040084
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040085 DSLExpression(DSLVarBase&& var, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050086
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -040087 DSLExpression(DSLPossibleExpression expr, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -050088
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -040089 explicit DSLExpression(std::unique_ptr<SkSL::Expression> expression);
Ethan Nicholas722cb672021-05-06 10:47:06 -040090
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040091 static DSLExpression Poison(PositionInfo pos = PositionInfo::Capture());
92
Ethan Nicholas95046142021-01-07 10:57:27 -050093 ~DSLExpression();
94
Ethan Nicholas722cb672021-05-06 10:47:06 -040095 DSLType type();
96
Ethan Nicholas95046142021-01-07 10:57:27 -050097 /**
Ethan Nicholas92969f22021-01-13 10:38:59 -050098 * Overloads the '=' operator to create an SkSL assignment statement.
99 */
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500100 DSLPossibleExpression operator=(DSLExpression other);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500101
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400102 DSLExpression x(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500103
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400104 DSLExpression y(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500105
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400106 DSLExpression z(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500107
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400108 DSLExpression w(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500109
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400110 DSLExpression r(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500111
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400112 DSLExpression g(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500113
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400114 DSLExpression b(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500115
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400116 DSLExpression a(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500117
Ethan Nicholas92969f22021-01-13 10:38:59 -0500118 /**
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500119 * Creates an SkSL struct field access expression.
120 */
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400121 DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500122
123 /**
Ethan Nicholas04be3392021-01-26 10:07:01 -0500124 * Creates an SkSL array index expression.
125 */
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500126 DSLPossibleExpression operator[](DSLExpression index);
Ethan Nicholas04be3392021-01-26 10:07:01 -0500127
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -0400128 DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args,
129 PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas722cb672021-05-06 10:47:06 -0400130
Ethan Nicholas9a1f92e2021-09-09 15:03:22 -0400131 DSLPossibleExpression operator()(ExpressionArray args,
132 PositionInfo pos = PositionInfo::Capture());
133
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400134 /**
135 * Returns true if this object contains an expression. DSLExpressions which were created with
Ethan Nicholas51b4b862021-08-31 16:12:40 -0400136 * 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).
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400138 */
Ethan Nicholas51b4b862021-08-31 16:12:40 -0400139 bool hasValue() const {
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -0400140 return fExpression != nullptr;
141 }
142
Ethan Nicholas51b4b862021-08-31 16:12:40 -0400143 /**
144 * Returns true if this object contains an expression which is not poison.
145 */
146 bool isValid() const;
147
Ethan Nicholas5b1ae4b2021-09-16 10:08:20 -0400148 SK_CLANG_REINITIALIZES void swap(DSLExpression& other);
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -0400149
Ethan Nicholas04be3392021-01-26 10:07:01 -0500150 /**
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400151 * Invalidates this object and returns the SkSL expression it represents. It is an error to call
152 * this on an invalid DSLExpression.
Ethan Nicholas95046142021-01-07 10:57:27 -0500153 */
154 std::unique_ptr<SkSL::Expression> release();
155
156private:
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400157 /**
Ethan Nicholas51b4b862021-08-31 16:12:40 -0400158 * Calls release if this expression has a value, otherwise returns null.
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400159 */
Ethan Nicholas51b4b862021-08-31 16:12:40 -0400160 std::unique_ptr<SkSL::Expression> releaseIfPossible();
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400161
Ethan Nicholas95046142021-01-07 10:57:27 -0500162 std::unique_ptr<SkSL::Expression> fExpression;
163
Ethan Nicholas840f5812021-02-16 13:02:57 -0500164 friend DSLExpression SampleChild(int index, DSLExpression coords);
165
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500166 friend class DSLCore;
Ethan Nicholas63f75fc2021-02-23 12:05:49 -0500167 friend class DSLFunction;
Ethan Nicholasb9563042021-02-25 09:45:49 -0500168 friend class DSLPossibleExpression;
John Stiles1a2cef72021-10-04 12:43:11 -0400169 friend class DSLType;
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400170 friend class DSLVarBase;
Ethan Nicholas95046142021-01-07 10:57:27 -0500171 friend class DSLWriter;
Ethan Nicholasa1a0b922021-05-04 12:22:02 -0400172 template<typename T> friend class DSLWrapper;
Ethan Nicholas95046142021-01-07 10:57:27 -0500173};
174
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500175DSLPossibleExpression operator+(DSLExpression left, DSLExpression right);
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500176DSLPossibleExpression operator+(DSLExpression expr);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500177DSLPossibleExpression operator+=(DSLExpression left, DSLExpression right);
178DSLPossibleExpression operator-(DSLExpression left, DSLExpression right);
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500179DSLPossibleExpression operator-(DSLExpression expr);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500180DSLPossibleExpression operator-=(DSLExpression left, DSLExpression right);
181DSLPossibleExpression operator*(DSLExpression left, DSLExpression right);
182DSLPossibleExpression operator*=(DSLExpression left, DSLExpression right);
183DSLPossibleExpression operator/(DSLExpression left, DSLExpression right);
184DSLPossibleExpression operator/=(DSLExpression left, DSLExpression right);
185DSLPossibleExpression operator%(DSLExpression left, DSLExpression right);
186DSLPossibleExpression operator%=(DSLExpression left, DSLExpression right);
187DSLPossibleExpression operator<<(DSLExpression left, DSLExpression right);
188DSLPossibleExpression operator<<=(DSLExpression left, DSLExpression right);
189DSLPossibleExpression operator>>(DSLExpression left, DSLExpression right);
190DSLPossibleExpression operator>>=(DSLExpression left, DSLExpression right);
191DSLPossibleExpression operator&&(DSLExpression left, DSLExpression right);
192DSLPossibleExpression operator||(DSLExpression left, DSLExpression right);
193DSLPossibleExpression operator&(DSLExpression left, DSLExpression right);
194DSLPossibleExpression operator&=(DSLExpression left, DSLExpression right);
195DSLPossibleExpression operator|(DSLExpression left, DSLExpression right);
196DSLPossibleExpression operator|=(DSLExpression left, DSLExpression right);
197DSLPossibleExpression operator^(DSLExpression left, DSLExpression right);
198DSLPossibleExpression operator^=(DSLExpression left, DSLExpression right);
Ethan Nicholas2ab47c92021-07-19 12:30:37 -0400199DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500200DSLPossibleExpression operator,(DSLExpression left, DSLExpression right);
Ethan Nicholasdb2326b2021-04-19 10:55:18 -0400201DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right);
202DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right);
203DSLPossibleExpression operator,(DSLPossibleExpression left, DSLPossibleExpression right);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500204DSLPossibleExpression operator==(DSLExpression left, DSLExpression right);
205DSLPossibleExpression operator!=(DSLExpression left, DSLExpression right);
206DSLPossibleExpression operator>(DSLExpression left, DSLExpression right);
207DSLPossibleExpression operator<(DSLExpression left, DSLExpression right);
208DSLPossibleExpression operator>=(DSLExpression left, DSLExpression right);
209DSLPossibleExpression operator<=(DSLExpression left, DSLExpression right);
210DSLPossibleExpression operator!(DSLExpression expr);
211DSLPossibleExpression operator~(DSLExpression expr);
212DSLPossibleExpression operator++(DSLExpression expr);
213DSLPossibleExpression operator++(DSLExpression expr, int);
214DSLPossibleExpression operator--(DSLExpression expr);
215DSLPossibleExpression operator--(DSLExpression expr, int);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500216
Ethan Nicholasb9563042021-02-25 09:45:49 -0500217/**
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 */
226class DSLPossibleExpression {
227public:
228 DSLPossibleExpression(std::unique_ptr<SkSL::Expression> expression);
229
Ethan Nicholasdaed2592021-03-04 14:30:25 -0500230 DSLPossibleExpression(DSLPossibleExpression&& other);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500231
232 ~DSLPossibleExpression();
233
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -0400234 bool valid() const {
235 return fExpression != nullptr;
236 }
237
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -0400238 /**
239 * Reports any pending errors at the specified position.
240 */
241 void reportErrors(PositionInfo pos);
242
Ethan Nicholas722cb672021-05-06 10:47:06 -0400243 DSLType type();
244
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400245 DSLExpression x(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500246
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400247 DSLExpression y(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500248
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400249 DSLExpression z(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500250
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400251 DSLExpression w(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500252
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400253 DSLExpression r(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500254
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400255 DSLExpression g(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500256
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400257 DSLExpression b(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500258
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400259 DSLExpression a(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500260
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400261 DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500262
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500263 DSLPossibleExpression operator=(DSLExpression expr);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500264
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500265 DSLPossibleExpression operator=(int expr);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500266
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500267 DSLPossibleExpression operator=(float expr);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500268
Ethan Nicholasa60cc3e2021-04-23 16:15:11 -0400269 DSLPossibleExpression operator=(double expr);
270
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500271 DSLPossibleExpression operator[](DSLExpression index);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500272
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -0400273 DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args,
274 PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas722cb672021-05-06 10:47:06 -0400275
Ethan Nicholas9a1f92e2021-09-09 15:03:22 -0400276 DSLPossibleExpression operator()(ExpressionArray args,
277 PositionInfo pos = PositionInfo::Capture());
278
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500279 DSLPossibleExpression operator++();
Ethan Nicholasb9563042021-02-25 09:45:49 -0500280
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500281 DSLPossibleExpression operator++(int);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500282
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500283 DSLPossibleExpression operator--();
Ethan Nicholasb9563042021-02-25 09:45:49 -0500284
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500285 DSLPossibleExpression operator--(int);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500286
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400287 std::unique_ptr<SkSL::Expression> release(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500288
289private:
290 std::unique_ptr<SkSL::Expression> fExpression;
291
292 friend class DSLExpression;
293};
294
Ethan Nicholas95046142021-01-07 10:57:27 -0500295} // namespace dsl
296
297} // namespace SkSL
298
299#endif