You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					81 lines
				
				3.1 KiB
			
		
		
			
		
	
	
					81 lines
				
				3.1 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								'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://ecma-international.org/ecma-262/12.0/#sec-applystringornumericbinaryoperator
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// https://ecma-international.org/ecma-262/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);
							 | 
						||
| 
								 | 
							
								};
							 |