2021-01-07 15:57:27 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
2021-06-23 17:51:55 +00:00
|
|
|
#include "include/core/SkStringView.h"
|
2021-01-07 15:57:27 +00:00
|
|
|
#include "include/core/SkTypes.h"
|
2021-05-06 14:47:06 +00:00
|
|
|
#include "include/private/SkTArray.h"
|
2021-03-04 19:30:25 +00:00
|
|
|
#include "include/sksl/DSLErrorHandling.h"
|
2021-05-06 14:47:06 +00:00
|
|
|
#include "include/sksl/DSLWrapper.h"
|
2021-01-07 15:57:27 +00:00
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
namespace SkSL {
|
|
|
|
|
|
|
|
class Expression;
|
2021-03-04 19:30:25 +00:00
|
|
|
class Type;
|
2021-01-07 15:57:27 +00:00
|
|
|
|
|
|
|
namespace dsl {
|
|
|
|
|
2021-02-25 14:45:49 +00:00
|
|
|
class DSLPossibleExpression;
|
2021-02-09 20:22:57 +00:00
|
|
|
class DSLStatement;
|
2021-05-06 14:47:06 +00:00
|
|
|
class DSLType;
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
class DSLVarBase;
|
2021-01-07 15:57:27 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents an expression such as 'cos(x)' or 'a + b'.
|
|
|
|
*/
|
|
|
|
class DSLExpression {
|
|
|
|
public:
|
|
|
|
DSLExpression(const DSLExpression&) = delete;
|
|
|
|
|
2021-03-04 19:30:25 +00:00
|
|
|
DSLExpression(DSLExpression&&);
|
2021-01-07 15:57:27 +00:00
|
|
|
|
|
|
|
DSLExpression();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an expression representing a literal float.
|
|
|
|
*/
|
|
|
|
DSLExpression(float value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an expression representing a literal float.
|
|
|
|
*/
|
|
|
|
DSLExpression(double value)
|
|
|
|
: DSLExpression((float) value) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an expression representing a literal int.
|
|
|
|
*/
|
|
|
|
DSLExpression(int value);
|
|
|
|
|
2021-05-03 18:25:35 +00:00
|
|
|
/**
|
|
|
|
* Creates an expression representing a literal uint.
|
|
|
|
*/
|
|
|
|
DSLExpression(unsigned int value);
|
|
|
|
|
2021-01-07 15:57:27 +00:00
|
|
|
/**
|
|
|
|
* Creates an expression representing a literal bool.
|
|
|
|
*/
|
|
|
|
DSLExpression(bool value);
|
|
|
|
|
2021-01-11 20:42:44 +00:00
|
|
|
/**
|
|
|
|
* Creates an expression representing a variable reference.
|
|
|
|
*/
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
DSLExpression(DSLVarBase& var);
|
2021-03-25 21:49:08 +00:00
|
|
|
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
DSLExpression(DSLVarBase&& var);
|
2021-01-11 20:42:44 +00:00
|
|
|
|
2021-02-25 14:45:49 +00:00
|
|
|
DSLExpression(DSLPossibleExpression expr, PositionInfo pos = PositionInfo());
|
|
|
|
|
2021-06-23 14:27:09 +00:00
|
|
|
explicit DSLExpression(std::unique_ptr<SkSL::Expression> expression);
|
2021-05-06 14:47:06 +00:00
|
|
|
|
2021-01-07 15:57:27 +00:00
|
|
|
~DSLExpression();
|
|
|
|
|
2021-05-06 14:47:06 +00:00
|
|
|
DSLType type();
|
|
|
|
|
2021-01-13 15:38:59 +00:00
|
|
|
/**
|
|
|
|
* Overloads the '=' operator to create an SkSL assignment statement.
|
|
|
|
*/
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator=(DSLExpression other);
|
2021-01-13 15:38:59 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression x(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression y(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression z(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression w(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression r(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression g(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression b(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLExpression a(PositionInfo pos = PositionInfo());
|
2021-01-26 19:31:29 +00:00
|
|
|
|
2021-02-11 20:18:31 +00:00
|
|
|
/**
|
|
|
|
* Creates an SkSL struct field access expression.
|
|
|
|
*/
|
2021-06-23 17:51:55 +00:00
|
|
|
DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo());
|
2021-02-11 20:18:31 +00:00
|
|
|
|
2021-01-26 15:07:01 +00:00
|
|
|
/**
|
|
|
|
* Creates an SkSL array index expression.
|
|
|
|
*/
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator[](DSLExpression index);
|
2021-01-26 15:07:01 +00:00
|
|
|
|
2021-05-06 14:47:06 +00:00
|
|
|
DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args);
|
|
|
|
|
2021-06-25 16:31:44 +00:00
|
|
|
/**
|
|
|
|
* Returns true if this object contains an expression. DSLExpressions which were created with
|
|
|
|
* the empty constructor or which have already been release()ed are not valid. DSLExpressions
|
|
|
|
* created with errors are still considered valid (but contain a poison value).
|
|
|
|
*/
|
2021-06-23 14:27:09 +00:00
|
|
|
bool valid() const {
|
|
|
|
return fExpression != nullptr;
|
|
|
|
}
|
|
|
|
|
2021-01-07 15:57:27 +00:00
|
|
|
/**
|
2021-06-25 16:31:44 +00:00
|
|
|
* Invalidates this object and returns the SkSL expression it represents. It is an error to call
|
|
|
|
* this on an invalid DSLExpression.
|
2021-01-07 15:57:27 +00:00
|
|
|
*/
|
|
|
|
std::unique_ptr<SkSL::Expression> release();
|
|
|
|
|
|
|
|
private:
|
2021-06-25 16:31:44 +00:00
|
|
|
/**
|
|
|
|
* Calls release if this expression is valid, otherwise returns null.
|
|
|
|
*/
|
|
|
|
std::unique_ptr<SkSL::Expression> releaseIfValid();
|
|
|
|
|
2021-05-04 16:22:02 +00:00
|
|
|
void swap(DSLExpression& other);
|
|
|
|
|
2021-01-13 15:38:59 +00:00
|
|
|
/**
|
|
|
|
* Invalidates this object and returns the SkSL expression it represents coerced to the
|
|
|
|
* specified type. If the expression cannot be coerced, reports an error and returns null.
|
|
|
|
*/
|
|
|
|
std::unique_ptr<SkSL::Expression> coerceAndRelease(const SkSL::Type& type);
|
|
|
|
|
2021-01-07 15:57:27 +00:00
|
|
|
std::unique_ptr<SkSL::Expression> fExpression;
|
|
|
|
|
2021-02-16 18:02:57 +00:00
|
|
|
friend DSLExpression SampleChild(int index, DSLExpression coords);
|
|
|
|
|
2021-01-22 20:18:25 +00:00
|
|
|
friend class DSLCore;
|
2021-02-23 17:05:49 +00:00
|
|
|
friend class DSLFunction;
|
2021-02-25 14:45:49 +00:00
|
|
|
friend class DSLPossibleExpression;
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
friend class DSLVarBase;
|
2021-01-07 15:57:27 +00:00
|
|
|
friend class DSLWriter;
|
2021-05-04 16:22:02 +00:00
|
|
|
template<typename T> friend class DSLWrapper;
|
2021-01-07 15:57:27 +00:00
|
|
|
};
|
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator+(DSLExpression left, DSLExpression right);
|
2021-03-08 22:07:58 +00:00
|
|
|
DSLPossibleExpression operator+(DSLExpression expr);
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator+=(DSLExpression left, DSLExpression right);
|
|
|
|
DSLPossibleExpression operator-(DSLExpression left, DSLExpression right);
|
2021-03-08 22:07:58 +00:00
|
|
|
DSLPossibleExpression operator-(DSLExpression expr);
|
2021-02-26 01:50:32 +00:00
|
|
|
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);
|
2021-07-19 16:30:37 +00:00
|
|
|
DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right);
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator,(DSLExpression left, DSLExpression right);
|
2021-04-19 14:55:18 +00:00
|
|
|
DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right);
|
|
|
|
DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right);
|
|
|
|
DSLPossibleExpression operator,(DSLPossibleExpression left, DSLPossibleExpression right);
|
2021-02-26 01:50:32 +00:00
|
|
|
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);
|
2021-01-13 15:38:59 +00:00
|
|
|
|
2021-02-25 14:45:49 +00:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2021-03-04 19:30:25 +00:00
|
|
|
DSLPossibleExpression(DSLPossibleExpression&& other);
|
2021-02-25 14:45:49 +00:00
|
|
|
|
|
|
|
~DSLPossibleExpression();
|
|
|
|
|
2021-06-23 14:27:09 +00:00
|
|
|
bool valid() const {
|
|
|
|
return fExpression != nullptr;
|
|
|
|
}
|
|
|
|
|
2021-05-06 14:47:06 +00:00
|
|
|
DSLType type();
|
|
|
|
|
2021-02-25 14:45:49 +00:00
|
|
|
DSLExpression x(PositionInfo pos = PositionInfo());
|
|
|
|
|
|
|
|
DSLExpression y(PositionInfo pos = PositionInfo());
|
|
|
|
|
|
|
|
DSLExpression z(PositionInfo pos = PositionInfo());
|
|
|
|
|
|
|
|
DSLExpression w(PositionInfo pos = PositionInfo());
|
|
|
|
|
|
|
|
DSLExpression r(PositionInfo pos = PositionInfo());
|
|
|
|
|
|
|
|
DSLExpression g(PositionInfo pos = PositionInfo());
|
|
|
|
|
|
|
|
DSLExpression b(PositionInfo pos = PositionInfo());
|
|
|
|
|
|
|
|
DSLExpression a(PositionInfo pos = PositionInfo());
|
|
|
|
|
2021-06-23 17:51:55 +00:00
|
|
|
DSLExpression field(skstd::string_view name, PositionInfo pos = PositionInfo());
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator=(DSLExpression expr);
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator=(int expr);
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator=(float expr);
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-04-23 20:15:11 +00:00
|
|
|
DSLPossibleExpression operator=(double expr);
|
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator[](DSLExpression index);
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-05-06 14:47:06 +00:00
|
|
|
DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args);
|
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator++();
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator++(int);
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator--();
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-02-26 01:50:32 +00:00
|
|
|
DSLPossibleExpression operator--(int);
|
2021-02-25 14:45:49 +00:00
|
|
|
|
2021-06-25 16:31:44 +00:00
|
|
|
std::unique_ptr<SkSL::Expression> release(PositionInfo pos = PositionInfo());
|
2021-02-25 14:45:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::unique_ptr<SkSL::Expression> fExpression;
|
|
|
|
|
|
|
|
friend class DSLExpression;
|
|
|
|
};
|
|
|
|
|
2021-01-07 15:57:27 +00:00
|
|
|
} // namespace dsl
|
|
|
|
|
|
|
|
} // namespace SkSL
|
|
|
|
|
|
|
|
#endif
|