blob: 07dad1d7dfe5a1d3b76a519d1982bf7b3c60f03a [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Ethan Nicholas86a43402017-01-19 13:32:00 -05007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_EXPRESSION
9#define SKSL_EXPRESSION
10
ethannicholasb3058bd2016-07-01 08:22:01 -070011#include "SkSLType.h"
Ethan Nicholas86a43402017-01-19 13:32:00 -050012#include "SkSLVariable.h"
13
14#include <unordered_map>
ethannicholasb3058bd2016-07-01 08:22:01 -070015
16namespace SkSL {
17
Ethan Nicholas86a43402017-01-19 13:32:00 -050018struct Expression;
19class IRGenerator;
20
21typedef std::unordered_map<const Variable*, std::unique_ptr<Expression>*> DefinitionMap;
22
ethannicholasb3058bd2016-07-01 08:22:01 -070023/**
Ethan Nicholas86a43402017-01-19 13:32:00 -050024 * Abstract supertype of all expressions.
ethannicholasb3058bd2016-07-01 08:22:01 -070025 */
26struct Expression : public IRNode {
27 enum Kind {
28 kBinary_Kind,
29 kBoolLiteral_Kind,
30 kConstructor_Kind,
31 kIntLiteral_Kind,
32 kFieldAccess_Kind,
33 kFloatLiteral_Kind,
34 kFunctionReference_Kind,
35 kFunctionCall_Kind,
36 kIndex_Kind,
37 kPrefix_Kind,
38 kPostfix_Kind,
39 kSwizzle_Kind,
40 kVariableReference_Kind,
41 kTernary_Kind,
42 kTypeReference_Kind,
ethannicholas22f939e2016-10-13 13:25:34 -070043 kDefined_Kind
ethannicholasb3058bd2016-07-01 08:22:01 -070044 };
45
ethannicholasd598f792016-07-25 10:08:54 -070046 Expression(Position position, Kind kind, const Type& type)
ethannicholasb3058bd2016-07-01 08:22:01 -070047 : INHERITED(position)
48 , fKind(kind)
49 , fType(std::move(type)) {}
50
Ethan Nicholas3deaeb22017-04-25 14:42:11 -040051 /**
52 * Returns true if this expression is constant. compareConstant must be implemented for all
53 * constants!
54 */
ethannicholasb3058bd2016-07-01 08:22:01 -070055 virtual bool isConstant() const {
56 return false;
57 }
58
Ethan Nicholas86a43402017-01-19 13:32:00 -050059 /**
Ethan Nicholas3deaeb22017-04-25 14:42:11 -040060 * Compares this constant expression against another constant expression of the same type. It is
61 * an error to call this on non-constant expressions, or if the types of the expressions do not
62 * match.
63 */
64 virtual bool compareConstant(const Context& context, const Expression& other) const {
65 ABORT("cannot call compareConstant on this type");
66 }
67
68 /**
Ethan Nicholascb670962017-04-20 19:31:52 -040069 * Returns true if evaluating the expression potentially has side effects. Expressions may never
70 * return false if they actually have side effects, but it is legal (though suboptimal) to
71 * return true if there are not actually any side effects.
72 */
73 virtual bool hasSideEffects() const = 0;
74
75 /**
Ethan Nicholas86a43402017-01-19 13:32:00 -050076 * Given a map of known constant variable values, substitute them in for references to those
77 * variables occurring in this expression and its subexpressions. Similar simplifications, such
78 * as folding a constant binary expression down to a single value, may also be performed.
79 * Returns a new expression which replaces this expression, or null if no replacements were
80 * made. If a new expression is returned, this expression is no longer valid.
81 */
82 virtual std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
83 const DefinitionMap& definitions) {
84 return nullptr;
85 }
86
ethannicholasb3058bd2016-07-01 08:22:01 -070087 const Kind fKind;
ethannicholasd598f792016-07-25 10:08:54 -070088 const Type& fType;
ethannicholasb3058bd2016-07-01 08:22:01 -070089
90 typedef IRNode INHERITED;
91};
92
93} // namespace
94
95#endif