PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/IronPython_Main/Languages/IronPython/IronPython/Runtime/Types/OperatorMapping.cs

#
C# | 143 lines | 93 code | 18 blank | 32 comment | 6 complexity | a015c8f20b4a2c10c7d27705317ca5a5 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using IronPython.Runtime.Binding;
  5. namespace IronPython.Runtime.Types {
  6. /// <summary>
  7. /// OperatorMapping provides a mapping from DLR operators to their associated .NET methods.
  8. /// </summary>
  9. class OperatorMapping {
  10. private static readonly OperatorMapping[] _infos = MakeOperatorTable(); // table of Operators, names, and alt names for looking up methods.
  11. private readonly PythonOperationKind _operator;
  12. private readonly string _name;
  13. private readonly string _altName;
  14. private readonly Type _altExpectedType;
  15. private OperatorMapping(PythonOperationKind op, string name, string altName) {
  16. _operator = op;
  17. _name = name;
  18. _altName = altName;
  19. }
  20. private OperatorMapping(PythonOperationKind op, string name, string altName, Type alternateExpectedType) {
  21. _operator = op;
  22. _name = name;
  23. _altName = altName;
  24. _altExpectedType = alternateExpectedType;
  25. }
  26. /// <summary>
  27. /// Given an operator returns the OperatorMapping associated with the operator or null
  28. /// </summary>
  29. public static OperatorMapping GetOperatorMapping(PythonOperationKind op) {
  30. foreach (OperatorMapping info in _infos) {
  31. if (info._operator == op) return info;
  32. }
  33. return null;
  34. }
  35. public static OperatorMapping GetOperatorMapping(string name) {
  36. foreach (OperatorMapping info in _infos) {
  37. if (info.Name == name || info.AlternateName == name) {
  38. return info;
  39. }
  40. }
  41. return null;
  42. }
  43. /// <summary>
  44. /// The operator the OperatorMapping provides info for.
  45. /// </summary>
  46. public PythonOperationKind Operator {
  47. get { return _operator; }
  48. }
  49. /// <summary>
  50. /// The primary method name associated with the method. This method name is
  51. /// usally in the form of op_Operator (e.g. op_Addition).
  52. /// </summary>
  53. public string Name {
  54. get { return _name; }
  55. }
  56. /// <summary>
  57. /// The secondary method name associated with the method. This method name is
  58. /// usually a standard .NET method name with pascal casing (e.g. Add).
  59. /// </summary>
  60. public string AlternateName {
  61. get { return _altName; }
  62. }
  63. /// <summary>
  64. /// The return type that must match for the alternate operator to be valid.
  65. ///
  66. /// This is available alternate operators don't have special names and therefore
  67. /// could be confused for a normal method which isn't fulfilling the contract.
  68. /// </summary>
  69. public Type AlternateExpectedType {
  70. get {
  71. return _altExpectedType;
  72. }
  73. }
  74. private static OperatorMapping[] MakeOperatorTable() {
  75. List<OperatorMapping> res = new List<OperatorMapping>();
  76. // alternate names from: http://msdn2.microsoft.com/en-us/library/2sk3x8a7(vs.71).aspx
  77. // different in:
  78. // comparisons all support alternative names, Xor is "ExclusiveOr" not "Xor"
  79. // unary operators as defined in Partition I Architecture 9.3.1:
  80. res.Add(new OperatorMapping(PythonOperationKind.Negate, "op_UnaryNegation", "Negate")); // - (unary)
  81. res.Add(new OperatorMapping(PythonOperationKind.Positive, "op_UnaryPlus", "Plus")); // + (unary)
  82. res.Add(new OperatorMapping(PythonOperationKind.Not, "op_LogicalNot", null)); // !
  83. //res.Add(new OperatorMapping(PythonOperationKind.AddressOf, "op_AddressOf", null)); // & (unary)
  84. res.Add(new OperatorMapping(PythonOperationKind.OnesComplement, "op_OnesComplement", "OnesComplement")); // ~
  85. //res.Add(new OperatorMapping(PythonOperationKind.PointerDereference, "op_PointerDereference", null)); // * (unary)
  86. // binary operators as defined in Partition I Architecture 9.3.2:
  87. res.Add(new OperatorMapping(PythonOperationKind.Add, "op_Addition", "Add")); // +
  88. res.Add(new OperatorMapping(PythonOperationKind.Subtract, "op_Subtraction", "Subtract")); // -
  89. res.Add(new OperatorMapping(PythonOperationKind.Multiply, "op_Multiply", "Multiply")); // *
  90. res.Add(new OperatorMapping(PythonOperationKind.Divide, "op_Division", "Divide")); // /
  91. res.Add(new OperatorMapping(PythonOperationKind.Mod, "op_Modulus", "Mod")); // %
  92. res.Add(new OperatorMapping(PythonOperationKind.ExclusiveOr, "op_ExclusiveOr", "ExclusiveOr")); // ^
  93. res.Add(new OperatorMapping(PythonOperationKind.BitwiseAnd, "op_BitwiseAnd", "BitwiseAnd")); // &
  94. res.Add(new OperatorMapping(PythonOperationKind.BitwiseOr, "op_BitwiseOr", "BitwiseOr")); // |
  95. res.Add(new OperatorMapping(PythonOperationKind.LeftShift, "op_LeftShift", "LeftShift")); // <<
  96. res.Add(new OperatorMapping(PythonOperationKind.RightShift, "op_RightShift", "RightShift")); // >>
  97. res.Add(new OperatorMapping(PythonOperationKind.Equal, "op_Equality", "Equals")); // ==
  98. res.Add(new OperatorMapping(PythonOperationKind.GreaterThan, "op_GreaterThan", "GreaterThan")); // >
  99. res.Add(new OperatorMapping(PythonOperationKind.LessThan, "op_LessThan", "LessThan")); // <
  100. res.Add(new OperatorMapping(PythonOperationKind.NotEqual, "op_Inequality", "NotEquals")); // !=
  101. res.Add(new OperatorMapping(PythonOperationKind.GreaterThanOrEqual, "op_GreaterThanOrEqual", "GreaterThanOrEqual")); // >=
  102. res.Add(new OperatorMapping(PythonOperationKind.LessThanOrEqual, "op_LessThanOrEqual", "LessThanOrEqual")); // <=
  103. res.Add(new OperatorMapping(PythonOperationKind.InPlaceMultiply, "op_MultiplicationAssignment", "InPlaceMultiply")); // *=
  104. res.Add(new OperatorMapping(PythonOperationKind.InPlaceSubtract, "op_SubtractionAssignment", "InPlaceSubtract")); // -=
  105. res.Add(new OperatorMapping(PythonOperationKind.InPlaceExclusiveOr, "op_ExclusiveOrAssignment", "InPlaceExclusiveOr")); // ^=
  106. res.Add(new OperatorMapping(PythonOperationKind.InPlaceLeftShift, "op_LeftShiftAssignment", "InPlaceLeftShift")); // <<=
  107. res.Add(new OperatorMapping(PythonOperationKind.InPlaceRightShift, "op_RightShiftAssignment", "InPlaceRightShift")); // >>=
  108. res.Add(new OperatorMapping(PythonOperationKind.InPlaceMod, "op_ModulusAssignment", "InPlaceMod")); // %=
  109. res.Add(new OperatorMapping(PythonOperationKind.InPlaceAdd, "op_AdditionAssignment", "InPlaceAdd")); // +=
  110. res.Add(new OperatorMapping(PythonOperationKind.InPlaceBitwiseAnd, "op_BitwiseAndAssignment", "InPlaceBitwiseAnd")); // &=
  111. res.Add(new OperatorMapping(PythonOperationKind.InPlaceBitwiseOr, "op_BitwiseOrAssignment", "InPlaceBitwiseOr")); // |=
  112. res.Add(new OperatorMapping(PythonOperationKind.InPlaceDivide, "op_DivisionAssignment", "InPlaceDivide")); // /=
  113. // these exist just for TypeInfo to map by name
  114. res.Add(new OperatorMapping(PythonOperationKind.GetItem, "get_Item", "GetItem")); // not defined
  115. res.Add(new OperatorMapping(PythonOperationKind.SetItem, "set_Item", "SetItem")); // not defined
  116. res.Add(new OperatorMapping(PythonOperationKind.DeleteItem, "del_Item", "DeleteItem")); // not defined
  117. // DLR Extended operators:
  118. res.Add(new OperatorMapping(PythonOperationKind.Compare, "op_Compare", "Compare", typeof(int))); // not defined
  119. res.Add(new OperatorMapping(PythonOperationKind.CallSignatures, "GetCallSignatures", null));
  120. res.Add(new OperatorMapping(PythonOperationKind.Documentation, "GetDocumentation", null));
  121. res.Add(new OperatorMapping(PythonOperationKind.IsCallable, "IsCallable", null));
  122. return res.ToArray();
  123. }
  124. }
  125. }