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_EXPRESSION
9 #define SKSL_EXPRESSION
10 
11 #include "src/sksl/ir/SkSLType.h"
12 #include "src/sksl/ir/SkSLVariable.h"
13 
14 #include <unordered_map>
15 
16 namespace SkSL {
17 
18 struct Expression;
19 class IRGenerator;
20 
21 typedef std::unordered_map<const Variable*, std::unique_ptr<Expression>*> DefinitionMap;
22 
23 /**
24  * Abstract supertype of all expressions.
25  */
26 struct Expression : public IRNode {
27     enum Kind {
28         kBinary_Kind,
29         kBoolLiteral_Kind,
30         kConstructor_Kind,
31         kExternalFunctionCall_Kind,
32         kExternalValue_Kind,
33         kIntLiteral_Kind,
34         kFieldAccess_Kind,
35         kFloatLiteral_Kind,
36         kFunctionReference_Kind,
37         kFunctionCall_Kind,
38         kIndex_Kind,
39         kNullLiteral_Kind,
40         kPrefix_Kind,
41         kPostfix_Kind,
42         kSetting_Kind,
43         kSwizzle_Kind,
44         kVariableReference_Kind,
45         kTernary_Kind,
46         kTypeReference_Kind,
47         kDefined_Kind
48     };
49 
ExpressionExpression50     Expression(int offset, Kind kind, const Type& type)
51     : INHERITED(offset)
52     , fKind(kind)
53     , fType(std::move(type)) {}
54 
55     /**
56      * Returns true if this expression is constant. compareConstant must be implemented for all
57      * constants!
58      */
isConstantExpression59     virtual bool isConstant() const {
60         return false;
61     }
62 
63     /**
64      * Compares this constant expression against another constant expression of the same type. It is
65      * an error to call this on non-constant expressions, or if the types of the expressions do not
66      * match.
67      */
compareConstantExpression68     virtual bool compareConstant(const Context& context, const Expression& other) const {
69         ABORT("cannot call compareConstant on this type");
70     }
71 
72     /**
73      * For an expression which evaluates to a constant int, returns the value. Otherwise calls
74      * ABORT.
75      */
getConstantIntExpression76     virtual int64_t getConstantInt() const {
77         ABORT("not a constant int");
78     }
79 
80     /**
81      * For an expression which evaluates to a constant float, returns the value. Otherwise calls
82      * ABORT.
83      */
getConstantFloatExpression84     virtual double getConstantFloat() const {
85         ABORT("not a constant float");
86     }
87 
88     /**
89      * Returns true if evaluating the expression potentially has side effects. Expressions may never
90      * return false if they actually have side effects, but it is legal (though suboptimal) to
91      * return true if there are not actually any side effects.
92      */
93     virtual bool hasSideEffects() const = 0;
94 
95     /**
96      * Given a map of known constant variable values, substitute them in for references to those
97      * variables occurring in this expression and its subexpressions.  Similar simplifications, such
98      * as folding a constant binary expression down to a single value, may also be performed.
99      * Returns a new expression which replaces this expression, or null if no replacements were
100      * made. If a new expression is returned, this expression is no longer valid.
101      */
constantPropagateExpression102     virtual std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
103                                                           const DefinitionMap& definitions) {
104         return nullptr;
105     }
106 
coercionCostExpression107     virtual int coercionCost(const Type& target) const {
108         return fType.coercionCost(target);
109     }
110 
111     /**
112      * For a literal vector expression, return the floating point value of the n'th vector
113      * component. It is an error to call this method on an expression which is not a literal vector.
114      */
getFVecComponentExpression115     virtual SKSL_FLOAT getFVecComponent(int n) const {
116         SkASSERT(false);
117         return 0;
118     }
119 
120     /**
121      * For a literal vector expression, return the integer value of the n'th vector component. It is
122      * an error to call this method on an expression which is not a literal vector.
123      */
getIVecComponentExpression124     virtual SKSL_INT getIVecComponent(int n) const {
125         SkASSERT(false);
126         return 0;
127     }
128 
129     /**
130      * For a literal matrix expression, return the floating point value of the component at
131      * [col][row]. It is an error to call this method on an expression which is not a literal
132      * matrix.
133      */
getMatComponentExpression134     virtual SKSL_FLOAT getMatComponent(int col, int row) const {
135         SkASSERT(false);
136         return 0;
137     }
138 
139     virtual std::unique_ptr<Expression> clone() const = 0;
140 
141     const Kind fKind;
142     const Type& fType;
143 
144     typedef IRNode INHERITED;
145 };
146 
147 } // namespace
148 
149 #endif
150