private Object EvaluateNumericBinary(Object v1, Object v2, JSToken operatorTok){
IConvertible ic1 = Convert.GetIConvertible(v1);
IConvertible ic2 = Convert.GetIConvertible(v2);
TypeCode t1 = Convert.GetTypeCode(v1, ic1);
TypeCode t2 = Convert.GetTypeCode(v2, ic2);
switch (t1){
case TypeCode.Empty:
return Double.NaN;
case TypeCode.DBNull:
return this.EvaluateNumericBinary(0, v2, operatorTok);
case TypeCode.Char: {
Object result;
int val = ic1.ToInt32(null);
switch (t2){
case TypeCode.Empty:
return Double.NaN;
case TypeCode.DBNull:
return NumericBinary.DoOp(val, 0, operatorTok);
case TypeCode.Boolean:
case TypeCode.Char:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
result = NumericBinary.DoOp(val, ic2.ToInt32(null), operatorTok);
break;
case TypeCode.UInt32:
case TypeCode.Int64:
result = NumericBinary.DoOp((long)val, ic2.ToInt64(null), operatorTok);
break;
case TypeCode.UInt64:
result = NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
break;
case TypeCode.Single:
case TypeCode.Double:
result = NumericBinary.DoOp((double)ic1.ToInt32(null), ic2.ToDouble(null), operatorTok);
break;
case TypeCode.String:
result = NumericBinary.DoOp(val, Convert.ToNumber(v2, ic2), operatorTok);
break;
case TypeCode.Object:
case TypeCode.Decimal:
case TypeCode.DateTime:
default:
result = null;
break;
}
if (this.operatorTok == JSToken.Minus && result != null && t2 != TypeCode.Char){
return Convert.Coerce2(result, TypeCode.Char, false);
} else if (result != null)
return result;
break;
}
case TypeCode.Boolean:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
{int val = ic1.ToInt32(null);
switch (t2){
case TypeCode.Empty:
return Double.NaN;
case TypeCode.DBNull:
return NumericBinary.DoOp(val, 0, operatorTok);
case TypeCode.Boolean:
case TypeCode.Char:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
return NumericBinary.DoOp(val, ic2.ToInt32(null), operatorTok);
case TypeCode.UInt32:
case TypeCode.Int64:
return NumericBinary.DoOp((long)val, ic2.ToInt64(null), operatorTok);
case TypeCode.UInt64:
if (val >= 0)
return NumericBinary.DoOp((ulong)val, ic2.ToUInt64(null), operatorTok);
else
return NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
case TypeCode.Single:
case TypeCode.Double:
return NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
case TypeCode.Object:
case TypeCode.Decimal:
case TypeCode.DateTime:
case TypeCode.String:
break;
}
break;}
case TypeCode.UInt32:
{uint val = ic1.ToUInt32(null);
switch (t2){
case TypeCode.Empty:
return Double.NaN;
case TypeCode.DBNull:
return NumericBinary.DoOp(val, 0, operatorTok);
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.Int32:
int val2 = ic2.ToInt32(null);
if (val2 >= 0)
return NumericBinary.DoOp(val, (uint)val2, operatorTok);
else
return NumericBinary.DoOp((long)val, (long)val2, operatorTok);
case TypeCode.Int64:
return NumericBinary.DoOp((long)val, ic2.ToInt64(null), operatorTok);
case TypeCode.Boolean:
case TypeCode.Char:
case TypeCode.UInt16:
case TypeCode.UInt32:
return NumericBinary.DoOp(val, ic2.ToUInt32(null), operatorTok);
case TypeCode.UInt64:
return NumericBinary.DoOp((ulong)val, ic2.ToUInt64(null), operatorTok);
case TypeCode.Single:
case TypeCode.Double:
return NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
case TypeCode.Object:
case TypeCode.Decimal:
case TypeCode.DateTime:
case TypeCode.String:
break;
}
break;}
case TypeCode.Int64:
{long val = ic1.ToInt64(null);
switch (t2){
case TypeCode.Empty:
return Double.NaN;
case TypeCode.DBNull:
return NumericBinary.DoOp(val, 0, operatorTok);
case TypeCode.Boolean:
case TypeCode.Char:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
return NumericBinary.DoOp(val, ic2.ToInt64(null), operatorTok);
case TypeCode.UInt64:
if (val >= 0)
return NumericBinary.DoOp((ulong)val, ic2.ToUInt64(null), operatorTok);
else
return NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
case TypeCode.Single:
case TypeCode.Double:
return NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
case TypeCode.Object:
case TypeCode.Decimal:
case TypeCode.DateTime:
case TypeCode.String:
break;
}
break;}
case TypeCode.UInt64:
{ulong val = ic1.ToUInt64(null);
switch (t2){
case TypeCode.Empty:
return Double.NaN;
case TypeCode.DBNull:
return NumericBinary.DoOp(val, 0, operatorTok);
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
long val2 = ic2.ToInt64(null);
if (val2 >= 0)
return NumericBinary.DoOp(val, (ulong)val2, operatorTok);
else
return NumericBinary.DoOp((double)val, (double)val2, operatorTok);
case TypeCode.Boolean:
case TypeCode.Char:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return NumericBinary.DoOp(val, ic2.ToUInt64(null), operatorTok);
case TypeCode.Single:
case TypeCode.Double:
return NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
case TypeCode.Object:
case TypeCode.Decimal:
case TypeCode.DateTime:
case TypeCode.String:
break;
}
break;}
case TypeCode.Single:
case TypeCode.Double:
{double d = ic1.ToDouble(null);
switch (t2){
case TypeCode.Empty:
return Double.NaN;
case TypeCode.DBNull:
return NumericBinary.DoOp(d, 0, operatorTok);
case TypeCode.Boolean:
case TypeCode.Char:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
return NumericBinary.DoOp(d, (double)ic2.ToInt32(null), operatorTok);
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
return NumericBinary.DoOp(d, ic2.ToDouble(null), operatorTok);
case TypeCode.Object:
case TypeCode.Decimal:
case TypeCode.DateTime:
case TypeCode.String:
break;
}
break;}
case TypeCode.Object:
case TypeCode.Decimal:
case TypeCode.DateTime:
case TypeCode.String:
break;
}
if (v2 == null) return Double.NaN;
MethodInfo oper = this.GetOperator(v1.GetType(), v2.GetType());
if (oper != null)
return oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[]{v1, v2}, null);
else{
return NumericBinary.DoOp(v1, v2, ic1, ic2, operatorTok);
}
}