/* * 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 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