• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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