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