PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Dependencies/boo/src/Boo.Lang.Compiler/Steps/UnfoldConstants.cs

https://github.com/w4x/boolangstudio
C# | 214 lines | 155 code | 32 blank | 27 comment | 36 complexity | 14a3b68ad2dca08b30df76078be9481e MD5 | raw file
Possible License(s): GPL-2.0
  1. #region license
  2. // Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without modification,
  6. // are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of Rodrigo B. de Oliveira nor the names of its
  14. // contributors may be used to endorse or promote products derived from this
  15. // software without specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  21. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #endregion
  28. using System;
  29. using Boo.Lang.Compiler.Ast;
  30. using Boo.Lang.Compiler.TypeSystem;
  31. namespace Boo.Lang.Compiler.Steps
  32. {
  33. /// <summary>
  34. /// </summary>
  35. public class UnfoldConstants : AbstractTransformerCompilerStep
  36. {
  37. public UnfoldConstants()
  38. {
  39. }
  40. public override void Run()
  41. {
  42. if (Errors.Count > 0) return;
  43. Visit(CompileUnit);
  44. }
  45. public override void LeaveBinaryExpression(BinaryExpression node)
  46. {
  47. switch (node.Operator)
  48. {
  49. case BinaryOperatorType.BitwiseOr:
  50. LeaveBitwiseOr(node);
  51. break;
  52. case BinaryOperatorType.BitwiseAnd:
  53. LeaveBitwiseAnd(node);
  54. break;
  55. case BinaryOperatorType.Addition:
  56. LeaveAddition(node);
  57. break;
  58. case BinaryOperatorType.Subtraction:
  59. LeaveSubtraction(node);
  60. break;
  61. case BinaryOperatorType.ExclusiveOr:
  62. LeaveExclusiveOr(node);
  63. break;
  64. }
  65. }
  66. private object GetLiteral(Expression expression)
  67. {
  68. switch (expression.NodeType)
  69. {
  70. case NodeType.CastExpression:
  71. return GetLiteral(((CastExpression)expression).Target);
  72. case NodeType.IntegerLiteralExpression:
  73. return ((IntegerLiteralExpression)expression).Value;
  74. }
  75. IField field = TypeSystemServices.GetOptionalEntity(expression) as IField;
  76. if (field == null) return null;
  77. if (!field.IsLiteral) return null;
  78. return field.StaticValue;
  79. }
  80. private void LeaveBitwiseOr(BinaryExpression node)
  81. {
  82. IType type = TypeSystemServices.GetExpressionType(node);
  83. if (!type.IsEnum) return;
  84. object lhs = GetLiteral(node.Left);
  85. if (null == lhs) return;
  86. object rhs = GetLiteral(node.Right);
  87. if (null == rhs) return;
  88. ReplaceCurrentNode(
  89. CodeBuilder.CreateCast(type,
  90. CodeBuilder.CreateIntegerLiteral(GetLongValue(rhs)|GetLongValue(lhs))));
  91. }
  92. private void LeaveBitwiseAnd(BinaryExpression node)
  93. {
  94. IType type = TypeSystemServices.GetExpressionType(node);
  95. if (!type.IsEnum) return;
  96. object lhs = GetLiteral(node.Left);
  97. if (null == lhs) return;
  98. object rhs = GetLiteral(node.Right);
  99. if (null == rhs) return;
  100. ReplaceCurrentNode(
  101. CodeBuilder.CreateCast(type,
  102. CodeBuilder.CreateIntegerLiteral(GetLongValue(rhs)&GetLongValue(lhs))));
  103. }
  104. private void LeaveAddition(BinaryExpression node)
  105. {
  106. IType type = TypeSystemServices.GetExpressionType(node);
  107. if (!type.IsEnum) return;
  108. object lhs = GetLiteral(node.Left);
  109. if (null == lhs) return;
  110. object rhs = GetLiteral(node.Right);
  111. if (null == rhs) return;
  112. ReplaceCurrentNode(
  113. CodeBuilder.CreateCast(type,
  114. CodeBuilder.CreateIntegerLiteral(GetLongValue(lhs)+GetLongValue(rhs))));
  115. }
  116. private void LeaveSubtraction(BinaryExpression node)
  117. {
  118. IType type = TypeSystemServices.GetExpressionType(node);
  119. if (!type.IsEnum) return;
  120. object lhs = GetLiteral(node.Left);
  121. if (null == lhs) return;
  122. object rhs = GetLiteral(node.Right);
  123. if (null == rhs) return;
  124. ReplaceCurrentNode(
  125. CodeBuilder.CreateCast(type,
  126. CodeBuilder.CreateIntegerLiteral(GetLongValue(lhs)-GetLongValue(rhs))));
  127. }
  128. private void LeaveExclusiveOr(BinaryExpression node)
  129. {
  130. IType type = TypeSystemServices.GetExpressionType(node);
  131. if (!type.IsEnum) return;
  132. object lhs = GetLiteral(node.Left);
  133. if (null == lhs) return;
  134. object rhs = GetLiteral(node.Right);
  135. if (null == rhs) return;
  136. ReplaceCurrentNode(
  137. CodeBuilder.CreateCast(type,
  138. CodeBuilder.CreateIntegerLiteral(GetLongValue(rhs)^GetLongValue(lhs))));
  139. }
  140. private long GetLongValue(object o)
  141. {
  142. return (long) Convert.ChangeType(o, typeof(long));
  143. }
  144. public override void LeaveUnaryExpression(Boo.Lang.Compiler.Ast.UnaryExpression node)
  145. {
  146. switch (node.Operator)
  147. {
  148. case UnaryOperatorType.UnaryNegation:
  149. {
  150. LeaveUnaryNegation(node);
  151. break;
  152. }
  153. case UnaryOperatorType.OnesComplement:
  154. {
  155. LeaveOnesCompliment(node);
  156. break;
  157. }
  158. }
  159. }
  160. private void LeaveUnaryNegation(UnaryExpression node)
  161. {
  162. Expression operand = node.Operand;
  163. switch (operand.NodeType)
  164. {
  165. case NodeType.IntegerLiteralExpression:
  166. (operand as IntegerLiteralExpression).Value *= -1;
  167. ReplaceCurrentNode(operand);
  168. break;
  169. }
  170. }
  171. private void LeaveOnesCompliment(UnaryExpression node)
  172. {
  173. IType type = TypeSystemServices.GetExpressionType(node);
  174. if (!type.IsEnum) return;
  175. object operand = GetLiteral(node.Operand);
  176. if (null == operand) return;
  177. ReplaceCurrentNode(
  178. CodeBuilder.CreateCast(type,
  179. CodeBuilder.CreateIntegerLiteral(~GetLongValue(operand))));
  180. }
  181. }
  182. }