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_FLOATLITERAL 9 #define SKSL_FLOATLITERAL 10 11 #include "include/core/SkTypes.h" 12 #include "include/private/SkSLDefines.h" 13 #include "include/private/SkSLIRNode.h" 14 #include "include/sksl/SkSLPosition.h" 15 #include "src/sksl/SkSLBuiltinTypes.h" 16 #include "src/sksl/SkSLContext.h" 17 #include "src/sksl/ir/SkSLExpression.h" 18 #include "src/sksl/ir/SkSLType.h" 19 20 #include <cstdint> 21 #include <cinttypes> 22 #include <memory> 23 #include <optional> 24 #include <string> 25 26 namespace SkSL { 27 28 enum class OperatorPrecedence : uint8_t; 29 30 /** 31 * A literal value. These can contain ints, floats, or booleans. 32 */ 33 34 class Literal : public Expression { 35 public: 36 inline static constexpr Kind kIRNodeKind = Kind::kLiteral; 37 Literal(Position pos,double value,const Type * type)38 Literal(Position pos, double value, const Type* type) 39 : INHERITED(pos, kIRNodeKind, type) 40 , fValue(value) {} 41 42 // Makes a literal of $floatLiteral type. MakeFloat(const Context & context,Position pos,float value)43 static std::unique_ptr<Literal> MakeFloat(const Context& context, Position pos, 44 float value) { 45 return std::make_unique<Literal>(pos, value, context.fTypes.fFloatLiteral.get()); 46 } 47 48 // Makes a float literal of the specified type. MakeFloat(Position pos,float value,const Type * type)49 static std::unique_ptr<Literal> MakeFloat(Position pos, float value, const Type* type) { 50 SkASSERT(type->isFloat()); 51 return std::make_unique<Literal>(pos, value, type); 52 } 53 54 // Makes a literal of $intLiteral type. MakeInt(const Context & context,Position pos,SKSL_INT value)55 static std::unique_ptr<Literal> MakeInt(const Context& context, Position pos, 56 SKSL_INT value) { 57 return std::make_unique<Literal>(pos, value, context.fTypes.fIntLiteral.get()); 58 } 59 60 // Makes an int literal of the specified type. MakeInt(Position pos,SKSL_INT value,const Type * type)61 static std::unique_ptr<Literal> MakeInt(Position pos, SKSL_INT value, const Type* type) { 62 SkASSERT(type->isInteger()); 63 SkASSERTF(value >= type->minimumValue(), "Value %" PRId64 " does not fit in type %s", 64 value, type->description().c_str()); 65 SkASSERTF(value <= type->maximumValue(), "Value %" PRId64 " does not fit in type %s", 66 value, type->description().c_str()); 67 return std::make_unique<Literal>(pos, value, type); 68 } 69 70 // Makes a literal of boolean type. MakeBool(const Context & context,Position pos,bool value)71 static std::unique_ptr<Literal> MakeBool(const Context& context, Position pos, bool value) { 72 return std::make_unique<Literal>(pos, value, context.fTypes.fBool.get()); 73 } 74 75 // Makes a literal of boolean type. (Functionally identical to the above, but useful if you 76 // don't have access to the Context.) MakeBool(Position pos,bool value,const Type * type)77 static std::unique_ptr<Literal> MakeBool(Position pos, bool value, const Type* type) { 78 SkASSERT(type->isBoolean()); 79 return std::make_unique<Literal>(pos, value, type); 80 } 81 82 // Makes a literal of the specified type, rounding as needed. Make(Position pos,double value,const Type * type)83 static std::unique_ptr<Literal> Make(Position pos, double value, const Type* type) { 84 if (type->isFloat()) { 85 return MakeFloat(pos, value, type); 86 } 87 if (type->isInteger()) { 88 return MakeInt(pos, value, type); 89 } 90 SkASSERT(type->isBoolean()); 91 return MakeBool(pos, value, type); 92 } 93 floatValue()94 float floatValue() const { 95 SkASSERT(this->type().isFloat()); 96 return (SKSL_FLOAT)fValue; 97 } 98 intValue()99 SKSL_INT intValue() const { 100 SkASSERT(this->type().isInteger()); 101 return (SKSL_INT)fValue; 102 } 103 boolValue()104 SKSL_INT boolValue() const { 105 SkASSERT(this->type().isBoolean()); 106 return (bool)fValue; 107 } 108 value()109 double value() const { 110 return fValue; 111 } 112 description(OperatorPrecedence)113 std::string description(OperatorPrecedence) const override; 114 115 ComparisonResult compareConstant(const Expression& other) const override { 116 if (!other.is<Literal>() || this->type().numberKind() != other.type().numberKind()) { 117 return ComparisonResult::kUnknown; 118 } 119 return this->value() == other.as<Literal>().value() 120 ? ComparisonResult::kEqual 121 : ComparisonResult::kNotEqual; 122 } 123 clone(Position pos)124 std::unique_ptr<Expression> clone(Position pos) const override { 125 return std::make_unique<Literal>(pos, this->value(), &this->type()); 126 } 127 supportsConstantValues()128 bool supportsConstantValues() const override { 129 return true; 130 } 131 getConstantValue(int n)132 std::optional<double> getConstantValue(int n) const override { 133 SkASSERT(n == 0); 134 return fValue; 135 } 136 137 private: 138 double fValue; 139 140 using INHERITED = Expression; 141 }; 142 143 } // namespace SkSL 144 145 #endif 146