blob: 0dfed5ffe1c63530db2b93ae8dd4e43acabcecd2 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2
3var GetIntrinsic = require('get-intrinsic');
4
5var $Number = GetIntrinsic('%Number%');
6var $TypeError = GetIntrinsic('%TypeError%');
7
8var $isNaN = require('../helpers/isNaN');
9var $isFinite = require('../helpers/isFinite');
10var isPrefixOf = require('../helpers/isPrefixOf');
11
12var ToNumber = require('./ToNumber');
13var ToPrimitive = require('./ToPrimitive');
14var Type = require('./Type');
15
16// https://262.ecma-international.org/5.1/#sec-11.8.5
17
18// eslint-disable-next-line max-statements
19module.exports = function AbstractRelationalComparison(x, y, LeftFirst) {
20 if (Type(LeftFirst) !== 'Boolean') {
21 throw new $TypeError('Assertion failed: LeftFirst argument must be a Boolean');
22 }
23 var px;
24 var py;
25 if (LeftFirst) {
26 px = ToPrimitive(x, $Number);
27 py = ToPrimitive(y, $Number);
28 } else {
29 py = ToPrimitive(y, $Number);
30 px = ToPrimitive(x, $Number);
31 }
32 var bothStrings = Type(px) === 'String' && Type(py) === 'String';
33 if (!bothStrings) {
34 var nx = ToNumber(px);
35 var ny = ToNumber(py);
36 if ($isNaN(nx) || $isNaN(ny)) {
37 return undefined;
38 }
39 if ($isFinite(nx) && $isFinite(ny) && nx === ny) {
40 return false;
41 }
42 if (nx === Infinity) {
43 return false;
44 }
45 if (ny === Infinity) {
46 return true;
47 }
48 if (ny === -Infinity) {
49 return false;
50 }
51 if (nx === -Infinity) {
52 return true;
53 }
54 return nx < ny; // by now, these are both nonzero, finite, and not equal
55 }
56 if (isPrefixOf(py, px)) {
57 return false;
58 }
59 if (isPrefixOf(px, py)) {
60 return true;
61 }
62 return px < py; // both strings, neither a prefix of the other. shortcut for steps c-f
63};