ApplyStringOrNumericBinaryOperator.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $TypeError = GetIntrinsic('%TypeError%');
  4. var HasOwnProperty = require('./HasOwnProperty');
  5. var ToNumeric = require('./ToNumeric');
  6. var ToPrimitive = require('./ToPrimitive');
  7. var ToString = require('./ToString');
  8. var Type = require('./Type');
  9. var NumberAdd = require('./Number/add');
  10. var NumberBitwiseAND = require('./Number/bitwiseAND');
  11. var NumberBitwiseOR = require('./Number/bitwiseOR');
  12. var NumberBitwiseXOR = require('./Number/bitwiseXOR');
  13. var NumberDivide = require('./Number/divide');
  14. var NumberExponentiate = require('./Number/exponentiate');
  15. var NumberLeftShift = require('./Number/leftShift');
  16. var NumberMultiply = require('./Number/multiply');
  17. var NumberRemainder = require('./Number/remainder');
  18. var NumberSignedRightShift = require('./Number/signedRightShift');
  19. var NumberSubtract = require('./Number/subtract');
  20. var NumberUnsignedRightShift = require('./Number/unsignedRightShift');
  21. var BigIntAdd = require('./BigInt/add');
  22. var BigIntBitwiseAND = require('./BigInt/bitwiseAND');
  23. var BigIntBitwiseOR = require('./BigInt/bitwiseOR');
  24. var BigIntBitwiseXOR = require('./BigInt/bitwiseXOR');
  25. var BigIntDivide = require('./BigInt/divide');
  26. var BigIntExponentiate = require('./BigInt/exponentiate');
  27. var BigIntLeftShift = require('./BigInt/leftShift');
  28. var BigIntMultiply = require('./BigInt/multiply');
  29. var BigIntRemainder = require('./BigInt/remainder');
  30. var BigIntSignedRightShift = require('./BigInt/signedRightShift');
  31. var BigIntSubtract = require('./BigInt/subtract');
  32. var BigIntUnsignedRightShift = require('./BigInt/unsignedRightShift');
  33. // https://262.ecma-international.org/12.0/#sec-applystringornumericbinaryoperator
  34. // https://262.ecma-international.org/12.0/#step-applystringornumericbinaryoperator-operations-table
  35. var table = {
  36. '**': [NumberExponentiate, BigIntExponentiate],
  37. '*': [NumberMultiply, BigIntMultiply],
  38. '/': [NumberDivide, BigIntDivide],
  39. '%': [NumberRemainder, BigIntRemainder],
  40. '+': [NumberAdd, BigIntAdd],
  41. '-': [NumberSubtract, BigIntSubtract],
  42. '<<': [NumberLeftShift, BigIntLeftShift],
  43. '>>': [NumberSignedRightShift, BigIntSignedRightShift],
  44. '>>>': [NumberUnsignedRightShift, BigIntUnsignedRightShift],
  45. '&': [NumberBitwiseAND, BigIntBitwiseAND],
  46. '^': [NumberBitwiseXOR, BigIntBitwiseXOR],
  47. '|': [NumberBitwiseOR, BigIntBitwiseOR]
  48. };
  49. module.exports = function ApplyStringOrNumericBinaryOperator(lval, opText, rval) {
  50. if (Type(opText) !== 'String' || !HasOwnProperty(table, opText)) {
  51. throw new $TypeError('Assertion failed: `opText` must be a valid operation string');
  52. }
  53. if (opText === '+') {
  54. var lprim = ToPrimitive(lval);
  55. var rprim = ToPrimitive(rval);
  56. if (Type(lprim) === 'String' || Type(rprim) === 'String') {
  57. var lstr = ToString(lprim);
  58. var rstr = ToString(rprim);
  59. return lstr + rstr;
  60. }
  61. /* eslint no-param-reassign: 1 */
  62. lval = lprim;
  63. rval = rprim;
  64. }
  65. var lnum = ToNumeric(lval);
  66. var rnum = ToNumeric(rval);
  67. var T = Type(lnum);
  68. if (T !== Type(rnum)) {
  69. throw new $TypeError('types of ' + lnum + ' and ' + rnum + ' differ');
  70. }
  71. var Operation = table[opText][T === 'BigInt' ? 1 : 0];
  72. return Operation(lnum, rnum);
  73. };