1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SKSL_OPERATORS 9 #define SKSL_OPERATORS 10 11 #include "include/private/SkSLDefines.h" 12 #include "src/sksl/SkSLLexer.h" 13 14 #include <string_view> 15 16 namespace SkSL { 17 18 class Context; 19 class Type; 20 21 class Operator { 22 public: 23 using Kind = Token::Kind; 24 25 // Allow implicit conversion from Token::Kind, since this is just a utility wrapper on top. Operator(Token::Kind t)26 Operator(Token::Kind t) : fKind(t) { 27 SkASSERTF(this->isOperator(), "token-kind %d is not an operator", (int)fKind); 28 } 29 30 enum class Precedence { 31 kParentheses = 1, 32 kPostfix = 2, 33 kPrefix = 3, 34 kMultiplicative = 4, 35 kAdditive = 5, 36 kShift = 6, 37 kRelational = 7, 38 kEquality = 8, 39 kBitwiseAnd = 9, 40 kBitwiseXor = 10, 41 kBitwiseOr = 11, 42 kLogicalAnd = 12, 43 kLogicalXor = 13, 44 kLogicalOr = 14, 45 kTernary = 15, 46 kAssignment = 16, 47 kSequence = 17, 48 kTopLevel = kSequence 49 }; 50 kind()51 Token::Kind kind() const { return fKind; } 52 isEquality()53 bool isEquality() const { 54 return fKind == Token::Kind::TK_EQEQ || fKind == Token::Kind::TK_NEQ; 55 } 56 57 Precedence getBinaryPrecedence() const; 58 59 // Returns the operator name surrounded by the expected whitespace for a tidy binary expression. 60 const char* operatorName() const; 61 62 // Returns the operator name without any surrounding whitespace. 63 std::string_view tightOperatorName() const; 64 65 // Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.) 66 bool isAssignment() const; 67 68 // Given a compound assignment operator, returns the non-assignment version of the operator 69 // (e.g. '+=' becomes '+') 70 Operator removeAssignment() const; 71 72 /** 73 * Defines the set of logical (comparison) operators: 74 * < <= > >= 75 */ 76 bool isLogical() const; 77 78 /** 79 * Defines the set of operators which are only valid on integral types: 80 * << <<= >> >>= & &= | |= ^ ^= % %= 81 */ 82 bool isOnlyValidForIntegralTypes() const; 83 84 /** 85 * Defines the set of operators which perform vector/matrix math. 86 * + += - -= * *= / /= % %= << <<= >> >>= & &= | |= ^ ^= 87 */ 88 bool isValidForMatrixOrVector() const; 89 90 /* 91 * Defines the set of operators allowed by The OpenGL ES Shading Language 1.00, Section 5.1. 92 * The set of illegal (reserved) operators are the ones that only make sense with integral 93 * types. This is not a coincidence: It's because ES2 doesn't require 'int' to be anything but 94 * syntactic sugar for floats with truncation after each operation. 95 */ isAllowedInStrictES2Mode()96 bool isAllowedInStrictES2Mode() const { 97 return !this->isOnlyValidForIntegralTypes(); 98 } 99 100 /** 101 * Determines the operand and result types of a binary expression. Returns true if the 102 * expression is legal, false otherwise. If false, the values of the out parameters are 103 * undefined. 104 */ 105 bool determineBinaryType(const Context& context, 106 const Type& left, 107 const Type& right, 108 const Type** outLeftType, 109 const Type** outRightType, 110 const Type** outResultType) const; 111 112 private: 113 bool isOperator() const; 114 bool isMatrixMultiply(const Type& left, const Type& right) const; 115 116 Kind fKind; 117 }; 118 119 } // namespace SkSL 120 121 #endif 122