xref: /aosp_15_r20/external/skia/src/sksl/SkSLOperator.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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,        // a comma-separated sequence
75     kExpression     = kSequence, // a top-level expression, anywhere in a statement
76     kStatement      = 18,        // a standalone expression-statement
77 };
78 
79 class Operator {
80 public:
81     using Kind = OperatorKind;
82 
Operator(Kind op)83     Operator(Kind op) : fKind(op) {}
84 
kind()85     Kind kind() const { return fKind; }
86 
isEquality()87     bool isEquality() const {
88         return fKind == Kind::EQEQ || fKind == Kind::NEQ;
89     }
90 
91     OperatorPrecedence getBinaryPrecedence() const;
92 
93     // Returns the operator name surrounded by the expected whitespace for a tidy binary expression.
94     const char* operatorName() const;
95 
96     // Returns the operator name without any surrounding whitespace.
97     std::string_view tightOperatorName() const;
98 
99     // Returns true if op is `=` or any compound-assignment operator (`+=`, `-=`, etc.)
100     bool isAssignment() const;
101 
102     // Returns true if op is any compound-assignment operator (`+=`, `-=`, etc.) but false for `=`
103     bool isCompoundAssignment() const;
104 
105     // Given a compound-assignment operator, returns the non-assignment version of the operator
106     // (e.g. `+=` becomes `+`)
107     Operator removeAssignment() const;
108 
109     /**
110      * Defines the set of relational (comparison) operators:
111      *     <  <=  >  >=
112      */
113     bool isRelational() const;
114 
115     /**
116      * Defines the set of operators which are only valid on integral types:
117      *   <<  <<=  >>  >>=  &  &=  |  |=  ^  ^=  %  %=
118      */
119     bool isOnlyValidForIntegralTypes() const;
120 
121     /**
122      * Defines the set of operators which perform vector/matrix math.
123      *   +  +=  -  -=  *  *=  /  /=  %  %=  <<  <<=  >>  >>=  &  &=  |  |=  ^  ^=
124      */
125     bool isValidForMatrixOrVector() const;
126 
127     /*
128      * Defines the set of operators allowed by The OpenGL ES Shading Language 1.00, Section 5.1.
129      * The set of illegal (reserved) operators are the ones that only make sense with integral
130      * types. This is not a coincidence: It's because ES2 doesn't require 'int' to be anything but
131      * syntactic sugar for floats with truncation after each operation.
132      */
isAllowedInStrictES2Mode()133     bool isAllowedInStrictES2Mode() const {
134         return !this->isOnlyValidForIntegralTypes();
135     }
136 
137     /**
138      * Determines the operand and result types of a binary expression. Returns true if the
139      * expression is legal, false otherwise. If false, the values of the out parameters are
140      * undefined.
141      */
142     bool determineBinaryType(const Context& context,
143                              const Type& left,
144                              const Type& right,
145                              const Type** outLeftType,
146                              const Type** outRightType,
147                              const Type** outResultType) const;
148 
149 private:
150     bool isOperator() const;
151     bool isMatrixMultiply(const Type& left, const Type& right) const;
152 
153     Kind fKind;
154 };
155 
156 }  // namespace SkSL
157 
158 #endif
159