blob: d7ed8eab9334b28101e937e670fa0a88a6079c7c [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
20namespace SkSL {
21
22class Expression;
Ethan Nicholasdaed2592021-03-04 14:30:25 -050023class Type;
Ethan Nicholas95046142021-01-07 10:57:27 -050024
25namespace dsl {
26
Ethan Nicholasb9563042021-02-25 09:45:49 -050027class DSLPossibleExpression;
Ethan Nicholascfefec02021-02-09 15:22:57 -050028class DSLStatement;
Ethan Nicholas722cb672021-05-06 10:47:06 -040029class DSLType;
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040030class DSLVarBase;
Ethan Nicholas95046142021-01-07 10:57:27 -050031
32/**
33 * Represents an expression such as 'cos(x)' or 'a + b'.
34 */
35class DSLExpression {
36public:
37 DSLExpression(const DSLExpression&) = delete;
38
Ethan Nicholasdaed2592021-03-04 14:30:25 -050039 DSLExpression(DSLExpression&&);
Ethan Nicholas95046142021-01-07 10:57:27 -050040
41 DSLExpression();
42
43 /**
44 * Creates an expression representing a literal float.
45 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040046 DSLExpression(float value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas95046142021-01-07 10:57:27 -050047
48 /**
49 * Creates an expression representing a literal float.
50 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040051 DSLExpression(double value, PositionInfo pos = PositionInfo::Capture())
Ethan Nicholas95046142021-01-07 10:57:27 -050052 : DSLExpression((float) value) {}
53
54 /**
55 * Creates an expression representing a literal int.
56 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040057 DSLExpression(int value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas95046142021-01-07 10:57:27 -050058
59 /**
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -040060 * Creates an expression representing a literal int.
61 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040062 DSLExpression(int64_t value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -040063
64 /**
Ethan Nicholasb83199e2021-05-03 14:25:35 -040065 * Creates an expression representing a literal uint.
66 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040067 DSLExpression(unsigned int value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb83199e2021-05-03 14:25:35 -040068
69 /**
Ethan Nicholas95046142021-01-07 10:57:27 -050070 * Creates an expression representing a literal bool.
71 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040072 DSLExpression(bool value, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas95046142021-01-07 10:57:27 -050073
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050074 /**
75 * Creates an expression representing a variable reference.
76 */
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040077 DSLExpression(DSLVarBase& var, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas707d3152021-03-25 17:49:08 -040078
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040079 DSLExpression(DSLVarBase&& var, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050080
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -040081 DSLExpression(DSLPossibleExpression expr, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -050082
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -040083 explicit DSLExpression(std::unique_ptr<SkSL::Expression> expression);
Ethan Nicholas722cb672021-05-06 10:47:06 -040084
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040085 static DSLExpression Poison(PositionInfo pos = PositionInfo::Capture());
86
Ethan Nicholas95046142021-01-07 10:57:27 -050087 ~DSLExpression();
88
Ethan Nicholas722cb672021-05-06 10:47:06 -040089 DSLType type();
90
Ethan Nicholas95046142021-01-07 10:57:27 -050091 /**
Ethan Nicholas92969f22021-01-13 10:38:59 -050092 * Overloads the '=' operator to create an SkSL assignment statement.
93 */
Ethan Nicholas34c7e112021-02-25 20:50:32 -050094 DSLPossibleExpression operator=(DSLExpression other);
Ethan Nicholas92969f22021-01-13 10:38:59 -050095
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -040096 DSLExpression x(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -050097
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -040098 DSLExpression y(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -050099
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400100 DSLExpression z(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500101
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400102 DSLExpression w(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500103
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400104 DSLExpression r(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500105
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400106 DSLExpression g(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500107
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400108 DSLExpression b(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500109
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400110 DSLExpression a(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas68c77d42021-01-26 14:31:29 -0500111
Ethan Nicholas92969f22021-01-13 10:38:59 -0500112 /**
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500113 * Creates an SkSL struct field access expression.
114 */
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400115 DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500116
117 /**
Ethan Nicholas04be3392021-01-26 10:07:01 -0500118 * Creates an SkSL array index expression.
119 */
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500120 DSLPossibleExpression operator[](DSLExpression index);
Ethan Nicholas04be3392021-01-26 10:07:01 -0500121
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -0400122 DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args,
123 PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas722cb672021-05-06 10:47:06 -0400124
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400125 /**
126 * Returns true if this object contains an expression. DSLExpressions which were created with
127 * the empty constructor or which have already been release()ed are not valid. DSLExpressions
128 * created with errors are still considered valid (but contain a poison value).
129 */
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -0400130 bool valid() const {
131 return fExpression != nullptr;
132 }
133
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -0400134 void swap(DSLExpression& other);
135
Ethan Nicholas04be3392021-01-26 10:07:01 -0500136 /**
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400137 * Invalidates this object and returns the SkSL expression it represents. It is an error to call
138 * this on an invalid DSLExpression.
Ethan Nicholas95046142021-01-07 10:57:27 -0500139 */
140 std::unique_ptr<SkSL::Expression> release();
141
142private:
Ethan Nicholas549c6b82021-06-25 12:31:44 -0400143 /**
144 * Calls release if this expression is valid, otherwise returns null.
145 */
146 std::unique_ptr<SkSL::Expression> releaseIfValid();
147
Ethan Nicholas92969f22021-01-13 10:38:59 -0500148 /**
149 * Invalidates this object and returns the SkSL expression it represents coerced to the
150 * specified type. If the expression cannot be coerced, reports an error and returns null.
151 */
152 std::unique_ptr<SkSL::Expression> coerceAndRelease(const SkSL::Type& type);
153
Ethan Nicholas95046142021-01-07 10:57:27 -0500154 std::unique_ptr<SkSL::Expression> fExpression;
155
Ethan Nicholas840f5812021-02-16 13:02:57 -0500156 friend DSLExpression SampleChild(int index, DSLExpression coords);
157
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500158 friend class DSLCore;
Ethan Nicholas63f75fc2021-02-23 12:05:49 -0500159 friend class DSLFunction;
Ethan Nicholasb9563042021-02-25 09:45:49 -0500160 friend class DSLPossibleExpression;
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400161 friend class DSLVarBase;
Ethan Nicholas95046142021-01-07 10:57:27 -0500162 friend class DSLWriter;
Ethan Nicholasa1a0b922021-05-04 12:22:02 -0400163 template<typename T> friend class DSLWrapper;
Ethan Nicholas95046142021-01-07 10:57:27 -0500164};
165
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500166DSLPossibleExpression operator+(DSLExpression left, DSLExpression right);
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500167DSLPossibleExpression operator+(DSLExpression expr);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500168DSLPossibleExpression operator+=(DSLExpression left, DSLExpression right);
169DSLPossibleExpression operator-(DSLExpression left, DSLExpression right);
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500170DSLPossibleExpression operator-(DSLExpression expr);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500171DSLPossibleExpression operator-=(DSLExpression left, DSLExpression right);
172DSLPossibleExpression operator*(DSLExpression left, DSLExpression right);
173DSLPossibleExpression operator*=(DSLExpression left, DSLExpression right);
174DSLPossibleExpression operator/(DSLExpression left, DSLExpression right);
175DSLPossibleExpression operator/=(DSLExpression left, DSLExpression right);
176DSLPossibleExpression operator%(DSLExpression left, DSLExpression right);
177DSLPossibleExpression operator%=(DSLExpression left, DSLExpression right);
178DSLPossibleExpression operator<<(DSLExpression left, DSLExpression right);
179DSLPossibleExpression operator<<=(DSLExpression left, DSLExpression right);
180DSLPossibleExpression 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);
Ethan Nicholas2ab47c92021-07-19 12:30:37 -0400190DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500191DSLPossibleExpression operator,(DSLExpression left, DSLExpression right);
Ethan Nicholasdb2326b2021-04-19 10:55:18 -0400192DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right);
193DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right);
194DSLPossibleExpression operator,(DSLPossibleExpression left, DSLPossibleExpression right);
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500195DSLPossibleExpression operator==(DSLExpression left, DSLExpression right);
196DSLPossibleExpression operator!=(DSLExpression left, DSLExpression right);
197DSLPossibleExpression operator>(DSLExpression left, DSLExpression right);
198DSLPossibleExpression operator<(DSLExpression left, DSLExpression right);
199DSLPossibleExpression operator>=(DSLExpression left, DSLExpression right);
200DSLPossibleExpression operator<=(DSLExpression left, DSLExpression right);
201DSLPossibleExpression operator!(DSLExpression expr);
202DSLPossibleExpression operator~(DSLExpression expr);
203DSLPossibleExpression operator++(DSLExpression expr);
204DSLPossibleExpression operator++(DSLExpression expr, int);
205DSLPossibleExpression operator--(DSLExpression expr);
206DSLPossibleExpression operator--(DSLExpression expr, int);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500207
Ethan Nicholasb9563042021-02-25 09:45:49 -0500208/**
209 * Represents an Expression which may have failed and/or have pending errors to report. Converting a
210 * PossibleExpression into an Expression requires PositionInfo so that any pending errors can be
211 * reported at the correct position.
212 *
213 * PossibleExpression is used instead of Expression in situations where it is not possible to
214 * capture the PositionInfo at the time of Expression construction (notably in operator overloads,
215 * where we cannot add default parameters).
216 */
217class DSLPossibleExpression {
218public:
219 DSLPossibleExpression(std::unique_ptr<SkSL::Expression> expression);
220
Ethan Nicholasdaed2592021-03-04 14:30:25 -0500221 DSLPossibleExpression(DSLPossibleExpression&& other);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500222
223 ~DSLPossibleExpression();
224
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -0400225 bool valid() const {
226 return fExpression != nullptr;
227 }
228
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -0400229 /**
230 * Reports any pending errors at the specified position.
231 */
232 void reportErrors(PositionInfo pos);
233
Ethan Nicholas722cb672021-05-06 10:47:06 -0400234 DSLType type();
235
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400236 DSLExpression x(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500237
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400238 DSLExpression y(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500239
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400240 DSLExpression z(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500241
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400242 DSLExpression w(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500243
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400244 DSLExpression r(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500245
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400246 DSLExpression g(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500247
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400248 DSLExpression b(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500249
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400250 DSLExpression a(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500251
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400252 DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500253
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500254 DSLPossibleExpression operator=(DSLExpression expr);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500255
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500256 DSLPossibleExpression operator=(int expr);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500257
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500258 DSLPossibleExpression operator=(float expr);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500259
Ethan Nicholasa60cc3e2021-04-23 16:15:11 -0400260 DSLPossibleExpression operator=(double expr);
261
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500262 DSLPossibleExpression operator[](DSLExpression index);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500263
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -0400264 DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args,
265 PositionInfo pos = PositionInfo::Capture());
Ethan Nicholas722cb672021-05-06 10:47:06 -0400266
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500267 DSLPossibleExpression operator++();
Ethan Nicholasb9563042021-02-25 09:45:49 -0500268
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500269 DSLPossibleExpression operator++(int);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500270
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500271 DSLPossibleExpression operator--();
Ethan Nicholasb9563042021-02-25 09:45:49 -0500272
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500273 DSLPossibleExpression operator--(int);
Ethan Nicholasb9563042021-02-25 09:45:49 -0500274
Ethan Nicholasa2fd01c2021-08-12 11:41:59 -0400275 std::unique_ptr<SkSL::Expression> release(PositionInfo pos = PositionInfo::Capture());
Ethan Nicholasb9563042021-02-25 09:45:49 -0500276
277private:
278 std::unique_ptr<SkSL::Expression> fExpression;
279
280 friend class DSLExpression;
281};
282
Ethan Nicholas95046142021-01-07 10:57:27 -0500283} // namespace dsl
284
285} // namespace SkSL
286
287#endif