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