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_OPERATOR 9 #define SKSL_OPERATOR 10 11 #include <cstdint> 12 #include <string_view> 13 14 namespace SkSL { 15 16 class Context; 17 class Type; 18 19 enum class OperatorKind : uint8_t { 20 PLUS, 21 MINUS, 22 STAR, 23 SLASH, 24 PERCENT, 25 SHL, 26 SHR, 27 LOGICALNOT, 28 LOGICALAND, 29 LOGICALOR, 30 LOGICALXOR, 31 BITWISENOT, 32 BITWISEAND, 33 BITWISEOR, 34 BITWISEXOR, 35 EQ, 36 EQEQ, 37 NEQ, 38 LT, 39 GT, 40 LTEQ, 41 GTEQ, 42 PLUSEQ, 43 MINUSEQ, 44 STAREQ, 45 SLASHEQ, 46 PERCENTEQ, 47 SHLEQ, 48 SHREQ, 49 BITWISEANDEQ, 50 BITWISEOREQ, 51 BITWISEXOREQ, 52 PLUSPLUS, 53 MINUSMINUS, 54 COMMA 55 }; 56 57 enum class OperatorPrecedence : uint8_t { 58 kParentheses = 1, 59 kPostfix = 2, 60 kPrefix = 3, 61 kMultiplicative = 4, 62 kAdditive = 5, 63 kShift = 6, 64 kRelational = 7, 65 kEquality = 8, 66 kBitwiseAnd = 9, 67 kBitwiseXor = 10, 68 kBitwiseOr = 11, 69 kLogicalAnd = 12, 70 kLogicalXor = 13, 71 kLogicalOr = 14, 72 kTernary = 15, 73 kAssignment = 16, 74 kSequence = 17, 75 kTopLevel = kSequence 76 }; 77 78 class Operator { 79 public: 80 using Kind = OperatorKind; 81 Operator(Kind op)82 Operator(Kind op) : fKind(op) {} 83 kind()84 Kind kind() const { return fKind; } 85 isEquality()86 bool isEquality() const { 87 return fKind == Kind::EQEQ || fKind == Kind::NEQ; 88 } 89 90 OperatorPrecedence getBinaryPrecedence() const; 91 92 // Returns the operator name surrounded by the expected whitespace for a tidy binary expression. 93 const char* operatorName() const; 94 95 // Returns the operator name without any surrounding whitespace. 96 std::string_view tightOperatorName() const; 97 98 // Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.) 99 bool isAssignment() const; 100 101 // Given a compound assignment operator, returns the non-assignment version of the operator 102 // (e.g. '+=' becomes '+') 103 Operator removeAssignment() const; 104 105 /** 106 * Defines the set of relational (comparison) operators: 107 * < <= > >= 108 */ 109 bool isRelational() const; 110 111 /** 112 * Defines the set of operators which are only valid on integral types: 113 * << <<= >> >>= & &= | |= ^ ^= % %= 114 */ 115 bool isOnlyValidForIntegralTypes() const; 116 117 /** 118 * Defines the set of operators which perform vector/matrix math. 119 * + += - -= * *= / /= % %= << <<= >> >>= & &= | |= ^ ^= 120 */ 121 bool isValidForMatrixOrVector() const; 122 123 /* 124 * Defines the set of operators allowed by The OpenGL ES Shading Language 1.00, Section 5.1. 125 * The set of illegal (reserved) operators are the ones that only make sense with integral 126 * types. This is not a coincidence: It's because ES2 doesn't require 'int' to be anything but 127 * syntactic sugar for floats with truncation after each operation. 128 */ isAllowedInStrictES2Mode()129 bool isAllowedInStrictES2Mode() const { 130 return !this->isOnlyValidForIntegralTypes(); 131 } 132 133 /** 134 * Determines the operand and result types of a binary expression. Returns true if the 135 * expression is legal, false otherwise. If false, the values of the out parameters are 136 * undefined. 137 */ 138 bool determineBinaryType(const Context& context, 139 const Type& left, 140 const Type& right, 141 const Type** outLeftType, 142 const Type** outRightType, 143 const Type** outResultType) const; 144 145 private: 146 bool isOperator() const; 147 bool isMatrixMultiply(const Type& left, const Type& right) const; 148 149 Kind fKind; 150 }; 151 152 } // namespace SkSL 153 154 #endif 155