| /* |
| * 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_OPERATORS |
| #define SKSL_OPERATORS |
| |
| #include "include/private/SkSLDefines.h" |
| #include "src/sksl/SkSLLexer.h" |
| |
| #include <string_view> |
| |
| namespace SkSL { |
| |
| class Context; |
| class Type; |
| |
| class Operator { |
| public: |
| using Kind = Token::Kind; |
| |
| // Allow implicit conversion from Token::Kind, since this is just a utility wrapper on top. |
| Operator(Token::Kind t) : fKind(t) { |
| SkASSERTF(this->isOperator(), "token-kind %d is not an operator", (int)fKind); |
| } |
| |
| 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 |
| }; |
| |
| Token::Kind kind() const { return fKind; } |
| |
| bool isEquality() const { |
| return fKind == Token::Kind::TK_EQEQ || fKind == Token::Kind::TK_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 logical (comparison) operators: |
| * < <= > >= |
| */ |
| bool isLogical() 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 |