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