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