• 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 "include/core/SkTypes.h"
12 #include "include/private/SkSLIRNode.h"
13 #include "include/sksl/SkSLOperator.h"
14 #include "include/sksl/SkSLPosition.h"
15 #include "src/sksl/ir/SkSLExpression.h"
16 
17 #include <memory>
18 #include <string>
19 #include <utility>
20 
21 namespace SkSL {
22 
23 class Context;
24 class Type;
25 class VariableReference;
26 
27 /**
28  * A binary operation.
29  */
30 class BinaryExpression final : public Expression {
31 public:
32     inline static constexpr Kind kIRNodeKind = Kind::kBinary;
33 
BinaryExpression(Position pos,std::unique_ptr<Expression> left,Operator op,std::unique_ptr<Expression> right,const Type * type)34     BinaryExpression(Position pos, std::unique_ptr<Expression> left, Operator op,
35                      std::unique_ptr<Expression> right, const Type* type)
36         : INHERITED(pos, kIRNodeKind, 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                                                Position pos,
48                                                std::unique_ptr<Expression> left,
49                                                Operator op,
50                                                std::unique_ptr<Expression> right);
51 
52     // Creates a potentially-simplified form of the expression. Determines the result type
53     // programmatically. Asserts if the expressions do not typecheck or are otherwise invalid.
54     static std::unique_ptr<Expression> Make(const Context& context,
55                                             Position pos,
56                                             std::unique_ptr<Expression> left,
57                                             Operator op,
58                                             std::unique_ptr<Expression> right);
59 
60     // Creates a potentially-simplified form of the expression. Result type is passed in.
61     // Asserts if the expressions do not typecheck or are otherwise invalid.
62     static std::unique_ptr<Expression> Make(const Context& context,
63                                             Position pos,
64                                             std::unique_ptr<Expression> left,
65                                             Operator op,
66                                             std::unique_ptr<Expression> right,
67                                             const Type* resultType);
68 
left()69     std::unique_ptr<Expression>& left() {
70         return fLeft;
71     }
72 
left()73     const std::unique_ptr<Expression>& left() const {
74         return fLeft;
75     }
76 
right()77     std::unique_ptr<Expression>& right() {
78         return fRight;
79     }
80 
right()81     const std::unique_ptr<Expression>& right() const {
82         return fRight;
83     }
84 
getOperator()85     Operator getOperator() const {
86         return fOperator;
87     }
88 
89     std::unique_ptr<Expression> clone(Position pos) const override;
90 
91     std::string description(OperatorPrecedence parentPrecedence) const override;
92 
93     /**
94      * If the expression is an assignment like `a = 1` or `a += sin(b)`, returns the
95      * VariableReference that will be written to. For other types of expressions, returns null.
96      * Complex expressions that contain inner assignments, like `(a = b) * 2`, will return null.
97      */
98     VariableReference* isAssignmentIntoVariable();
99 
100 private:
101     static bool CheckRef(const Expression& expr);
102 
103     std::unique_ptr<Expression> fLeft;
104     Operator fOperator;
105     std::unique_ptr<Expression> fRight;
106 
107     using INHERITED = Expression;
108 };
109 
110 }  // namespace SkSL
111 
112 #endif
113