blob: 89a1a1e84a88a937ef97e85fa85b6e0b778a8c9c [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,
Ethan Nicholasc0709392017-06-27 11:20:22 -040039 kSetting_Kind,
ethannicholasb3058bd2016-07-01 08:22:01 -070040 kSwizzle_Kind,
41 kVariableReference_Kind,
42 kTernary_Kind,
43 kTypeReference_Kind,
ethannicholas22f939e2016-10-13 13:25:34 -070044 kDefined_Kind
ethannicholasb3058bd2016-07-01 08:22:01 -070045 };
46
ethannicholasd598f792016-07-25 10:08:54 -070047 Expression(Position position, Kind kind, const Type& type)
ethannicholasb3058bd2016-07-01 08:22:01 -070048 : INHERITED(position)
49 , fKind(kind)
50 , fType(std::move(type)) {}
51
Ethan Nicholas3deaeb22017-04-25 14:42:11 -040052 /**
53 * Returns true if this expression is constant. compareConstant must be implemented for all
54 * constants!
55 */
ethannicholasb3058bd2016-07-01 08:22:01 -070056 virtual bool isConstant() const {
57 return false;
58 }
59
Ethan Nicholas86a43402017-01-19 13:32:00 -050060 /**
Ethan Nicholas3deaeb22017-04-25 14:42:11 -040061 * Compares this constant expression against another constant expression of the same type. It is
62 * an error to call this on non-constant expressions, or if the types of the expressions do not
63 * match.
64 */
65 virtual bool compareConstant(const Context& context, const Expression& other) const {
66 ABORT("cannot call compareConstant on this type");
67 }
68
69 /**
Ethan Nicholascb670962017-04-20 19:31:52 -040070 * Returns true if evaluating the expression potentially has side effects. Expressions may never
71 * return false if they actually have side effects, but it is legal (though suboptimal) to
72 * return true if there are not actually any side effects.
73 */
74 virtual bool hasSideEffects() const = 0;
75
76 /**
Ethan Nicholas86a43402017-01-19 13:32:00 -050077 * Given a map of known constant variable values, substitute them in for references to those
78 * variables occurring in this expression and its subexpressions. Similar simplifications, such
79 * as folding a constant binary expression down to a single value, may also be performed.
80 * Returns a new expression which replaces this expression, or null if no replacements were
81 * made. If a new expression is returned, this expression is no longer valid.
82 */
83 virtual std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
84 const DefinitionMap& definitions) {
85 return nullptr;
86 }
87
ethannicholasb3058bd2016-07-01 08:22:01 -070088 const Kind fKind;
ethannicholasd598f792016-07-25 10:08:54 -070089 const Type& fType;
ethannicholasb3058bd2016-07-01 08:22:01 -070090
91 typedef IRNode INHERITED;
92};
93
94} // namespace
95
96#endif