• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
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_BINARYEXPRESSION
9 #define SKSL_BINARYEXPRESSION
10 
11 #ifdef SKSL_EXT
12 #include "src/sksl/SkSLLexerExt.h"
13 #else
14 #include "src/sksl/SkSLLexer.h"
15 #endif
16 #include "src/sksl/SkSLOperators.h"
17 #include "src/sksl/ir/SkSLExpression.h"
18 #include "src/sksl/ir/SkSLFieldAccess.h"
19 #include "src/sksl/ir/SkSLIndexExpression.h"
20 #include "src/sksl/ir/SkSLSwizzle.h"
21 #include "src/sksl/ir/SkSLTernaryExpression.h"
22 
23 #include <memory>
24 
25 namespace SkSL {
26 
27 /**
28  * A binary operation.
29  */
30 class BinaryExpression final : public Expression {
31 public:
32     inline static constexpr Kind kExpressionKind = Kind::kBinary;
33 
BinaryExpression(int line,std::unique_ptr<Expression> left,Operator op,std::unique_ptr<Expression> right,const Type * type)34     BinaryExpression(int line, std::unique_ptr<Expression> left, Operator op,
35                      std::unique_ptr<Expression> right, const Type* type)
36         : INHERITED(line, kExpressionKind, type)
37         , fLeft(std::move(left))
38         , fOperator(op)
39         , fRight(std::move(right)) {
40         // If we are assigning to a VariableReference, ensure that it is set to Write or ReadWrite.
41         SkASSERT(!op.isAssignment() || CheckRef(*this->left()));
42     }
43 
44     // Creates a potentially-simplified form of the expression. Determines the result type
45     // programmatically. Typechecks and coerces input expressions; reports errors via ErrorReporter.
46     static std::unique_ptr<Expression> Convert(const Context& context,
47                                                std::unique_ptr<Expression> left,
48                                                Operator op,
49                                                std::unique_ptr<Expression> right);
50 
51     // Creates a potentially-simplified form of the expression. Determines the result type
52     // programmatically. Asserts if the expressions do not typecheck or are otherwise invalid.
53     static std::unique_ptr<Expression> Make(const Context& context,
54                                             std::unique_ptr<Expression> left,
55                                             Operator op,
56                                             std::unique_ptr<Expression> right);
57 
58     // Creates a potentially-simplified form of the expression. Result type is passed in.
59     // Asserts if the expressions do not typecheck or are otherwise invalid.
60     static std::unique_ptr<Expression> Make(const Context& context,
61                                             std::unique_ptr<Expression> left,
62                                             Operator op,
63                                             std::unique_ptr<Expression> right,
64                                             const Type* resultType);
65 
left()66     std::unique_ptr<Expression>& left() {
67         return fLeft;
68     }
69 
left()70     const std::unique_ptr<Expression>& left() const {
71         return fLeft;
72     }
73 
right()74     std::unique_ptr<Expression>& right() {
75         return fRight;
76     }
77 
right()78     const std::unique_ptr<Expression>& right() const {
79         return fRight;
80     }
81 
getOperator()82     Operator getOperator() const {
83         return fOperator;
84     }
85 
isConstantOrUniform()86     bool isConstantOrUniform() const override {
87         return this->left()->isConstantOrUniform() && this->right()->isConstantOrUniform();
88     }
89 
hasProperty(Property property)90     bool hasProperty(Property property) const override {
91         if (property == Property::kSideEffects && this->getOperator().isAssignment()) {
92             return true;
93         }
94         return this->left()->hasProperty(property) || this->right()->hasProperty(property);
95     }
96 
97     std::unique_ptr<Expression> clone() const override;
98 
99     String description() const override;
100 
101 private:
102     static bool CheckRef(const Expression& expr);
103 
104     std::unique_ptr<Expression> fLeft;
105     Operator fOperator;
106     std::unique_ptr<Expression> fRight;
107 
108     using INHERITED = Expression;
109 };
110 
111 }  // namespace SkSL
112 
113 #endif
114