|  | /* | 
|  | * 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 <cstdint> | 
|  | #include <string_view> | 
|  |  | 
|  | namespace SkSL { | 
|  |  | 
|  | class Context; | 
|  | class Type; | 
|  |  | 
|  | enum class OperatorKind : uint8_t { | 
|  | 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 OperatorPrecedence : uint8_t { | 
|  | 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,        // a comma-separated sequence | 
|  | kExpression     = kSequence, // a top-level expression, anywhere in a statement | 
|  | kStatement      = 18,        // a standalone expression-statement | 
|  | }; | 
|  |  | 
|  | class Operator { | 
|  | public: | 
|  | using Kind = OperatorKind; | 
|  |  | 
|  | Operator(Kind op) : fKind(op) {} | 
|  |  | 
|  | Kind kind() const { return fKind; } | 
|  |  | 
|  | bool isEquality() const { | 
|  | return fKind == Kind::EQEQ || fKind == Kind::NEQ; | 
|  | } | 
|  |  | 
|  | OperatorPrecedence 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; | 
|  |  | 
|  | // Returns true if op is any compound-assignment operator (`+=`, `-=`, etc.) but false for `=` | 
|  | bool isCompoundAssignment() 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 |