skia2/include/sksl/SkSLOperator.h
Ethan Nicholas 3f5184cfa6 Added an SkSL Operator enum
SkSL::Operator was previously just a thin wrapper around Token::Kind and
everything was therefore written in terms of Token. Since Token is not
accessible from include/ (and we don't want it to be), this creates an
actual Operator enum and eliminates the dependence on Token. This will
enable followup changes to reference Operator from within the DSL
include files.

Change-Id: I49555c9151618fd15970a303d2284972c78c3f21
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/525976
Reviewed-by: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2022-03-31 13:20:57 +00:00

152 lines
3.9 KiB
C++

/*
* Copyright 2021 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_OPERATOR
#define SKSL_OPERATOR
#include <string_view>
namespace SkSL {
class Context;
class Type;
class Operator {
public:
enum class Kind {
PLUS,
MINUS,
STAR,
SLASH,
PERCENT,
SHL,
SHR,
LOGICALNOT,
LOGICALAND,
LOGICALOR,
LOGICALXOR,
BITWISENOT,
BITWISEAND,
BITWISEOR,
BITWISEXOR,
EQ,
EQEQ,
NEQ,
LT,
GT,
LTEQ,
GTEQ,
PLUSEQ,
MINUSEQ,
STAREQ,
SLASHEQ,
PERCENTEQ,
SHLEQ,
SHREQ,
BITWISEANDEQ,
BITWISEOREQ,
BITWISEXOREQ,
PLUSPLUS,
MINUSMINUS,
COMMA
};
enum class Precedence {
kParentheses = 1,
kPostfix = 2,
kPrefix = 3,
kMultiplicative = 4,
kAdditive = 5,
kShift = 6,
kRelational = 7,
kEquality = 8,
kBitwiseAnd = 9,
kBitwiseXor = 10,
kBitwiseOr = 11,
kLogicalAnd = 12,
kLogicalXor = 13,
kLogicalOr = 14,
kTernary = 15,
kAssignment = 16,
kSequence = 17,
kTopLevel = kSequence
};
Operator(Kind op) : fKind(op) {}
Kind kind() const { return fKind; }
bool isEquality() const {
return fKind == Kind::EQEQ || fKind == Kind::NEQ;
}
Precedence getBinaryPrecedence() const;
// Returns the operator name surrounded by the expected whitespace for a tidy binary expression.
const char* operatorName() const;
// Returns the operator name without any surrounding whitespace.
std::string_view tightOperatorName() const;
// Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.)
bool isAssignment() const;
// Given a compound assignment operator, returns the non-assignment version of the operator
// (e.g. '+=' becomes '+')
Operator removeAssignment() const;
/**
* Defines the set of relational (comparison) operators:
* < <= > >=
*/
bool isRelational() const;
/**
* Defines the set of operators which are only valid on integral types:
* << <<= >> >>= & &= | |= ^ ^= % %=
*/
bool isOnlyValidForIntegralTypes() const;
/**
* Defines the set of operators which perform vector/matrix math.
* + += - -= * *= / /= % %= << <<= >> >>= & &= | |= ^ ^=
*/
bool isValidForMatrixOrVector() const;
/*
* Defines the set of operators allowed by The OpenGL ES Shading Language 1.00, Section 5.1.
* The set of illegal (reserved) operators are the ones that only make sense with integral
* types. This is not a coincidence: It's because ES2 doesn't require 'int' to be anything but
* syntactic sugar for floats with truncation after each operation.
*/
bool isAllowedInStrictES2Mode() const {
return !this->isOnlyValidForIntegralTypes();
}
/**
* Determines the operand and result types of a binary expression. Returns true if the
* expression is legal, false otherwise. If false, the values of the out parameters are
* undefined.
*/
bool determineBinaryType(const Context& context,
const Type& left,
const Type& right,
const Type** outLeftType,
const Type** outRightType,
const Type** outResultType) const;
private:
bool isOperator() const;
bool isMatrixMultiply(const Type& left, const Type& right) const;
Kind fKind;
};
} // namespace SkSL
#endif