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
13#include <unordered_map>
14
15namespace SkSL {
16
17struct Expression;
18class IRGenerator;
19struct Variable;
20
21typedef std::unordered_map<const Variable*, std::unique_ptr<Expression>*> DefinitionMap;
22
23/**
24 * Abstract supertype of all expressions.
25 */
26struct 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
50 enum class Property {
51 kSideEffects,
52 kContainsRTAdjust
53 };
54
55 Expression(int offset, Kind kind, const Type& type)
56 : INHERITED(offset)
57 , fKind(kind)
58 , fType(std::move(type)) {}
59
60 /**
61 * Returns true if this expression is constant. compareConstant must be implemented for all
62 * constants!
63 */
64 virtual bool isCompileTimeConstant() const {
65 return false;
66 }
67
68 /**
69 * Compares this constant expression against another constant expression of the same type. It is
70 * an error to call this on non-constant expressions, or if the types of the expressions do not
71 * match.
72 */
73 virtual bool compareConstant(const Context& context, const Expression& other) const {
74 ABORT("cannot call compareConstant on this type");
75 }
76
77 /**
78 * For an expression which evaluates to a constant int, returns the value. Otherwise calls
79 * ABORT.
80 */
81 virtual int64_t getConstantInt() const {
82 ABORT("not a constant int");
83 }
84
85 /**
86 * For an expression which evaluates to a constant float, returns the value. Otherwise calls
87 * ABORT.
88 */
89 virtual double getConstantFloat() const {
90 ABORT("not a constant float");
91 }
92
93 /**
94 * Returns true if, given fixed values for uniforms, this expression always evaluates to the
95 * same result with no side effects.
96 */
97 virtual bool isConstantOrUniform() const {
98 SkASSERT(!this->isCompileTimeConstant() || !this->hasSideEffects());
99 return this->isCompileTimeConstant();
100 }
101
102 virtual bool hasProperty(Property property) const = 0;
103
104 bool hasSideEffects() const {
105 return this->hasProperty(Property::kSideEffects);
106 }
107
108 bool containsRTAdjust() const {
109 return this->hasProperty(Property::kContainsRTAdjust);
110 }
111
112 /**
113 * Given a map of known constant variable values, substitute them in for references to those
114 * variables occurring in this expression and its subexpressions. Similar simplifications, such
115 * as folding a constant binary expression down to a single value, may also be performed.
116 * Returns a new expression which replaces this expression, or null if no replacements were
117 * made. If a new expression is returned, this expression is no longer valid.
118 */
119 virtual std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
120 const DefinitionMap& definitions) {
121 return nullptr;
122 }
123
124 virtual int coercionCost(const Type& target) const {
125 return fType.coercionCost(target);
126 }
127
128 /**
129 * For a literal vector expression, return the floating point value of the n'th vector
130 * component. It is an error to call this method on an expression which is not a literal vector.
131 */
132 virtual SKSL_FLOAT getFVecComponent(int n) const {
133 SkASSERT(false);
134 return 0;
135 }
136
137 /**
138 * For a literal vector expression, return the integer value of the n'th vector component. It is
139 * an error to call this method on an expression which is not a literal vector.
140 */
141 virtual SKSL_INT getIVecComponent(int n) const {
142 SkASSERT(false);
143 return 0;
144 }
145
146 /**
147 * For a literal matrix expression, return the floating point value of the component at
148 * [col][row]. It is an error to call this method on an expression which is not a literal
149 * matrix.
150 */
151 virtual SKSL_FLOAT getMatComponent(int col, int row) const {
152 SkASSERT(false);
153 return 0;
154 }
155
156 virtual std::unique_ptr<Expression> clone() const = 0;
157
158 const Kind fKind;
159 const Type& fType;
160
161 typedef IRNode INHERITED;
162};
163
164} // namespace SkSL
165
166#endif
167