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