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