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 "SkSLType.h"
12 #include "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         kAppendStage_Kind,
29         kBinary_Kind,
30         kBoolLiteral_Kind,
31         kConstructor_Kind,
32         kIntLiteral_Kind,
33         kFieldAccess_Kind,
34         kFloatLiteral_Kind,
35         kFunctionReference_Kind,
36         kFunctionCall_Kind,
37         kIndex_Kind,
38         kNullLiteral_Kind,
39         kPrefix_Kind,
40         kPostfix_Kind,
41         kSetting_Kind,
42         kSwizzle_Kind,
43         kVariableReference_Kind,
44         kTernary_Kind,
45         kTypeReference_Kind,
46         kDefined_Kind
47     };
48 
ExpressionExpression49     Expression(int offset, Kind kind, const Type& type)
50     : INHERITED(offset)
51     , fKind(kind)
52     , fType(std::move(type)) {}
53 
54     /**
55      * Returns true if this expression is constant. compareConstant must be implemented for all
56      * constants!
57      */
isConstantExpression58     virtual bool isConstant() const {
59         return false;
60     }
61 
62     /**
63      * Compares this constant expression against another constant expression of the same type. It is
64      * an error to call this on non-constant expressions, or if the types of the expressions do not
65      * match.
66      */
compareConstantExpression67     virtual bool compareConstant(const Context& context, const Expression& other) const {
68         ABORT("cannot call compareConstant on this type");
69     }
70 
71     /**
72      * For an expression which evaluates to a constant int, returns the value. Otherwise calls
73      * ABORT.
74      */
getConstantIntExpression75     virtual int64_t getConstantInt() const {
76         ABORT("not a constant int");
77     }
78 
79     /**
80      * For an expression which evaluates to a constant float, returns the value. Otherwise calls
81      * ABORT.
82      */
getConstantFloatExpression83     virtual double getConstantFloat() const {
84         ABORT("not a constant float");
85     }
86 
87     /**
88      * Returns true if evaluating the expression potentially has side effects. Expressions may never
89      * return false if they actually have side effects, but it is legal (though suboptimal) to
90      * return true if there are not actually any side effects.
91      */
92     virtual bool hasSideEffects() const = 0;
93 
94     /**
95      * Given a map of known constant variable values, substitute them in for references to those
96      * variables occurring in this expression and its subexpressions.  Similar simplifications, such
97      * as folding a constant binary expression down to a single value, may also be performed.
98      * Returns a new expression which replaces this expression, or null if no replacements were
99      * made. If a new expression is returned, this expression is no longer valid.
100      */
constantPropagateExpression101     virtual std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
102                                                           const DefinitionMap& definitions) {
103         return nullptr;
104     }
105 
coercionCostExpression106     virtual int coercionCost(const Type& target) const {
107         return fType.coercionCost(target);
108     }
109 
110     virtual std::unique_ptr<Expression> clone() const = 0;
111 
112     const Kind fKind;
113     const Type& fType;
114 
115     typedef IRNode INHERITED;
116 };
117 
118 } // namespace
119 
120 #endif
121