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