IsLessThan.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $Number = GetIntrinsic('%Number%');
  4. var $TypeError = GetIntrinsic('%TypeError%');
  5. var min = GetIntrinsic('%Math.min%');
  6. var $isNaN = require('../helpers/isNaN');
  7. var $charCodeAt = require('call-bind/callBound')('String.prototype.charCodeAt');
  8. var StringToBigInt = require('./StringToBigInt');
  9. var ToNumeric = require('./ToNumeric');
  10. var ToPrimitive = require('./ToPrimitive');
  11. var Type = require('./Type');
  12. var BigIntLessThan = require('./BigInt/lessThan');
  13. var NumberLessThan = require('./Number/lessThan');
  14. // https://262.ecma-international.org/14.0/#sec-islessthan
  15. // eslint-disable-next-line max-statements, max-lines-per-function
  16. module.exports = function IsLessThan(x, y, LeftFirst) {
  17. if (Type(LeftFirst) !== 'Boolean') {
  18. throw new $TypeError('Assertion failed: LeftFirst argument must be a Boolean');
  19. }
  20. var px;
  21. var py;
  22. if (LeftFirst) {
  23. px = ToPrimitive(x, $Number);
  24. py = ToPrimitive(y, $Number);
  25. } else {
  26. py = ToPrimitive(y, $Number);
  27. px = ToPrimitive(x, $Number);
  28. }
  29. var pxType = Type(px);
  30. var pyType = Type(py);
  31. if (pxType === 'String' && pyType === 'String') { // step 3
  32. // a. Let lx be the length of px.
  33. // b. Let ly be the length of py.
  34. // c. For each integer i starting with 0 such that i < min(lx, ly), in ascending order, do
  35. // i. Let cx be the integer that is the numeric value of the code unit at index i within px.
  36. // ii. Let cy be the integer that is the numeric value of the code unit at index i within py.
  37. // iii. If cx < cy, return true.
  38. // iv. If cx > cy, return false.
  39. // d. If lx < ly, return true. Otherwise, return false.
  40. var lx = px.length; // step 3.a
  41. var ly = py.length; // step 3.b
  42. for (var i = 0; i < min(lx, ly); i++) { // step 3.c
  43. var cx = $charCodeAt(px, i); // step 3.c.i
  44. var cy = $charCodeAt(py, i); // step 3.c.ii
  45. if (cx < cy) {
  46. return true; // step 3.c.iii
  47. }
  48. if (cx > cy) {
  49. return false; // step 3.c.iv
  50. }
  51. }
  52. return lx < ly; // step 3.d
  53. }
  54. var nx;
  55. var ny;
  56. if (pxType === 'BigInt' && pyType === 'String') {
  57. ny = StringToBigInt(py);
  58. if (typeof ny === 'undefined') {
  59. return void undefined;
  60. }
  61. return BigIntLessThan(px, ny);
  62. }
  63. if (pxType === 'String' && pyType === 'BigInt') {
  64. nx = StringToBigInt(px);
  65. if (typeof nx === 'undefined') {
  66. return void undefined;
  67. }
  68. return BigIntLessThan(nx, py);
  69. }
  70. nx = ToNumeric(px);
  71. ny = ToNumeric(py);
  72. var nxType = Type(nx);
  73. if (nxType === Type(ny)) {
  74. return nxType === 'Number' ? NumberLessThan(nx, ny) : BigIntLessThan(nx, ny);
  75. }
  76. if ($isNaN(nx) || $isNaN(ny)) {
  77. return void undefined;
  78. }
  79. if (nx === -Infinity || ny === Infinity) {
  80. return true;
  81. }
  82. if (nx === Infinity || ny === -Infinity) {
  83. return false;
  84. }
  85. return nx < ny; // by now, these are both finite, and the same type
  86. };