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