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