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