33 const ExpressionArray& operands);
40 return ~static_cast<SKSL_INT>(
value);
46 double (*fn)(
double)) {
51 if (numSlots > std::size(values)) {
56 for (
size_t index = 0; index < numSlots; ++index) {
58 values[index] = fn(*slotValue);
75 switch (
value->kind()) {
76 case Expression::Kind::kLiteral:
77 case Expression::Kind::kConstructorSplat:
78 case Expression::Kind::kConstructorCompound: {
86 case Expression::Kind::kPrefix: {
89 if (prefix.getOperator().kind() == Operator::Kind::MINUS) {
90 return prefix.operand()->clone(
pos);
94 case Expression::Kind::kConstructorArray:
103 case Expression::Kind::kConstructorDiagonalMatrix:
111 std::move(simplified));
127 for (
const std::unique_ptr<Expression>& expr : array) {
130 replacement.
push_back(std::move(simplified));
132 replacement.
push_back(std::make_unique<PrefixExpression>(
pos, Operator::Kind::MINUS,
141 std::unique_ptr<Expression> value) {
148 return std::make_unique<PrefixExpression>(
pos, Operator::Kind::MINUS, std::move(
value));
153 std::unique_ptr<Expression> operand) {
155 switch (
value->kind()) {
156 case Expression::Kind::kLiteral: {
162 case Expression::Kind::kPrefix: {
165 if (prefix.getOperator().kind() == Operator::Kind::LOGICALNOT) {
166 prefix.operand()->fPosition =
pos;
167 return std::move(prefix.operand());
171 case Expression::Kind::kBinary: {
173 std::optional<Operator> replacement;
174 switch (binary.getOperator().kind()) {
183 if (replacement.has_value()) {
185 *replacement, std::move(binary.right()),
195 return std::make_unique<PrefixExpression>(
pos, Operator::Kind::LOGICALNOT, std::move(operand));
200 std::unique_ptr<Expression> operand) {
201 SkASSERT(operand->type().componentType().isInteger());
205 switch (
value->kind()) {
206 case Expression::Kind::kLiteral:
207 case Expression::Kind::kConstructorSplat:
208 case Expression::Kind::kConstructorCompound: {
216 case Expression::Kind::kPrefix: {
219 if (prefix.getOperator().kind() == Operator::Kind::BITWISENOT) {
220 prefix.operand()->fPosition =
pos;
221 return std::move(prefix.operand());
230 return std::make_unique<PrefixExpression>(
pos, Operator::Kind::BITWISENOT, std::move(operand));
236 std::unique_ptr<Expression>
base) {
237 const Type& baseType =
base->type();
239 case Operator::Kind::PLUS:
242 "'+' cannot operate on '" + baseType.
displayName() +
"'");
247 case Operator::Kind::MINUS:
250 "'-' cannot operate on '" + baseType.
displayName() +
"'");
255 case Operator::Kind::PLUSPLUS:
256 case Operator::Kind::MINUSMINUS:
260 "' cannot operate on '" + baseType.
displayName() +
"'");
269 case Operator::Kind::LOGICALNOT:
273 "' cannot operate on '" + baseType.
displayName() +
"'");
278 case Operator::Kind::BITWISENOT:
289 "' cannot operate on '" + baseType.
displayName() +
"'");
295 SK_ABORT(
"unsupported prefix operator");
306 std::unique_ptr<Expression>
base) {
307 const Type& baseType =
base->type();
309 case Operator::Kind::PLUS:
315 case Operator::Kind::MINUS:
320 case Operator::Kind::LOGICALNOT:
324 case Operator::Kind::PLUSPLUS:
325 case Operator::Kind::MINUSMINUS:
330 case Operator::Kind::BITWISENOT:
345 return std::make_unique<PrefixExpression>(
pos, op, std::move(
base));
350 return std::string(needsParens ?
"(" :
"") +
353 std::string(needsParens ?
")" :
"");
#define SK_ABORT(message,...)
#define SkDEBUGFAILF(fmt,...)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right)
static const Expression * GetConstantValueForVariable(const Expression &value)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, ExpressionArray args)
static std::unique_ptr< Expression > MakeFromConstants(const Context &context, Position pos, const Type &type, const double values[])
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
void error(Position position, std::string_view msg)
virtual const Type & type() const
virtual std::unique_ptr< Expression > clone(Position pos) const =0
virtual std::optional< double > getConstantValue(int n) const
std::string description() const final
static std::unique_ptr< Literal > MakeBool(const Context &context, Position pos, bool value)
ExpressionArray & arguments()
std::string_view tightOperatorName() const
const char * operatorName() const
static std::unique_ptr< Expression > Make(const Context &context, Position pos, Operator op, std::unique_ptr< Expression > base)
Operator getOperator() const
static std::unique_ptr< Expression > Convert(const Context &context, Position pos, Operator op, std::unique_ptr< Expression > base)
std::unique_ptr< Expression > & operand()
std::unique_ptr< Expression > & argument()
virtual bool isArray() const
std::unique_ptr< Expression > coerceExpression(std::unique_ptr< Expression > expr, const Context &context) const
virtual const Type & componentType() const
virtual bool isLiteral() const
virtual size_t slotCount() const
virtual const Type & scalarTypeForLiteral() const
bool checkForOutOfRangeLiteral(const Context &context, const Expression &expr) const
std::string displayName() const
void reserve_exact(int n)
bool IsCompileTimeConstant(const Expression &expr)
bool UpdateVariableRefKind(Expression *expr, VariableRefKind kind, ErrorReporter *errors=nullptr)
bool IsAssignable(Expression &expr, AssignmentInfo *info=nullptr, ErrorReporter *errors=nullptr)
static std::unique_ptr< Expression > negate_operand(const Context &context, Position pos, std::unique_ptr< Expression > value)
static std::unique_ptr< Expression > bitwise_not_operand(const Context &context, Position pos, std::unique_ptr< Expression > operand)
static std::unique_ptr< Expression > simplify_negation(const Context &context, Position pos, const Expression &originalExpr)
static std::unique_ptr< Expression > logical_not_operand(const Context &context, Position pos, std::unique_ptr< Expression > operand)
static ExpressionArray negate_operands(const Context &context, Position pos, const ExpressionArray &operands)
static double negate_value(double value)
static double bitwise_not_value(double value)
static std::unique_ptr< Expression > apply_to_elements(const Context &context, Position pos, const Expression &expr, double(*fn)(double))
bool strictES2Mode() const