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