IsLessThan.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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 IsStringPrefix = require('./IsStringPrefix');
  7. var StringToBigInt = require('./StringToBigInt');
  8. var ToNumeric = require('./ToNumeric');
  9. var ToPrimitive = require('./ToPrimitive');
  10. var Type = require('./Type');
  11. var BigIntLessThan = require('./BigInt/lessThan');
  12. var NumberLessThan = require('./Number/lessThan');
  13. // https://262.ecma-international.org/13.0/#sec-islessthan
  14. // eslint-disable-next-line max-statements, max-lines-per-function
  15. module.exports = function IsLessThan(x, y, LeftFirst) {
  16. if (Type(LeftFirst) !== 'Boolean') {
  17. throw new $TypeError('Assertion failed: LeftFirst argument must be a Boolean');
  18. }
  19. var px;
  20. var py;
  21. if (LeftFirst) {
  22. px = ToPrimitive(x, $Number);
  23. py = ToPrimitive(y, $Number);
  24. } else {
  25. py = ToPrimitive(y, $Number);
  26. px = ToPrimitive(x, $Number);
  27. }
  28. var pxType = Type(px);
  29. var pyType = Type(py);
  30. if (pxType === 'String' && pyType === 'String') {
  31. if (IsStringPrefix(py, px)) {
  32. return false;
  33. }
  34. if (IsStringPrefix(px, py)) {
  35. return true;
  36. }
  37. /*
  38. c. Let k be the smallest non-negative integer such that the code unit at index k within px is different from the code unit at index k within py. (There must be such a k, for neither String is a prefix of the other.)
  39. d. Let m be the integer that is the numeric value of the code unit at index k within px.
  40. e. Let n be the integer that is the numeric value of the code unit at index k within py.
  41. f. If m < n, return true. Otherwise, return false.
  42. */
  43. return px < py; // both strings, neither a prefix of the other. shortcut for steps 3 c-f
  44. }
  45. var nx;
  46. var ny;
  47. if (pxType === 'BigInt' && pyType === 'String') {
  48. ny = StringToBigInt(py);
  49. if ($isNaN(ny)) {
  50. return void undefined;
  51. }
  52. return BigIntLessThan(px, ny);
  53. }
  54. if (pxType === 'String' && pyType === 'BigInt') {
  55. nx = StringToBigInt(px);
  56. if ($isNaN(nx)) {
  57. return void undefined;
  58. }
  59. return BigIntLessThan(nx, py);
  60. }
  61. nx = ToNumeric(px);
  62. ny = ToNumeric(py);
  63. var nxType = Type(nx);
  64. if (nxType === Type(ny)) {
  65. return nxType === 'Number' ? NumberLessThan(nx, ny) : BigIntLessThan(nx, ny);
  66. }
  67. if ($isNaN(nx) || $isNaN(ny)) {
  68. return void undefined;
  69. }
  70. if (nx === -Infinity || ny === Infinity) {
  71. return true;
  72. }
  73. if (nx === Infinity || ny === -Infinity) {
  74. return false;
  75. }
  76. return nx < ny; // by now, these are both nonzero, finite, and not equal
  77. };