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_TERNARYEXPRESSION 9 #define SKSL_TERNARYEXPRESSION 10 11 #include "include/core/SkTypes.h" 12 #include "src/sksl/SkSLPosition.h" 13 #include "src/sksl/ir/SkSLExpression.h" 14 #include "src/sksl/ir/SkSLIRNode.h" 15 #include "src/sksl/ir/SkSLType.h" 16 17 #include <cstdint> 18 #include <memory> 19 #include <string> 20 #include <utility> 21 22 namespace SkSL { 23 24 class Context; 25 enum class OperatorPrecedence : uint8_t; 26 27 /** 28 * A ternary expression (test ? ifTrue : ifFalse). 29 */ 30 class TernaryExpression final : public Expression { 31 public: 32 inline static constexpr Kind kIRNodeKind = Kind::kTernary; 33 TernaryExpression(Position pos,std::unique_ptr<Expression> test,std::unique_ptr<Expression> ifTrue,std::unique_ptr<Expression> ifFalse)34 TernaryExpression(Position pos, std::unique_ptr<Expression> test, 35 std::unique_ptr<Expression> ifTrue, std::unique_ptr<Expression> ifFalse) 36 : INHERITED(pos, kIRNodeKind, &ifTrue->type()) 37 , fTest(std::move(test)) 38 , fIfTrue(std::move(ifTrue)) 39 , fIfFalse(std::move(ifFalse)) { 40 SkASSERT(this->ifTrue()->type().matches(this->ifFalse()->type())); 41 } 42 43 // Creates a potentially-simplified form of the ternary. Typechecks and coerces input 44 // expressions; reports errors via ErrorReporter. 45 static std::unique_ptr<Expression> Convert(const Context& context, 46 Position pos, 47 std::unique_ptr<Expression> test, 48 std::unique_ptr<Expression> ifTrue, 49 std::unique_ptr<Expression> ifFalse); 50 51 // Creates a potentially-simplified form of the ternary; reports errors via ASSERT. 52 static std::unique_ptr<Expression> Make(const Context& context, 53 Position pos, 54 std::unique_ptr<Expression> test, 55 std::unique_ptr<Expression> ifTrue, 56 std::unique_ptr<Expression> ifFalse); 57 test()58 std::unique_ptr<Expression>& test() { 59 return fTest; 60 } 61 test()62 const std::unique_ptr<Expression>& test() const { 63 return fTest; 64 } 65 ifTrue()66 std::unique_ptr<Expression>& ifTrue() { 67 return fIfTrue; 68 } 69 ifTrue()70 const std::unique_ptr<Expression>& ifTrue() const { 71 return fIfTrue; 72 } 73 ifFalse()74 std::unique_ptr<Expression>& ifFalse() { 75 return fIfFalse; 76 } 77 ifFalse()78 const std::unique_ptr<Expression>& ifFalse() const { 79 return fIfFalse; 80 } 81 clone(Position pos)82 std::unique_ptr<Expression> clone(Position pos) const override { 83 return std::make_unique<TernaryExpression>(pos, this->test()->clone(), 84 this->ifTrue()->clone(), 85 this->ifFalse()->clone()); 86 } 87 88 std::string description(OperatorPrecedence parentPrecedence) const override; 89 90 private: 91 std::unique_ptr<Expression> fTest; 92 std::unique_ptr<Expression> fIfTrue; 93 std::unique_ptr<Expression> fIfFalse; 94 95 using INHERITED = Expression; 96 }; 97 98 } // namespace SkSL 99 100 #endif 101