• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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