AbstractRelationalComparison.js 1.6 KB

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