Skip to content

Commit 3ac5779

Browse files
committed
Remove Infinity, -Infinity and NaN types
1 parent 27fa1cb commit 3ac5779

File tree

14 files changed

+158
-331
lines changed

14 files changed

+158
-331
lines changed

include/scratchcpp/value.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,6 @@ class LIBSCRATCHCPP_EXPORT Value
5757
value_assign_cstring(&m_data, stringValue);
5858
}
5959

60-
/*! Constructs a special Value. */
61-
Value(SpecialValue specialValue)
62-
{
63-
value_init(&m_data);
64-
value_assign_special(&m_data, specialValue);
65-
}
66-
6760
/*! Constructs value from ValueData. */
6861
Value(const ValueData &v)
6962
{

include/scratchcpp/value_functions.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ extern "C"
1515
LIBSCRATCHCPP_EXPORT void value_assign_bool(ValueData *v, bool boolValue);
1616
LIBSCRATCHCPP_EXPORT void value_assign_string(ValueData *v, const std::string &stringValue);
1717
LIBSCRATCHCPP_EXPORT void value_assign_cstring(ValueData *v, const char *stringValue);
18-
LIBSCRATCHCPP_EXPORT void value_assign_special(ValueData *v, SpecialValue specialValue);
1918
LIBSCRATCHCPP_EXPORT void value_assign_copy(ValueData *v, const ValueData *another);
2019

2120
LIBSCRATCHCPP_EXPORT bool value_isInfinity(const ValueData *v);

include/scratchcpp/valuedata.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,11 @@
99
namespace libscratchcpp
1010
{
1111

12-
enum class LIBSCRATCHCPP_EXPORT SpecialValue
13-
{
14-
Infinity,
15-
NegativeInfinity,
16-
NaN
17-
};
18-
1912
enum class LIBSCRATCHCPP_EXPORT ValueType
2013
{
2114
Number = 0,
2215
Bool = 1,
23-
String = 2,
24-
Infinity = -1,
25-
NegativeInfinity = -2,
26-
NaN = -3
16+
String = 2
2717
};
2818

2919
extern "C"

src/blocks/operatorblocks.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,9 @@ unsigned int OperatorBlocks::op_ln(VirtualMachine *vm)
261261
{
262262
const Value &v = *vm->getInput(0, 1);
263263
if (v < 0)
264-
vm->replaceReturnValue(Value(SpecialValue::NaN), 1);
264+
vm->replaceReturnValue(std::numeric_limits<double>::quiet_NaN(), 1);
265265
else if (v == 0 || v.isNaN())
266-
vm->replaceReturnValue(Value(SpecialValue::NegativeInfinity), 1);
266+
vm->replaceReturnValue(-std::numeric_limits<double>::infinity(), 1);
267267
else if (!v.isInfinity())
268268
vm->replaceReturnValue(std::log(v.toDouble()), 1);
269269
return 0;
@@ -273,9 +273,9 @@ unsigned int OperatorBlocks::op_log(VirtualMachine *vm)
273273
{
274274
const Value &v = *vm->getInput(0, 1);
275275
if (v < 0)
276-
vm->replaceReturnValue(Value(SpecialValue::NaN), 1);
276+
vm->replaceReturnValue(std::numeric_limits<double>::quiet_NaN(), 1);
277277
else if (v == 0 || v.isNaN())
278-
vm->replaceReturnValue(Value(SpecialValue::NegativeInfinity), 1);
278+
vm->replaceReturnValue(-std::numeric_limits<double>::infinity(), 1);
279279
else if (!v.isInfinity())
280280
vm->replaceReturnValue(std::log10(v.toDouble()), 1);
281281
return 0;
@@ -284,7 +284,9 @@ unsigned int OperatorBlocks::op_log(VirtualMachine *vm)
284284
unsigned int OperatorBlocks::op_eexp(VirtualMachine *vm)
285285
{
286286
const Value *v = vm->getInput(0, 1);
287-
if (v->isNegativeInfinity())
287+
if (v->isNaN())
288+
vm->replaceReturnValue(1, 1);
289+
else if (v->isNegativeInfinity())
288290
vm->replaceReturnValue(0, 1);
289291
else if (!v->isInfinity())
290292
vm->replaceReturnValue(std::exp(v->toDouble()), 1);
@@ -294,7 +296,9 @@ unsigned int OperatorBlocks::op_eexp(VirtualMachine *vm)
294296
unsigned int OperatorBlocks::op_10exp(VirtualMachine *vm)
295297
{
296298
const Value *v = vm->getInput(0, 1);
297-
if (v->isNegativeInfinity())
299+
if (v->isNaN())
300+
vm->replaceReturnValue(1, 1);
301+
else if (v->isNegativeInfinity())
298302
vm->replaceReturnValue(0, 1);
299303
else if (!v->isInfinity())
300304
vm->replaceReturnValue(std::pow(10, v->toDouble()), 1);

src/dev/engine/internal/llvmcodebuilder.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@
1010

1111
using namespace libscratchcpp;
1212

13-
static std::unordered_map<ValueType, Compiler::StaticType> TYPE_MAP = {
14-
{ ValueType::Number, Compiler::StaticType::Number }, { ValueType::Bool, Compiler::StaticType::Bool },
15-
{ ValueType::String, Compiler::StaticType::String }, { ValueType::Infinity, Compiler::StaticType::Number },
16-
{ ValueType::NegativeInfinity, Compiler::StaticType::Number }, { ValueType::NaN, Compiler::StaticType::Number }
17-
};
13+
static std::unordered_map<ValueType, Compiler::StaticType>
14+
TYPE_MAP = { { ValueType::Number, Compiler::StaticType::Number }, { ValueType::Bool, Compiler::StaticType::Bool }, { ValueType::String, Compiler::StaticType::String } };
1815

1916
LLVMCodeBuilder::LLVMCodeBuilder(const std::string &id, bool warp) :
2017
m_id(id),

src/engine/virtualmachine_p.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
461461
{
462462
const Value *v = READ_REG(0, 1);
463463
if (v->isNegativeInfinity())
464-
REPLACE_RET_VALUE(Value(SpecialValue::Infinity), 1);
464+
REPLACE_RET_VALUE(std::numeric_limits<double>::infinity(), 1);
465465
else if (!v->isInfinity())
466466
REPLACE_RET_VALUE(std::abs(v->toDouble()), 1);
467467
DISPATCH();
@@ -487,7 +487,7 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
487487
{
488488
const Value &v = *READ_REG(0, 1);
489489
if (v < 0)
490-
REPLACE_RET_VALUE(Value(SpecialValue::NaN), 1);
490+
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
491491
else if (!v.isInfinity())
492492
REPLACE_RET_VALUE(std::sqrt(v.toDouble()), 1);
493493
DISPATCH();
@@ -497,7 +497,7 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
497497
{
498498
const Value *v = READ_REG(0, 1);
499499
if (v->isInfinity() || v->isNegativeInfinity())
500-
REPLACE_RET_VALUE(Value(SpecialValue::NaN), 1);
500+
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
501501
else
502502
REPLACE_RET_VALUE(std::sin(v->toDouble() * pi / 180), 1);
503503
DISPATCH();
@@ -507,7 +507,7 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
507507
{
508508
const Value *v = READ_REG(0, 1);
509509
if (v->isInfinity() || v->isNegativeInfinity())
510-
REPLACE_RET_VALUE(Value(SpecialValue::NaN), 1);
510+
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
511511
else
512512
REPLACE_RET_VALUE(std::cos(v->toDouble() * pi / 180), 1);
513513
DISPATCH();
@@ -517,17 +517,17 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
517517
{
518518
const Value *v = READ_REG(0, 1);
519519
if (v->isInfinity() || v->isNegativeInfinity())
520-
REPLACE_RET_VALUE(Value(SpecialValue::NaN), 1);
520+
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
521521
else {
522522
long mod;
523523
if (v->toLong() < 0)
524524
mod = (v->toLong() + 360) % 360;
525525
else
526526
mod = v->toLong() % 360;
527527
if (mod == 90)
528-
REPLACE_RET_VALUE(Value(SpecialValue::Infinity), 1);
528+
REPLACE_RET_VALUE(std::numeric_limits<double>::infinity(), 1);
529529
else if (mod == 270)
530-
REPLACE_RET_VALUE(Value(SpecialValue::NegativeInfinity), 1);
530+
REPLACE_RET_VALUE(-std::numeric_limits<double>::infinity(), 1);
531531
else
532532
REPLACE_RET_VALUE(std::tan(v->toDouble() * pi / 180), 1);
533533
}
@@ -538,7 +538,7 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
538538
{
539539
const Value &v = *READ_REG(0, 1);
540540
if (v < -1 || v > 1)
541-
REPLACE_RET_VALUE(Value(SpecialValue::NaN), 1);
541+
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
542542
else
543543
REPLACE_RET_VALUE(std::asin(v.toDouble()) * 180 / pi, 1);
544544
DISPATCH();
@@ -548,7 +548,7 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
548548
{
549549
const Value &v = *READ_REG(0, 1);
550550
if (v < -1 || v > 1)
551-
REPLACE_RET_VALUE(Value(SpecialValue::NaN), 1);
551+
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
552552
else
553553
REPLACE_RET_VALUE(std::acos(v.toDouble()) * 180 / pi, 1);
554554
DISPATCH();

src/scratch/inputvalue.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,8 @@
1717

1818
using namespace libscratchcpp;
1919

20-
static const std::map<ValueType, InputValue::Type> VALUE_TYPE_MAP = {
21-
{ ValueType::Number, InputValue::Type::Number }, { ValueType::Bool, InputValue::Type::String },
22-
{ ValueType::String, InputValue::Type::String }, { ValueType::Infinity, InputValue::Type::String },
23-
{ ValueType::NegativeInfinity, InputValue::Type::String }, { ValueType::NaN, InputValue::Type::String }
24-
};
20+
static const std::map<ValueType, InputValue::Type>
21+
VALUE_TYPE_MAP = { { ValueType::Number, InputValue::Type::Number }, { ValueType::Bool, InputValue::Type::String }, { ValueType::String, InputValue::Type::String } };
2522

2623
/*! Constructs InputValue with the given type. */
2724
InputValue::InputValue(Type type) :

src/scratch/value_functions.cpp

Lines changed: 14 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,6 @@ extern "C"
6868
}
6969
}
7070

71-
/*! Assigns special value to the given value. */
72-
void value_assign_special(ValueData *v, SpecialValue specialValue)
73-
{
74-
value_free(v);
75-
76-
if (specialValue == SpecialValue::Infinity)
77-
v->type = ValueType::Infinity;
78-
else if (specialValue == SpecialValue::NegativeInfinity)
79-
v->type = ValueType::NegativeInfinity;
80-
else if (specialValue == SpecialValue::NaN)
81-
v->type = ValueType::NaN;
82-
else {
83-
v->type = ValueType::Number;
84-
v->numberValue = 0;
85-
}
86-
}
87-
8871
/*! Assigns another value to the given value. */
8972
void value_assign_copy(ValueData *v, const libscratchcpp::ValueData *another)
9073
{
@@ -112,8 +95,6 @@ extern "C"
11295
bool value_isInfinity(const libscratchcpp::ValueData *v)
11396
{
11497
switch (v->type) {
115-
case ValueType::Infinity:
116-
return true;
11798
case ValueType::Number:
11899
return value_isInf(v->numberValue);
119100
case ValueType::String:
@@ -127,8 +108,6 @@ extern "C"
127108
bool value_isNegativeInfinity(const libscratchcpp::ValueData *v)
128109
{
129110
switch (v->type) {
130-
case ValueType::NegativeInfinity:
131-
return true;
132111
case ValueType::Number:
133112
return value_isNegativeInf(v->numberValue);
134113
case ValueType::String:
@@ -142,8 +121,6 @@ extern "C"
142121
bool value_isNaN(const libscratchcpp::ValueData *v)
143122
{
144123
switch (v->type) {
145-
case ValueType::NaN:
146-
return true;
147124
case ValueType::Number:
148125
return std::isnan(v->numberValue);
149126
case ValueType::String:
@@ -168,8 +145,6 @@ extern "C"
168145
if (value_isInfinity(v) || value_isNegativeInfinity(v))
169146
return true;
170147

171-
assert(v->type != ValueType::Infinity && v->type != ValueType::NegativeInfinity);
172-
173148
switch (v->type) {
174149
case ValueType::Number:
175150
case ValueType::Bool:
@@ -187,11 +162,12 @@ extern "C"
187162
// https://github.com/scratchfoundation/scratch-vm/blob/112989da0e7306eeb405a5c52616e41c2164af24/src/util/cast.js#L157-L181
188163
switch (v->type) {
189164
case ValueType::Bool:
190-
case ValueType::Infinity:
191-
case ValueType::NegativeInfinity:
192-
case ValueType::NaN:
193165
return true;
166+
194167
case ValueType::Number: {
168+
if (std::isinf(v->numberValue) || std::isnan(v->numberValue))
169+
return true;
170+
195171
double intpart;
196172
std::modf(v->numberValue, &intpart);
197173
return v->numberValue == intpart;
@@ -220,9 +196,9 @@ extern "C"
220196
/*! Returns the long representation of the given value. */
221197
long value_toLong(const libscratchcpp::ValueData *v)
222198
{
223-
if (v->type == ValueType::Number)
199+
if (v->type == ValueType::Number) {
224200
return v->numberValue;
225-
else if (v->type == ValueType::Bool)
201+
} else if (v->type == ValueType::Bool)
226202
return v->boolValue;
227203
else if (v->type == ValueType::String)
228204
return value_stringToLong(v->stringValue);
@@ -252,10 +228,6 @@ extern "C"
252228
return v->boolValue;
253229
else if (v->type == ValueType::String)
254230
return value_stringToDouble(v->stringValue);
255-
else if (v->type == ValueType::Infinity)
256-
return std::numeric_limits<double>::infinity();
257-
else if (v->type == ValueType::NegativeInfinity)
258-
return -std::numeric_limits<double>::infinity();
259231
else
260232
return 0;
261233
}
@@ -269,10 +241,6 @@ extern "C"
269241
return v->numberValue != 0;
270242
} else if (v->type == ValueType::String) {
271243
return value_stringToBool(v->stringValue);
272-
} else if (v->type == ValueType::Infinity || v->type == ValueType::NegativeInfinity) {
273-
return true;
274-
} else if (v->type == ValueType::NaN) {
275-
return false;
276244
} else {
277245
return false;
278246
}
@@ -287,12 +255,6 @@ extern "C"
287255
value_doubleToString(v->numberValue, dst);
288256
else if (v->type == ValueType::Bool)
289257
dst->assign(v->boolValue ? "true" : "false");
290-
else if (v->type == ValueType::Infinity)
291-
dst->assign("Infinity");
292-
else if (v->type == ValueType::NegativeInfinity)
293-
dst->assign("-Infinity");
294-
else if (v->type == ValueType::NaN)
295-
dst->assign("NaN");
296258
else
297259
dst->clear();
298260
}
@@ -396,7 +358,7 @@ extern "C"
396358
double b = value_toDouble(v2);
397359

398360
if ((b == 0) || std::isinf(a))
399-
value_assign_special(dst, SpecialValue::NaN);
361+
value_assign_double(dst, std::numeric_limits<double>::quiet_NaN());
400362
else if (std::isinf(b))
401363
value_assign_double(dst, value_toDouble(v1));
402364
else if (value_isNegative(v1) || value_isNegative(v2))
@@ -413,9 +375,12 @@ extern "C"
413375
// https://github.com/scratchfoundation/scratch-vm/blob/112989da0e7306eeb405a5c52616e41c2164af24/src/util/cast.js#L121-L150
414376
assert(v1 && v2);
415377

416-
if (v1->type == ValueType::Number && v2->type == ValueType::Number)
378+
if (v1->type == ValueType::Number && v2->type == ValueType::Number) {
379+
if (std::isnan(v1->numberValue) && std::isnan(v2->numberValue))
380+
return true;
381+
417382
return v1->numberValue == v2->numberValue;
418-
else if (v1->type == ValueType::Bool && v2->type == ValueType::Bool)
383+
} else if (v1->type == ValueType::Bool && v2->type == ValueType::Bool)
419384
return v1->boolValue == v2->boolValue;
420385

421386
bool ok;
@@ -436,8 +401,8 @@ extern "C"
436401

437402
// Handle the special case of Infinity
438403
if ((static_cast<int>(v1->type) < 0) && (static_cast<int>(v2->type) < 0)) {
439-
assert(v1->type != ValueType::NaN);
440-
assert(v2->type != ValueType::NaN);
404+
assert(!value_isNaN(v1));
405+
assert(!value_isNaN(v2));
441406
return v1->type == v2->type;
442407
}
443408

0 commit comments

Comments
 (0)