PageRenderTime 62ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Boo.Lang.Compiler/Ast/CodeSerializer.cs

https://github.com/boo/boo-lang
C# | 258 lines | 194 code | 39 blank | 25 comment | 11 complexity | 8f336d733c697334ed1dd78506ef7327 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 System.Collections.Generic;
  30. namespace Boo.Lang.Compiler.Ast
  31. {
  32. public partial class CodeSerializer : DepthFirstVisitor
  33. {
  34. public static string LiftName(string value)
  35. {
  36. return value;
  37. }
  38. public static string LiftName(ReferenceExpression node)
  39. {
  40. return node.Name;
  41. }
  42. private Stack<Expression> _stack = new Stack<Expression>();
  43. public Expression Serialize(QuasiquoteExpression node)
  44. {
  45. Expression e = Serialize(node.Node);
  46. if (_stack.Count != 0) throw new InvalidOperationException();
  47. return e;
  48. }
  49. public Expression Serialize(Node node)
  50. {
  51. if (null == node) return new NullLiteralExpression();
  52. node.Accept(this);
  53. return _stack.Pop();
  54. }
  55. public Expression CreateReference(Node sourceNode, string qname)
  56. {
  57. return AstUtil.CreateReferenceExpression(sourceNode.LexicalInfo, qname);
  58. }
  59. public Expression CreateReference(string qname)
  60. {
  61. return AstUtil.CreateReferenceExpression(qname);
  62. }
  63. public bool ShouldSerialize<T>(NodeCollection<T> c) where T: Node
  64. {
  65. return c.Count > 0;
  66. }
  67. public bool ShouldSerialize(object value)
  68. {
  69. return value != null;
  70. }
  71. public Expression Serialize(string value)
  72. {
  73. return new StringLiteralExpression(value);
  74. }
  75. public Expression Serialize(bool value)
  76. {
  77. return new BoolLiteralExpression(value);
  78. }
  79. public Expression Serialize(long value)
  80. {
  81. return new IntegerLiteralExpression(value);
  82. }
  83. public Expression Serialize(double value)
  84. {
  85. return new DoubleLiteralExpression(value);
  86. }
  87. public Expression Serialize(TimeSpan value)
  88. {
  89. return new TimeSpanLiteralExpression(value);
  90. }
  91. private Expression SerializeEnum(string enumType, long value)
  92. {
  93. return new CastExpression(
  94. Serialize(value),
  95. new SimpleTypeReference("Boo.Lang.Compiler.Ast." + enumType));
  96. }
  97. protected Expression SerializeCollection(Node sourceNode, string typeName, StatementCollection items)
  98. {
  99. MethodInvocationExpression mie = CreateFromArrayInvocation(sourceNode, typeName);
  100. foreach (Statement item in items)
  101. {
  102. mie.Arguments.Add(LiftStatement(Serialize(item)));
  103. }
  104. return mie;
  105. }
  106. private MethodInvocationExpression CreateFromArrayInvocation(Node sourceNode, string typeName)
  107. {
  108. return CreateInvocation(sourceNode, typeName + ".FromArray");
  109. }
  110. protected Expression SerializeCollection(Node sourceNode, string typeName, System.Collections.IEnumerable items)
  111. {
  112. MethodInvocationExpression mie = CreateFromArrayInvocation(sourceNode, typeName);
  113. foreach (Node item in items)
  114. {
  115. mie.Arguments.Add(Serialize(item));
  116. }
  117. return mie;
  118. }
  119. public override void OnExpressionStatement(ExpressionStatement node)
  120. {
  121. Visit(node.Expression);
  122. if (null != node.Modifier)
  123. {
  124. Visit(node.Modifier);
  125. MethodInvocationExpression ctor = CreateInvocation(node, "Boo.Lang.Compiler.Ast.ExpressionStatement");
  126. ctor.NamedArguments.Add(Pair("Modifier", Pop()));
  127. ctor.NamedArguments.Add(Pair("Expression", Pop()));
  128. Push(ctor);
  129. }
  130. }
  131. public override void OnOmittedExpression(OmittedExpression node)
  132. {
  133. Push(CreateReference(node, "Boo.Lang.Compiler.Ast.OmittedExpression.Default"));
  134. }
  135. public override void OnSpliceMemberReferenceExpression(SpliceMemberReferenceExpression node)
  136. {
  137. MethodInvocationExpression ctor = CreateInvocation(node, "Boo.Lang.Compiler.Ast.MemberReferenceExpression");
  138. ctor.Arguments.Add(Serialize(node.Target));
  139. ctor.Arguments.Add(LiftMemberName(node.NameExpression));
  140. Push(ctor);
  141. }
  142. public override void OnSpliceTypeMember(SpliceTypeMember node)
  143. {
  144. MethodInvocationExpression ctor = (MethodInvocationExpression)Serialize(node.TypeMember);
  145. SpliceName(ctor, node.NameExpression);
  146. Push(ctor);
  147. }
  148. private void SpliceName(MethodInvocationExpression ctor, Expression nameExpression)
  149. {
  150. ctor.NamedArguments.Add(Pair("Name", LiftMemberName(nameExpression)));
  151. }
  152. private ExpressionPair Pair(string name, Expression e)
  153. {
  154. return new ExpressionPair(
  155. new ReferenceExpression(e.LexicalInfo, name),
  156. e);
  157. }
  158. public override void OnSpliceParameterDeclaration(SpliceParameterDeclaration node)
  159. {
  160. MethodInvocationExpression ctor = (MethodInvocationExpression)Serialize(node.ParameterDeclaration);
  161. SpliceName(ctor, node.NameExpression);
  162. Push(ctor);
  163. }
  164. public override void OnSpliceTypeReference(SpliceTypeReference node)
  165. {
  166. Push(LiftTypeReference(node.Expression));
  167. }
  168. public override void OnSpliceExpression(SpliceExpression node)
  169. {
  170. if (IsStatementExpression(node))
  171. {
  172. Push(LiftStatement(node.Expression));
  173. return;
  174. }
  175. Push(LiftExpression(node.Expression));
  176. }
  177. private MethodInvocationExpression LiftMemberName(Expression node)
  178. {
  179. return Lift("Boo.Lang.Compiler.Ast.CodeSerializer.LiftName", node);
  180. }
  181. private MethodInvocationExpression LiftStatement(Expression node)
  182. {
  183. return Lift("Boo.Lang.Compiler.Ast.Statement.Lift", node);
  184. }
  185. private MethodInvocationExpression LiftExpression(Expression node)
  186. {
  187. return Lift("Boo.Lang.Compiler.Ast.Expression.Lift", node);
  188. }
  189. private MethodInvocationExpression LiftTypeReference(Expression node)
  190. {
  191. return Lift("Boo.Lang.Compiler.Ast.TypeReference.Lift", node);
  192. }
  193. private MethodInvocationExpression Lift(string methodName, Expression node)
  194. {
  195. MethodInvocationExpression lift = CreateInvocation(node, methodName);
  196. lift.Arguments.Add(node);
  197. return lift;
  198. }
  199. private MethodInvocationExpression CreateInvocation(Node sourceNode, string reference)
  200. {
  201. return new MethodInvocationExpression(
  202. sourceNode.LexicalInfo,
  203. CreateReference(sourceNode, reference));
  204. }
  205. private static bool IsStatementExpression(SpliceExpression node)
  206. {
  207. if (node.ParentNode == null) return false;
  208. return node.ParentNode.NodeType == NodeType.ExpressionStatement;
  209. }
  210. private void Push(Expression node)
  211. {
  212. _stack.Push(node);
  213. }
  214. private Expression Pop()
  215. {
  216. return _stack.Pop();
  217. }
  218. }
  219. }