Skip to content

Commit c847df4

Browse files
committed
Fix GT and LT value comparison to match Scratch
1 parent 29859b5 commit c847df4

File tree

4 files changed

+140
-82
lines changed

4 files changed

+140
-82
lines changed

src/engine/virtualmachine_p.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -537,20 +537,22 @@ unsigned int *VirtualMachinePrivate::run(unsigned int *pos, bool reset)
537537
OP(ASIN) :
538538
{
539539
const Value &v = *READ_REG(0, 1);
540-
if (v < -1 || v > 1)
540+
const double num = v.toDouble();
541+
if (num < -1 || num > 1)
541542
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
542543
else
543-
REPLACE_RET_VALUE(std::asin(v.toDouble()) * 180 / pi, 1);
544+
REPLACE_RET_VALUE(std::asin(num) * 180 / pi, 1);
544545
DISPATCH();
545546
}
546547

547548
OP(ACOS) :
548549
{
549550
const Value &v = *READ_REG(0, 1);
550-
if (v < -1 || v > 1)
551+
const double num = v.toDouble();
552+
if (num < -1 || num > 1)
551553
REPLACE_RET_VALUE(std::numeric_limits<double>::quiet_NaN(), 1);
552554
else
553-
REPLACE_RET_VALUE(std::acos(v.toDouble()) * 180 / pi, 1);
555+
REPLACE_RET_VALUE(std::acos(num) * 180 / pi, 1);
554556
DISPATCH();
555557
}
556558

src/scratch/value_functions.cpp

Lines changed: 3 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -372,93 +372,19 @@ extern "C"
372372
/*! Returns true if the given values are equal. */
373373
bool value_equals(const libscratchcpp::ValueData *v1, const libscratchcpp::ValueData *v2)
374374
{
375-
// https://github.com/scratchfoundation/scratch-vm/blob/112989da0e7306eeb405a5c52616e41c2164af24/src/util/cast.js#L121-L150
376-
assert(v1 && v2);
377-
378-
if (v1->type == ValueType::Number && v2->type == ValueType::Number) {
379-
if (std::isnan(v1->numberValue) && std::isnan(v2->numberValue))
380-
return true;
381-
382-
return v1->numberValue == v2->numberValue;
383-
} else if (v1->type == ValueType::Bool && v2->type == ValueType::Bool)
384-
return v1->boolValue == v2->boolValue;
385-
386-
bool ok;
387-
double n1 = value_getNumber(v1, &ok);
388-
double n2;
389-
390-
if (ok)
391-
n2 = value_getNumber(v2, &ok);
392-
393-
if (!ok) {
394-
// At least one argument can't be converted to a number
395-
// Scratch compares strings as case insensitive
396-
std::u16string s1, s2;
397-
value_toUtf16(v1, &s1);
398-
value_toUtf16(v2, &s2);
399-
return value_u16StringsEqual(s1, s2);
400-
}
401-
402-
// Handle the special case of Infinity
403-
if ((static_cast<int>(v1->type) < 0) && (static_cast<int>(v2->type) < 0)) {
404-
assert(!value_isNaN(v1));
405-
assert(!value_isNaN(v2));
406-
return v1->type == v2->type;
407-
}
408-
409-
// Compare as numbers
410-
return n1 == n2;
375+
return value_compare(v1, v2) == 0;
411376
}
412377

413378
/*! Returns true if the first value is greater than the second value. */
414379
bool value_greater(const libscratchcpp::ValueData *v1, const libscratchcpp::ValueData *v2)
415380
{
416-
assert(v1 && v2);
417-
418-
if (v1->type == ValueType::Number && v2->type == ValueType::Number)
419-
return v1->numberValue > v2->numberValue;
420-
else if (v1->type == ValueType::Bool && v2->type == ValueType::Bool)
421-
return v1->boolValue > v2->boolValue;
422-
423-
double n1, n2;
424-
425-
if (v1->type == ValueType::String)
426-
n1 = value_stringToDouble(v1->stringValue);
427-
else
428-
n1 = value_toDouble(v1);
429-
430-
if (v2->type == ValueType::String)
431-
n2 = value_stringToDouble(v2->stringValue);
432-
else
433-
n2 = value_toDouble(v2);
434-
435-
return n1 > n2;
381+
return value_compare(v1, v2) > 0;
436382
}
437383

438384
/*! Returns true if the first value is lower than the second value. */
439385
bool value_lower(const libscratchcpp::ValueData *v1, const libscratchcpp::ValueData *v2)
440386
{
441-
assert(v1 && v2);
442-
443-
if (v1->type == ValueType::Number && v2->type == ValueType::Number)
444-
return v1->numberValue < v2->numberValue;
445-
else if (v1->type == ValueType::Bool && v2->type == ValueType::Bool)
446-
return v1->boolValue < v2->boolValue;
447-
448-
return value_toDouble(v1) < value_toDouble(v2);
449-
double n1, n2;
450-
451-
if (v1->type == ValueType::String)
452-
n1 = value_stringToDouble(v1->stringValue);
453-
else
454-
n1 = value_toDouble(v1);
455-
456-
if (v2->type == ValueType::String)
457-
n2 = value_stringToDouble(v2->stringValue);
458-
else
459-
n2 = value_toDouble(v2);
460-
461-
return n1 < n2;
387+
return value_compare(v1, v2) < 0;
462388
}
463389
}
464390

src/scratch/value_functions_p.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,46 @@ extern "C"
539539
else
540540
return false;
541541
}
542+
543+
inline double value_compare(const ValueData *v1, const ValueData *v2)
544+
{
545+
// https://github.com/scratchfoundation/scratch-vm/blob/112989da0e7306eeb405a5c52616e41c2164af24/src/util/cast.js#L121-L150
546+
assert(v1 && v2);
547+
548+
if (v1->type == ValueType::Number && v2->type == ValueType::Number && !std::isnan(v1->numberValue) && !std::isnan(v2->numberValue)) {
549+
// Handle the special case of Infinity
550+
if ((value_isInf(v1->numberValue) && value_isInf(v2->numberValue)) || (value_isNegativeInf(v1->numberValue) && value_isNegativeInf(v2->numberValue)))
551+
return 0;
552+
553+
return v1->numberValue - v2->numberValue;
554+
} else if (v1->type == ValueType::Bool && v2->type == ValueType::Bool)
555+
return v1->boolValue - v2->boolValue;
556+
557+
bool ok;
558+
double n1 = value_getNumber(v1, &ok);
559+
double n2;
560+
561+
if (ok)
562+
n2 = value_getNumber(v2, &ok);
563+
564+
if (!ok) {
565+
// At least one argument can't be converted to a number
566+
// Scratch compares strings as case insensitive
567+
char *s1 = value_toCString(v1);
568+
char *s2 = value_toCString(v2);
569+
int ret = strcasecmp(s1, s2);
570+
free(s1);
571+
free(s2);
572+
return ret;
573+
}
574+
575+
// Handle the special case of Infinity
576+
if ((value_isInf(n1) && value_isInf(n2)) || (value_isNegativeInf(n1) && value_isNegativeInf(n2)))
577+
return 0;
578+
579+
// Compare as numbers
580+
return n1 - n2;
581+
}
542582
}
543583

544584
} // namespace libscratchcpp

0 commit comments

Comments
 (0)