'use strict'; var GetIntrinsic = require('get-intrinsic'); var $TypeError = GetIntrinsic('%TypeError%'); var HasOwnProperty = require('./HasOwnProperty'); var ToNumeric = require('./ToNumeric'); var ToPrimitive = require('./ToPrimitive'); var ToString = require('./ToString'); var Type = require('./Type'); var NumberAdd = require('./Number/add'); var NumberBitwiseAND = require('./Number/bitwiseAND'); var NumberBitwiseOR = require('./Number/bitwiseOR'); var NumberBitwiseXOR = require('./Number/bitwiseXOR'); var NumberDivide = require('./Number/divide'); var NumberExponentiate = require('./Number/exponentiate'); var NumberLeftShift = require('./Number/leftShift'); var NumberMultiply = require('./Number/multiply'); var NumberRemainder = require('./Number/remainder'); var NumberSignedRightShift = require('./Number/signedRightShift'); var NumberSubtract = require('./Number/subtract'); var NumberUnsignedRightShift = require('./Number/unsignedRightShift'); var BigIntAdd = require('./BigInt/add'); var BigIntBitwiseAND = require('./BigInt/bitwiseAND'); var BigIntBitwiseOR = require('./BigInt/bitwiseOR'); var BigIntBitwiseXOR = require('./BigInt/bitwiseXOR'); var BigIntDivide = require('./BigInt/divide'); var BigIntExponentiate = require('./BigInt/exponentiate'); var BigIntLeftShift = require('./BigInt/leftShift'); var BigIntMultiply = require('./BigInt/multiply'); var BigIntRemainder = require('./BigInt/remainder'); var BigIntSignedRightShift = require('./BigInt/signedRightShift'); var BigIntSubtract = require('./BigInt/subtract'); var BigIntUnsignedRightShift = require('./BigInt/unsignedRightShift'); // https://262.ecma-international.org/12.0/#sec-applystringornumericbinaryoperator // https://262.ecma-international.org/12.0/#step-applystringornumericbinaryoperator-operations-table var table = { '**': [NumberExponentiate, BigIntExponentiate], '*': [NumberMultiply, BigIntMultiply], '/': [NumberDivide, BigIntDivide], '%': [NumberRemainder, BigIntRemainder], '+': [NumberAdd, BigIntAdd], '-': [NumberSubtract, BigIntSubtract], '<<': [NumberLeftShift, BigIntLeftShift], '>>': [NumberSignedRightShift, BigIntSignedRightShift], '>>>': [NumberUnsignedRightShift, BigIntUnsignedRightShift], '&': [NumberBitwiseAND, BigIntBitwiseAND], '^': [NumberBitwiseXOR, BigIntBitwiseXOR], '|': [NumberBitwiseOR, BigIntBitwiseOR] }; module.exports = function ApplyStringOrNumericBinaryOperator(lval, opText, rval) { if (Type(opText) !== 'String' || !HasOwnProperty(table, opText)) { throw new $TypeError('Assertion failed: `opText` must be a valid operation string'); } if (opText === '+') { var lprim = ToPrimitive(lval); var rprim = ToPrimitive(rval); if (Type(lprim) === 'String' || Type(rprim) === 'String') { var lstr = ToString(lprim); var rstr = ToString(rprim); return lstr + rstr; } /* eslint no-param-reassign: 1 */ lval = lprim; rval = rprim; } var lnum = ToNumeric(lval); var rnum = ToNumeric(rval); var T = Type(lnum); if (T !== Type(rnum)) { throw new $TypeError('types of ' + lnum + ' and ' + rnum + ' differ'); } var Operation = table[opText][T === 'BigInt' ? 1 : 0]; return Operation(lnum, rnum); };