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