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