Skip to content

Commit dea2218

Browse files
committed
Value: Implement remaining operators
1 parent dfae647 commit dea2218

File tree

2 files changed

+116
-3
lines changed

2 files changed

+116
-3
lines changed

src/scratch/value.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ Value::Value(std::string stringValue) :
4949
{
5050
if (m_stringValue.empty())
5151
return;
52+
else if (m_stringValue == "Infinity") {
53+
m_isInfinity = true;
54+
m_type = Type::Special;
55+
return;
56+
} else if (m_stringValue == "-Infinity") {
57+
m_isNegativeInfinity = true;
58+
m_type = Type::Special;
59+
return;
60+
} else if (m_stringValue == "NaN") {
61+
m_isNaN = true;
62+
m_type = Type::Special;
63+
return;
64+
}
65+
5266
bool ok;
5367
float f = stringToFloat(m_stringValue, &ok);
5468
if (ok) {

src/scratch/value.h

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,118 @@ class LIBSCRATCHCPP_EXPORT Value
7474
return v1.m_boolValue == v2.m_boolValue;
7575
case Type::String:
7676
return stringsEqual(v1.toUtf16(), v2.toUtf16());
77-
default:
78-
return false;
77+
case Type::Special:
78+
if (v1.isNaN() || v2.isNaN())
79+
return false;
80+
else
81+
return ((v1.isInfinity() && v2.isInfinity()) || (v1.isNegativeInfinity() && v2.isNegativeInfinity()));
7982
}
8083
} else {
8184
if (v1.isNumber() || v2.isNumber())
8285
return v1.toNumber() == v2.toNumber();
8386
else if (v1.isBool() || v2.isBool())
84-
return v1.toBool() == v2.toBool();
87+
return ((!v1.isNaN() && !v2.isNaN()) && (v1.toBool() == v2.toBool()));
8588
else if (v1.isString() || v2.isString())
8689
return stringsEqual(v1.toUtf16(), v2.toUtf16());
8790
else
8891
return false;
8992
}
93+
return false;
94+
}
95+
96+
friend inline bool operator>(const Value &v1, const Value &v2)
97+
{
98+
if (v1.isInfinity()) {
99+
return !v2.isInfinity();
100+
} else if (v1.isNegativeInfinity())
101+
return false;
102+
else if (v2.isInfinity())
103+
return false;
104+
else if (v2.isNegativeInfinity())
105+
return true;
106+
return v1.toNumber() > v2.toNumber();
107+
}
108+
109+
friend inline bool operator<(const Value &v1, const Value &v2)
110+
{
111+
if (v1.isInfinity()) {
112+
return false;
113+
} else if (v1.isNegativeInfinity())
114+
return !v2.isNegativeInfinity();
115+
else if (v2.isInfinity())
116+
return !v1.isInfinity();
117+
else if (v2.isNegativeInfinity())
118+
return false;
119+
return v1.toNumber() < v2.toNumber();
120+
}
121+
122+
friend inline bool operator>=(const Value &v1, const Value &v2) { return v1 > v2 || v1 == v2; }
123+
124+
friend inline bool operator<=(const Value &v1, const Value &v2) { return v1 < v2 || v1 == v2; }
125+
126+
friend inline Value operator+(const Value &v1, const Value &v2)
127+
{
128+
if ((v1.isInfinity() && v2.isNegativeInfinity()) || (v1.isNegativeInfinity() && v2.isInfinity()))
129+
return Value(SpecialValue::NaN);
130+
else if (v1.isInfinity() || v2.isInfinity())
131+
return Value(SpecialValue::Infinity);
132+
else if (v1.isNegativeInfinity() || v2.isNegativeInfinity())
133+
return Value(SpecialValue::NegativeInfinity);
134+
return v1.toNumber() + v2.toNumber();
135+
}
136+
137+
friend inline Value operator-(const Value &v1, const Value &v2)
138+
{
139+
if ((v1.isInfinity() && v2.isInfinity()) || (v1.isNegativeInfinity() && v2.isNegativeInfinity()))
140+
return Value(SpecialValue::NaN);
141+
else if (v1.isInfinity() || v2.isNegativeInfinity())
142+
return Value(SpecialValue::Infinity);
143+
else if (v1.isNegativeInfinity() || v2.isInfinity())
144+
return Value(SpecialValue::NegativeInfinity);
145+
return v1.toNumber() - v2.toNumber();
146+
}
147+
148+
friend inline Value operator*(const Value &v1, const Value &v2)
149+
{
150+
if (v1.isInfinity() || v1.isNegativeInfinity() || v2.isInfinity() || v2.isNegativeInfinity()) {
151+
bool mode = (v1.isInfinity() || v2.isInfinity());
152+
const Value &value = (v1.isInfinity() || v1.isNegativeInfinity()) ? v2 : v1;
153+
if (value > 0)
154+
return Value(mode ? SpecialValue::Infinity : SpecialValue::NegativeInfinity);
155+
else if (value < 0)
156+
return Value(mode ? SpecialValue::NegativeInfinity : SpecialValue::Infinity);
157+
else
158+
return Value(SpecialValue::NaN);
159+
}
160+
return v1.toNumber() * v2.toNumber();
161+
}
162+
163+
friend inline Value operator/(const Value &v1, const Value &v2)
164+
{
165+
166+
if ((v1 == 0) && (v2 == 0))
167+
return Value(SpecialValue::NaN);
168+
else if (v2 == 0) {
169+
if (v2.isInfinity() || v2.isNegativeInfinity()) {
170+
if (v1.isInfinity() || v1.isNegativeInfinity())
171+
return Value(SpecialValue::NaN);
172+
else
173+
return 0;
174+
} else
175+
return Value(v1 > 0 ? SpecialValue::Infinity : SpecialValue::NegativeInfinity);
176+
}
177+
return v1.toNumber() / v2.toNumber();
178+
}
179+
180+
friend inline Value operator%(const Value &v1, const Value &v2)
181+
{
182+
183+
if ((v2 == 0) || (v1.isInfinity() || v1.isNegativeInfinity()))
184+
return Value(SpecialValue::NaN);
185+
else if (v2.isInfinity() || v2.isNegativeInfinity()) {
186+
return v1.toNumber();
187+
}
188+
return static_cast<int>(v1.toNumber()) % static_cast<int>(v2.toNumber());
90189
}
91190
};
92191

0 commit comments

Comments
 (0)