1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_INDEX 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_INDEX 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLPosition.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLExpression.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLIRNode.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 16*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 17*c8dee2aaSAndroid Build Coastguard Worker #include <string> 18*c8dee2aaSAndroid Build Coastguard Worker #include <utility> 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard Worker class Context; 23*c8dee2aaSAndroid Build Coastguard Worker class Type; 24*c8dee2aaSAndroid Build Coastguard Worker enum class OperatorPrecedence : uint8_t; 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker /** 27*c8dee2aaSAndroid Build Coastguard Worker * An expression which extracts a value from an array, vector or matrix, as in 'm[2]'. 28*c8dee2aaSAndroid Build Coastguard Worker */ 29*c8dee2aaSAndroid Build Coastguard Worker class IndexExpression final : public Expression { 30*c8dee2aaSAndroid Build Coastguard Worker public: 31*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr Kind kIRNodeKind = Kind::kIndex; 32*c8dee2aaSAndroid Build Coastguard Worker IndexExpression(const Context & context,Position pos,std::unique_ptr<Expression> base,std::unique_ptr<Expression> index)33*c8dee2aaSAndroid Build Coastguard Worker IndexExpression(const Context& context, Position pos, std::unique_ptr<Expression> base, 34*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> index) 35*c8dee2aaSAndroid Build Coastguard Worker : INHERITED(pos, kIRNodeKind, &IndexType(context, base->type())) 36*c8dee2aaSAndroid Build Coastguard Worker , fBase(std::move(base)) 37*c8dee2aaSAndroid Build Coastguard Worker , fIndex(std::move(index)) {} 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker // Returns a simplified index-expression; reports errors via the ErrorReporter. 40*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Expression> Convert(const Context& context, 41*c8dee2aaSAndroid Build Coastguard Worker Position pos, 42*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> base, 43*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> index); 44*c8dee2aaSAndroid Build Coastguard Worker 45*c8dee2aaSAndroid Build Coastguard Worker // Returns a simplified index-expression; reports errors via ASSERT. 46*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Expression> Make(const Context& context, 47*c8dee2aaSAndroid Build Coastguard Worker Position pos, 48*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> base, 49*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> index); 50*c8dee2aaSAndroid Build Coastguard Worker 51*c8dee2aaSAndroid Build Coastguard Worker /** 52*c8dee2aaSAndroid Build Coastguard Worker * Given a type, returns the type that will result from extracting an array value from it. 53*c8dee2aaSAndroid Build Coastguard Worker */ 54*c8dee2aaSAndroid Build Coastguard Worker static const Type& IndexType(const Context& context, const Type& type); 55*c8dee2aaSAndroid Build Coastguard Worker base()56*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression>& base() { 57*c8dee2aaSAndroid Build Coastguard Worker return fBase; 58*c8dee2aaSAndroid Build Coastguard Worker } 59*c8dee2aaSAndroid Build Coastguard Worker base()60*c8dee2aaSAndroid Build Coastguard Worker const std::unique_ptr<Expression>& base() const { 61*c8dee2aaSAndroid Build Coastguard Worker return fBase; 62*c8dee2aaSAndroid Build Coastguard Worker } 63*c8dee2aaSAndroid Build Coastguard Worker index()64*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression>& index() { 65*c8dee2aaSAndroid Build Coastguard Worker return fIndex; 66*c8dee2aaSAndroid Build Coastguard Worker } 67*c8dee2aaSAndroid Build Coastguard Worker index()68*c8dee2aaSAndroid Build Coastguard Worker const std::unique_ptr<Expression>& index() const { 69*c8dee2aaSAndroid Build Coastguard Worker return fIndex; 70*c8dee2aaSAndroid Build Coastguard Worker } 71*c8dee2aaSAndroid Build Coastguard Worker clone(Position pos)72*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> clone(Position pos) const override { 73*c8dee2aaSAndroid Build Coastguard Worker return std::unique_ptr<Expression>(new IndexExpression(pos, this->base()->clone(), 74*c8dee2aaSAndroid Build Coastguard Worker this->index()->clone(), 75*c8dee2aaSAndroid Build Coastguard Worker &this->type())); 76*c8dee2aaSAndroid Build Coastguard Worker } 77*c8dee2aaSAndroid Build Coastguard Worker 78*c8dee2aaSAndroid Build Coastguard Worker std::string description(OperatorPrecedence) const override; 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Expression; 81*c8dee2aaSAndroid Build Coastguard Worker 82*c8dee2aaSAndroid Build Coastguard Worker private: IndexExpression(Position pos,std::unique_ptr<Expression> base,std::unique_ptr<Expression> index,const Type * type)83*c8dee2aaSAndroid Build Coastguard Worker IndexExpression(Position pos, std::unique_ptr<Expression> base, 84*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> index, const Type* type) 85*c8dee2aaSAndroid Build Coastguard Worker : INHERITED(pos, Kind::kIndex, type) 86*c8dee2aaSAndroid Build Coastguard Worker , fBase(std::move(base)) 87*c8dee2aaSAndroid Build Coastguard Worker , fIndex(std::move(index)) {} 88*c8dee2aaSAndroid Build Coastguard Worker 89*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> fBase; 90*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> fIndex; 91*c8dee2aaSAndroid Build Coastguard Worker }; 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker #endif 96