blob: 68e615096ce3715aa8aba429c5719c8a84eaceb4 [file] [log] [blame]
/*
* 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