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