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_INDEX
9 #define SKSL_INDEX
10 
11 #include "src/sksl/SkSLContext.h"
12 #include "src/sksl/SkSLUtil.h"
13 #include "src/sksl/ir/SkSLExpression.h"
14 
15 namespace SkSL {
16 
17 /**
18  * An expression which extracts a value from an array or matrix, as in 'm[2]'.
19  */
20 struct IndexExpression final : public Expression {
21     static constexpr Kind kExpressionKind = Kind::kIndex;
22 
IndexExpressionfinal23     IndexExpression(const Context& context, std::unique_ptr<Expression> base,
24                     std::unique_ptr<Expression> index)
25         : INHERITED(base->fOffset, kExpressionKind, &IndexType(context, base->type()))
26         , fBase(std::move(base))
27         , fIndex(std::move(index)) {}
28 
29     // Returns a simplified index-expression; reports errors via the ErrorReporter.
30     static std::unique_ptr<Expression> Convert(const Context& context,
31                                                std::unique_ptr<Expression> base,
32                                                std::unique_ptr<Expression> index);
33 
34     // Returns a simplified index-expression; reports errors via ASSERT.
35     static std::unique_ptr<Expression> Make(const Context& context,
36                                             std::unique_ptr<Expression> base,
37                                             std::unique_ptr<Expression> index);
38 
39     /**
40      * Given a type, returns the type that will result from extracting an array value from it.
41      */
42     static const Type& IndexType(const Context& context, const Type& type);
43 
basefinal44     std::unique_ptr<Expression>& base() {
45         return fBase;
46     }
47 
basefinal48     const std::unique_ptr<Expression>& base() const {
49         return fBase;
50     }
51 
indexfinal52     std::unique_ptr<Expression>& index() {
53         return fIndex;
54     }
55 
indexfinal56     const std::unique_ptr<Expression>& index() const {
57         return fIndex;
58     }
59 
hasPropertyfinal60     bool hasProperty(Property property) const override {
61         return this->base()->hasProperty(property) || this->index()->hasProperty(property);
62     }
63 
clonefinal64     std::unique_ptr<Expression> clone() const override {
65         return std::unique_ptr<Expression>(new IndexExpression(this->base()->clone(),
66                                                                this->index()->clone(),
67                                                                &this->type()));
68     }
69 
descriptionfinal70     String description() const override {
71         return this->base()->description() + "[" + this->index()->description() + "]";
72     }
73 
74     using INHERITED = Expression;
75 
76 private:
IndexExpressionfinal77     IndexExpression(std::unique_ptr<Expression> base, std::unique_ptr<Expression> index,
78                     const Type* type)
79         : INHERITED(base->fOffset, Kind::kIndex, type)
80         , fBase(std::move(base))
81         , fIndex(std::move(index)) {}
82 
83     std::unique_ptr<Expression> fBase;
84     std::unique_ptr<Expression> fIndex;
85 };
86 
87 }  // namespace SkSL
88 
89 #endif
90