PageRenderTime 504ms CodeModel.GetById 22ms RepoModel.GetById 3ms app.codeStats 0ms

/DICK.B1/IronPython/Runtime/Binding/PythonBinaryOperationBinder.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 883 lines | 711 code | 157 blank | 15 comment | 515 complexity | da5ee5b31545b69e89b32f2009112b11 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if !CLR2
  16. using System.Linq.Expressions;
  17. #else
  18. using Microsoft.Scripting.Ast;
  19. #endif
  20. using System;
  21. using System.Dynamic;
  22. using System.Reflection;
  23. using System.Runtime.CompilerServices;
  24. using Microsoft.Scripting.Generation;
  25. using Microsoft.Scripting.Runtime;
  26. using Microsoft.Scripting.Utils;
  27. using IronPython.Runtime.Operations;
  28. using IronPython.Runtime.Types;
  29. namespace IronPython.Runtime.Binding {
  30. using Ast = Expression;
  31. using AstUtils = Microsoft.Scripting.Ast.Utils;
  32. class PythonBinaryOperationBinder : BinaryOperationBinder, IPythonSite, IExpressionSerializable {
  33. private readonly PythonContext/*!*/ _context;
  34. public PythonBinaryOperationBinder(PythonContext/*!*/ context, ExpressionType operation)
  35. : base(operation) {
  36. _context = context;
  37. }
  38. public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) {
  39. return PythonProtocol.Operation(this, target, arg, errorSuggestion);
  40. }
  41. //private static Func<CallSite, object, object, object> DoubleAddSite = new Func<CallSite, object, object, object>(DoubleAdd);
  42. public override T BindDelegate<T>(CallSite<T> site, object[] args) {
  43. if (args[0] != null &&
  44. CompilerHelpers.GetType(args[0]) == CompilerHelpers.GetType(args[1])) {
  45. switch (Operation) {
  46. case ExpressionType.Add:
  47. case ExpressionType.AddAssign:
  48. return BindAdd<T>(site, args);
  49. case ExpressionType.And:
  50. case ExpressionType.AndAssign:
  51. return BindAnd<T>(site, args);
  52. case ExpressionType.Or:
  53. case ExpressionType.OrAssign:
  54. return BindOr<T>(site, args);
  55. case ExpressionType.Subtract:
  56. case ExpressionType.SubtractAssign:
  57. return BindSubtract<T>(site, args);
  58. case ExpressionType.Equal:
  59. return BindEqual<T>(site, args);
  60. case ExpressionType.NotEqual:
  61. return BindNotEqual<T>(site, args);
  62. case ExpressionType.GreaterThan:
  63. return BindGreaterThan<T>(site, args);
  64. case ExpressionType.LessThan:
  65. return BindLessThan<T>(site, args);
  66. case ExpressionType.LessThanOrEqual:
  67. return BindLessThanOrEqual<T>(site, args);
  68. case ExpressionType.GreaterThanOrEqual:
  69. return BindGreaterThanOrEqual<T>(site, args);
  70. case ExpressionType.Multiply:
  71. case ExpressionType.MultiplyAssign:
  72. return BindMultiply<T>(site, args);
  73. case ExpressionType.Divide:
  74. case ExpressionType.DivideAssign:
  75. return BindDivide<T>(site, args);
  76. case ExpressionType.Modulo:
  77. return BindModulo<T>(site, args);
  78. }
  79. } else {
  80. switch(Operation) {
  81. case ExpressionType.Modulo:
  82. return BindModulo<T>(site, args);
  83. case ExpressionType.Multiply:
  84. return BindMultiplyDifferentTypes<T>(site, args);
  85. }
  86. }
  87. return base.BindDelegate<T>(site, args);
  88. }
  89. private T BindModulo<T>(CallSite<T> site, object[] args) where T : class {
  90. if (CompilerHelpers.GetType(args[0]) == typeof(string) && !(args[1] is Extensible<string>)) {
  91. if (typeof(T) == typeof(Func<CallSite, string, PythonDictionary, object>)) {
  92. return (T)(object)new Func<CallSite, string, PythonDictionary, object>(StringModulo);
  93. } else if (typeof(T) == typeof(Func<CallSite, string, PythonTuple, object>)) {
  94. return (T)(object)new Func<CallSite, string, PythonTuple, object>(StringModulo);
  95. } else if (typeof(T) == typeof(Func<CallSite, string, object, object>)) {
  96. return (T)(object)new Func<CallSite, string, object, object>(StringModulo);
  97. } else if (typeof(T) == typeof(Func<CallSite, object, PythonDictionary, object>)) {
  98. return (T)(object)new Func<CallSite, object, PythonDictionary, object>(StringModulo);
  99. } else if (typeof(T) == typeof(Func<CallSite, object, PythonTuple, object>)) {
  100. return (T)(object)new Func<CallSite, object, PythonTuple, object>(StringModulo);
  101. } else if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  102. return (T)(object)new Func<CallSite, object, object, object>(StringModulo);
  103. }
  104. }
  105. return base.BindDelegate(site, args);
  106. }
  107. private T BindMultiply<T>(CallSite<T> site, object[] args) where T : class {
  108. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  109. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  110. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  111. return (T)(object)new Func<CallSite, object, object, object>(IntMultiply);
  112. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  113. return (T)(object)new Func<CallSite, int, object, object>(IntMultiply);
  114. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  115. return (T)(object)new Func<CallSite, object, int, object>(IntMultiply);
  116. }
  117. }
  118. return base.BindDelegate(site, args);
  119. }
  120. private T BindMultiplyDifferentTypes<T>(CallSite<T> site, object[] args) where T : class {
  121. if (CompilerHelpers.GetType(args[0]) == typeof(List) &&
  122. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  123. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  124. return (T)(object)new Func<CallSite, object, object, object>(ListIntMultiply);
  125. }
  126. } else if (CompilerHelpers.GetType(args[0]) == typeof(string) &&
  127. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  128. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  129. return (T)(object)new Func<CallSite, object, object, object>(StringIntMultiply);
  130. }
  131. } else if (CompilerHelpers.GetType(args[0]) == typeof(PythonTuple) &&
  132. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  133. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  134. return (T)(object)new Func<CallSite, object, object, object>(TupleIntMultiply);
  135. }
  136. }
  137. return base.BindDelegate(site, args);
  138. }
  139. private T BindDivide<T>(CallSite<T> site, object[] args) where T : class {
  140. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  141. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  142. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  143. return (T)(object)new Func<CallSite, object, object, object>(IntDivide);
  144. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  145. return (T)(object)new Func<CallSite, int, object, object>(IntDivide);
  146. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  147. return (T)(object)new Func<CallSite, object, int, object>(IntDivide);
  148. }
  149. }
  150. return base.BindDelegate(site, args);
  151. }
  152. private T BindLessThanOrEqual<T>(CallSite<T> site, object[] args) where T : class {
  153. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  154. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  155. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  156. return (T)(object)new Func<CallSite, object, object, object>(IntLessThanOrEqual);
  157. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  158. return (T)(object)new Func<CallSite, int, object, object>(IntLessThanOrEqual);
  159. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  160. return (T)(object)new Func<CallSite, object, int, object>(IntLessThanOrEqual);
  161. }
  162. }
  163. return base.BindDelegate(site, args);
  164. }
  165. private T BindGreaterThanOrEqual<T>(CallSite<T> site, object[] args) where T : class {
  166. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  167. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  168. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  169. return (T)(object)new Func<CallSite, object, object, object>(IntGreaterThanOrEqual);
  170. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  171. return (T)(object)new Func<CallSite, int, object, object>(IntGreaterThanOrEqual);
  172. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  173. return (T)(object)new Func<CallSite, object, int, object>(IntGreaterThanOrEqual);
  174. }
  175. }
  176. return base.BindDelegate(site, args);
  177. }
  178. private T BindGreaterThan<T>(CallSite<T> site, object[] args) where T : class {
  179. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  180. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  181. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  182. return (T)(object)new Func<CallSite, object, object, object>(IntGreaterThan);
  183. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  184. return (T)(object)new Func<CallSite, int, object, object>(IntGreaterThan);
  185. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  186. return (T)(object)new Func<CallSite, object, int, object>(IntGreaterThan);
  187. }
  188. }
  189. return base.BindDelegate(site, args);
  190. }
  191. private T BindLessThan<T>(CallSite<T> site, object[] args) where T : class {
  192. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  193. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  194. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  195. return (T)(object)new Func<CallSite, object, object, object>(IntLessThan);
  196. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  197. return (T)(object)new Func<CallSite, int, object, object>(IntLessThan);
  198. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  199. return (T)(object)new Func<CallSite, object, int, object>(IntLessThan);
  200. }
  201. }
  202. return base.BindDelegate(site, args);
  203. }
  204. private T BindAnd<T>(CallSite<T> site, object[] args) where T : class {
  205. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  206. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  207. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  208. return (T)(object)new Func<CallSite, object, object, object>(IntAnd);
  209. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  210. return (T)(object)new Func<CallSite, int, object, object>(IntAnd);
  211. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  212. return (T)(object)new Func<CallSite, object, int, object>(IntAnd);
  213. }
  214. }
  215. return base.BindDelegate(site, args);
  216. }
  217. private T BindOr<T>(CallSite<T> site, object[] args) where T : class {
  218. if (CompilerHelpers.GetType(args[0]) == typeof(int) &&
  219. CompilerHelpers.GetType(args[1]) == typeof(int)) {
  220. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  221. return (T)(object)new Func<CallSite, object, object, object>(IntOr);
  222. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  223. return (T)(object)new Func<CallSite, int, object, object>(IntOr);
  224. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  225. return (T)(object)new Func<CallSite, object, int, object>(IntOr);
  226. }
  227. }
  228. return base.BindDelegate(site, args);
  229. }
  230. private T BindAdd<T>(CallSite<T> site, object[] args) where T : class {
  231. Type t = args[0].GetType();
  232. if (t == typeof(string)) {
  233. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  234. return (T)(object)new Func<CallSite, object, object, object>(StringAdd);
  235. } else if (typeof(T) == typeof(Func<CallSite, object, string, object>)) {
  236. return (T)(object)new Func<CallSite, object, string, object>(StringAdd);
  237. } else if (typeof(T) == typeof(Func<CallSite, string, object, object>)) {
  238. return (T)(object)new Func<CallSite, string, object, object>(StringAdd);
  239. }
  240. } else if (t == typeof(List)) {
  241. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  242. if (Operation == ExpressionType.Add) {
  243. return (T)(object)new Func<CallSite, object, object, object>(ListAdd);
  244. } else {
  245. return (T)(object)new Func<CallSite, object, object, object>(ListAddAssign);
  246. }
  247. }
  248. } else if (t == typeof(PythonTuple)) {
  249. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  250. return (T)(object)new Func<CallSite, object, object, object>(TupleAdd);
  251. }
  252. } else if (!t.IsEnum) {
  253. switch (Type.GetTypeCode(t)) {
  254. case TypeCode.Double:
  255. if(typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  256. return (T)(object)new Func<CallSite, object, object, object>(DoubleAdd);
  257. }
  258. break;
  259. case TypeCode.Int32:
  260. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  261. return (T)(object)new Func<CallSite, object, object, object>(IntAdd);
  262. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  263. return (T)(object)new Func<CallSite, object, int, object>(IntAdd);
  264. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  265. return (T)(object)new Func<CallSite, int, object, object>(IntAdd);
  266. }
  267. break;
  268. }
  269. }
  270. return base.BindDelegate(site, args);
  271. }
  272. private T BindSubtract<T>(CallSite<T> site, object[] args) where T : class {
  273. Type t = args[0].GetType();
  274. if (!t.IsEnum) {
  275. switch (Type.GetTypeCode(t)) {
  276. case TypeCode.Double:
  277. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  278. return (T)(object)new Func<CallSite, object, object, object>(DoubleSubtract);
  279. }
  280. break;
  281. case TypeCode.Int32:
  282. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  283. return (T)(object)new Func<CallSite, object, object, object>(IntSubtract);
  284. } else if (typeof(T) == typeof(Func<CallSite, object, int, object>)) {
  285. return (T)(object)new Func<CallSite, object, int, object>(IntSubtract);
  286. } else if (typeof(T) == typeof(Func<CallSite, int, object, object>)) {
  287. return (T)(object)new Func<CallSite, int, object, object>(IntSubtract);
  288. }
  289. break;
  290. }
  291. }
  292. return base.BindDelegate(site, args);
  293. }
  294. private T BindEqual<T>(CallSite<T> site, object[] args) where T : class {
  295. Type t = args[0].GetType();
  296. if (t == typeof(string)) {
  297. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  298. return (T)(object)new Func<CallSite, object, object, object>(StringEqual);
  299. } else if (typeof(T) == typeof(Func<CallSite, string, object, object>)) {
  300. return (T)(object)new Func<CallSite, string, object, object>(StringEqual);
  301. } else if (typeof(T) == typeof(Func<CallSite, object, string, object>)) {
  302. return (T)(object)new Func<CallSite, object, string, object>(StringEqual);
  303. }
  304. } else if (!t.IsEnum && typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  305. switch (Type.GetTypeCode(t)) {
  306. case TypeCode.Double:
  307. return (T)(object)new Func<CallSite, object, object, object>(DoubleEqual);
  308. case TypeCode.Int32:
  309. return (T)(object)new Func<CallSite, object, object, object>(IntEqual);
  310. }
  311. }
  312. return base.BindDelegate(site, args);
  313. }
  314. private T BindNotEqual<T>(CallSite<T> site, object[] args) where T : class {
  315. Type t = args[0].GetType();
  316. if (t == typeof(string)) {
  317. if (typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  318. return (T)(object)new Func<CallSite, object, object, object>(StringNotEqual);
  319. } else if (typeof(T) == typeof(Func<CallSite, object, string, object>)) {
  320. return (T)(object)new Func<CallSite, object, string, object>(StringNotEqual);
  321. } else if (typeof(T) == typeof(Func<CallSite, string, object, object>)) {
  322. return (T)(object)new Func<CallSite, string, object, object>(StringNotEqual);
  323. }
  324. } else if (!t.IsEnum && typeof(T) == typeof(Func<CallSite, object, object, object>)) {
  325. switch (Type.GetTypeCode(t)) {
  326. case TypeCode.Double:
  327. return (T)(object)new Func<CallSite, object, object, object>(DoubleNotEqual);
  328. case TypeCode.Int32:
  329. return (T)(object)new Func<CallSite, object, object, object>(IntNotEqual);
  330. }
  331. }
  332. return base.BindDelegate(site, args);
  333. }
  334. private object StringModulo(CallSite site, string self, PythonDictionary other) {
  335. return StringOps.Mod(Context.SharedContext, self, other);
  336. }
  337. private object StringModulo(CallSite site, string self, PythonTuple other) {
  338. return StringOps.Mod(Context.SharedContext, self, other);
  339. }
  340. private object StringModulo(CallSite site, string self, object other) {
  341. return StringOps.Mod(Context.SharedContext, self, other);
  342. }
  343. private object StringModulo(CallSite site, object self, PythonDictionary other) {
  344. if (self != null && self.GetType() == typeof(string)) {
  345. return StringOps.Mod(Context.SharedContext, (string)self, other);
  346. }
  347. return ((CallSite<Func<CallSite, object, PythonDictionary, object>>)site).Update(site, self, other);
  348. }
  349. private object StringModulo(CallSite site, object self, PythonTuple other) {
  350. if (self != null && self.GetType() == typeof(string)) {
  351. return StringOps.Mod(Context.SharedContext, (string)self, other);
  352. }
  353. return ((CallSite<Func<CallSite, object, PythonTuple, object>>)site).Update(site, self, other);
  354. }
  355. private object StringModulo(CallSite site, object self, object other) {
  356. if (self != null && self.GetType() == typeof(string)) {
  357. return StringOps.Mod(Context.SharedContext, (string)self, other);
  358. }
  359. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  360. }
  361. private object DoubleAdd(CallSite site, object self, object other) {
  362. if (self != null && self.GetType() == typeof(double) &&
  363. other != null && other.GetType() == typeof(double)) {
  364. return (double)self + (double)other;
  365. }
  366. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  367. }
  368. private object IntAdd(CallSite site, object self, object other) {
  369. if (self != null && self.GetType() == typeof(int) &&
  370. other != null && other.GetType() == typeof(int)) {
  371. return Int32Ops.Add((int)self, (int)other);
  372. }
  373. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  374. }
  375. private object IntAdd(CallSite site, object self, int other) {
  376. if (self != null && self.GetType() == typeof(int)) {
  377. return Int32Ops.Add((int)self, other);
  378. }
  379. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  380. }
  381. private object IntAdd(CallSite site, int self, object other) {
  382. if (other != null && other.GetType() == typeof(int)) {
  383. return Int32Ops.Add(self, (int)other);
  384. }
  385. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  386. }
  387. private object ListIntMultiply(CallSite site, object self, object other) {
  388. if (self != null && self.GetType() == typeof(List) &&
  389. other != null && other.GetType() == typeof(int)) {
  390. return ((List)self) * (int)other;
  391. }
  392. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  393. }
  394. private object StringIntMultiply(CallSite site, object self, object other) {
  395. if (self != null && self.GetType() == typeof(string) &&
  396. other != null && other.GetType() == typeof(int)) {
  397. return StringOps.Multiply((string)self, (int)other);
  398. }
  399. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  400. }
  401. private object TupleIntMultiply(CallSite site, object self, object other) {
  402. if (self != null && self.GetType() == typeof(PythonTuple) &&
  403. other != null && other.GetType() == typeof(int)) {
  404. return ((PythonTuple)self) * (int)other;
  405. }
  406. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  407. }
  408. private object IntMultiply(CallSite site, object self, object other) {
  409. if (self != null && self.GetType() == typeof(int) &&
  410. other != null && other.GetType() == typeof(int)) {
  411. return Int32Ops.Multiply((int)self, (int)other);
  412. }
  413. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  414. }
  415. private object IntMultiply(CallSite site, object self, int other) {
  416. if (self != null && self.GetType() == typeof(int)) {
  417. return Int32Ops.Multiply((int)self, other);
  418. }
  419. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  420. }
  421. private object IntMultiply(CallSite site, int self, object other) {
  422. if (other != null && other.GetType() == typeof(int)) {
  423. return Int32Ops.Multiply(self, (int)other);
  424. }
  425. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  426. }
  427. private object IntDivide(CallSite site, object self, object other) {
  428. if (self != null && self.GetType() == typeof(int) &&
  429. other != null && other.GetType() == typeof(int)) {
  430. return Int32Ops.Divide((int)self, (int)other);
  431. }
  432. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  433. }
  434. private object IntDivide(CallSite site, object self, int other) {
  435. if (self != null && self.GetType() == typeof(int)) {
  436. return Int32Ops.Divide((int)self, other);
  437. }
  438. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  439. }
  440. private object IntDivide(CallSite site, int self, object other) {
  441. if (other != null && other.GetType() == typeof(int)) {
  442. return Int32Ops.Divide(self, (int)other);
  443. }
  444. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  445. }
  446. private object IntAnd(CallSite site, object self, object other) {
  447. if (self != null && self.GetType() == typeof(int) &&
  448. other != null && other.GetType() == typeof(int)) {
  449. return ScriptingRuntimeHelpers.Int32ToObject(Int32Ops.BitwiseAnd((int)self, (int)other));
  450. }
  451. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  452. }
  453. private object IntAnd(CallSite site, object self, int other) {
  454. if (self != null && self.GetType() == typeof(int)) {
  455. return ScriptingRuntimeHelpers.Int32ToObject(Int32Ops.BitwiseAnd((int)self, other));
  456. }
  457. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  458. }
  459. private object IntAnd(CallSite site, int self, object other) {
  460. if (other != null && other.GetType() == typeof(int)) {
  461. return ScriptingRuntimeHelpers.Int32ToObject(Int32Ops.BitwiseAnd(self, (int)other));
  462. }
  463. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  464. }
  465. private object IntOr(CallSite site, object self, object other) {
  466. if (self != null && self.GetType() == typeof(int) &&
  467. other != null && other.GetType() == typeof(int)) {
  468. return ScriptingRuntimeHelpers.Int32ToObject(Int32Ops.BitwiseOr((int)self, (int)other));
  469. }
  470. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  471. }
  472. private object IntOr(CallSite site, object self, int other) {
  473. if (self != null && self.GetType() == typeof(int)) {
  474. return ScriptingRuntimeHelpers.Int32ToObject(Int32Ops.BitwiseOr((int)self, other));
  475. }
  476. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  477. }
  478. private object IntOr(CallSite site, int self, object other) {
  479. if (other != null && other.GetType() == typeof(int)) {
  480. return ScriptingRuntimeHelpers.Int32ToObject(Int32Ops.BitwiseOr(self, (int)other));
  481. }
  482. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  483. }
  484. private object ListAdd(CallSite site, object self, object other) {
  485. if (self != null && self.GetType() == typeof(List) &&
  486. other != null && other.GetType() == typeof(List)) {
  487. return (List)self + (List)other;
  488. }
  489. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  490. }
  491. private object ListAddAssign(CallSite site, object self, object other) {
  492. if (self != null && self.GetType() == typeof(List) &&
  493. other != null && other.GetType() == typeof(List)) {
  494. return ((List)self).InPlaceAdd(other);
  495. }
  496. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  497. }
  498. private object TupleAdd(CallSite site, object self, object other) {
  499. if (self != null && self.GetType() == typeof(PythonTuple) &&
  500. other != null && other.GetType() == typeof(PythonTuple)) {
  501. return (PythonTuple)self + (PythonTuple)other;
  502. }
  503. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  504. }
  505. private object StringAdd(CallSite site, object self, object other) {
  506. if (self != null && self.GetType() == typeof(string) &&
  507. other != null && other.GetType() == typeof(string)) {
  508. return StringOps.Add((string)self, (string)other);
  509. }
  510. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  511. }
  512. private object StringAdd(CallSite site, string self, object other) {
  513. if (self != null &&
  514. other != null && other.GetType() == typeof(string)) {
  515. return StringOps.Add(self, (string)other);
  516. }
  517. return ((CallSite<Func<CallSite, string, object, object>>)site).Update(site, self, other);
  518. }
  519. private object StringAdd(CallSite site, object self, string other) {
  520. if (self != null && self.GetType() == typeof(string) &&
  521. other != null) {
  522. return StringOps.Add((string)self, other);
  523. }
  524. return ((CallSite<Func<CallSite, object, string, object>>)site).Update(site, self, other);
  525. }
  526. private object DoubleSubtract(CallSite site, object self, object other) {
  527. if (self != null && self.GetType() == typeof(double) &&
  528. other != null && other.GetType() == typeof(double)) {
  529. return (double)self - (double)other;
  530. }
  531. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  532. }
  533. private object IntSubtract(CallSite site, object self, object other) {
  534. if (self != null && self.GetType() == typeof(int) &&
  535. other != null && other.GetType() == typeof(int)) {
  536. return Int32Ops.Subtract((int)self, (int)other);
  537. }
  538. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  539. }
  540. private object IntSubtract(CallSite site, object self, int other) {
  541. if (self != null && self.GetType() == typeof(int)) {
  542. return Int32Ops.Subtract((int)self, other);
  543. }
  544. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  545. }
  546. private object IntSubtract(CallSite site, int self, object other) {
  547. if (other != null && other.GetType() == typeof(int)) {
  548. return Int32Ops.Subtract(self, (int)other);
  549. }
  550. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  551. }
  552. private object DoubleEqual(CallSite site, object self, object other) {
  553. if (self != null && self.GetType() == typeof(double) &&
  554. other != null && other.GetType() == typeof(double)) {
  555. return DoubleOps.Equals((double)self, (double)other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  556. }
  557. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  558. }
  559. private object IntEqual(CallSite site, object self, object other) {
  560. if (self != null && self.GetType() == typeof(int) &&
  561. other != null && other.GetType() == typeof(int)) {
  562. return (int)self == (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  563. }
  564. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  565. }
  566. private object StringEqual(CallSite site, object self, object other) {
  567. if (self != null && self.GetType() == typeof(string) &&
  568. other != null && other.GetType() == typeof(string)) {
  569. return StringOps.Equals((string)self, (string)other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  570. }
  571. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  572. }
  573. private object StringEqual(CallSite site, string self, object other) {
  574. if (self != null &&
  575. other != null && other.GetType() == typeof(string)) {
  576. return StringOps.Equals(self, (string)other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  577. }
  578. return ((CallSite<Func<CallSite, string, object, object>>)site).Update(site, self, other);
  579. }
  580. private object StringEqual(CallSite site, object self, string other) {
  581. if (self != null && self.GetType() == typeof(string) &&
  582. other != null) {
  583. return StringOps.Equals((string)self, other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  584. }
  585. return ((CallSite<Func<CallSite, object, string, object>>)site).Update(site, self, other);
  586. }
  587. private object DoubleNotEqual(CallSite site, object self, object other) {
  588. if (self != null && self.GetType() == typeof(double) &&
  589. other != null && other.GetType() == typeof(double)) {
  590. return DoubleOps.NotEquals((double)self, (double)other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  591. }
  592. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  593. }
  594. private object IntNotEqual(CallSite site, object self, object other) {
  595. if (self != null && self.GetType() == typeof(int) &&
  596. other != null && other.GetType() == typeof(int)) {
  597. return (int)self != (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  598. }
  599. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  600. }
  601. private object StringNotEqual(CallSite site, object self, object other) {
  602. if (self != null && self.GetType() == typeof(string) &&
  603. other != null && other.GetType() == typeof(string)) {
  604. return StringOps.NotEquals((string)self, (string)other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  605. }
  606. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  607. }
  608. private object StringNotEqual(CallSite site, string self, object other) {
  609. if (self != null &&
  610. other != null && other.GetType() == typeof(string)) {
  611. return StringOps.NotEquals(self, (string)other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  612. }
  613. return ((CallSite<Func<CallSite, string, object, object>>)site).Update(site, self, other);
  614. }
  615. private object StringNotEqual(CallSite site, object self, string other) {
  616. if (self != null && self.GetType() == typeof(string) &&
  617. other != null) {
  618. return StringOps.NotEquals((string)self, other) ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  619. }
  620. return ((CallSite<Func<CallSite, object, string, object>>)site).Update(site, self, other);
  621. }
  622. private object IntGreaterThan(CallSite site, object self, object other) {
  623. if (self != null && self.GetType() == typeof(int) &&
  624. other != null && other.GetType() == typeof(int)) {
  625. return (int)self > (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  626. }
  627. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  628. }
  629. private object IntGreaterThan(CallSite site, object self, int other) {
  630. if (self != null && self.GetType() == typeof(int)) {
  631. return (int)self > other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  632. }
  633. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  634. }
  635. private object IntGreaterThan(CallSite site, int self, object other) {
  636. if (other != null && other.GetType() == typeof(int)) {
  637. return self > (int)other;
  638. }
  639. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  640. }
  641. private object IntLessThan(CallSite site, object self, object other) {
  642. if (self != null && self.GetType() == typeof(int) &&
  643. other != null && other.GetType() == typeof(int)) {
  644. return (int)self < (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  645. }
  646. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  647. }
  648. private object IntLessThan(CallSite site, object self, int other) {
  649. if (self != null && self.GetType() == typeof(int)) {
  650. return (int)self < other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  651. }
  652. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  653. }
  654. private object IntLessThan(CallSite site, int self, object other) {
  655. if (other != null && other.GetType() == typeof(int)) {
  656. return self < (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  657. }
  658. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  659. }
  660. private object IntGreaterThanOrEqual(CallSite site, object self, object other) {
  661. if (self != null && self.GetType() == typeof(int) &&
  662. other != null && other.GetType() == typeof(int)) {
  663. return (int)self >= (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  664. }
  665. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  666. }
  667. private object IntGreaterThanOrEqual(CallSite site, object self, int other) {
  668. if (self != null && self.GetType() == typeof(int)) {
  669. return (int)self >= other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  670. }
  671. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  672. }
  673. private object IntGreaterThanOrEqual(CallSite site, int self, object other) {
  674. if (other != null && other.GetType() == typeof(int)) {
  675. return self >= (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  676. }
  677. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  678. }
  679. private object IntLessThanOrEqual(CallSite site, object self, object other) {
  680. if (self != null && self.GetType() == typeof(int) &&
  681. other != null && other.GetType() == typeof(int)) {
  682. return (int)self <= (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  683. }
  684. return ((CallSite<Func<CallSite, object, object, object>>)site).Update(site, self, other);
  685. }
  686. private object IntLessThanOrEqual(CallSite site, object self, int other) {
  687. if (self != null && self.GetType() == typeof(int)) {
  688. return (int)self <= other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  689. }
  690. return ((CallSite<Func<CallSite, object, int, object>>)site).Update(site, self, other);
  691. }
  692. private object IntLessThanOrEqual(CallSite site, int self, object other) {
  693. if (other != null && other.GetType() == typeof(int)) {
  694. return self <= (int)other ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;
  695. }
  696. return ((CallSite<Func<CallSite, int, object, object>>)site).Update(site, self, other);
  697. }
  698. public override int GetHashCode() {
  699. return base.GetHashCode() ^ _context.Binder.GetHashCode();
  700. }
  701. public override bool Equals(object obj) {
  702. PythonBinaryOperationBinder ob = obj as PythonBinaryOperationBinder;
  703. if (ob == null) {
  704. return false;
  705. }
  706. return ob._context.Binder == _context.Binder && base.Equals(obj);
  707. }
  708. public PythonContext/*!*/ Context {
  709. get {
  710. return _context;
  711. }
  712. }
  713. public override string ToString() {
  714. return "PythonBinary " + Operation;
  715. }
  716. #region IExpressionSerializable Members
  717. public Expression CreateExpression() {
  718. return Ast.Call(
  719. typeof(PythonOps).GetMethod("MakeBinaryOperationAction"),
  720. BindingHelpers.CreateBinderStateExpression(),
  721. AstUtils.Constant(Operation)
  722. );
  723. }
  724. #endregion
  725. }
  726. }