PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Languages/IronPython/IronPython/Runtime/Binding/PythonBinaryOperationBinder.cs

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