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

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

https://github.com/w4x/boolangstudio
C# | 246 lines | 183 code | 38 blank | 25 comment | 9 complexity | 07ba4b5db8b26c2faf66173d45bfb190 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. }
  123. public override void OnOmittedExpression(OmittedExpression node)
  124. {
  125. Push(CreateReference(node, "Boo.Lang.Compiler.Ast.OmittedExpression.Default"));
  126. }
  127. public override void OnSpliceMemberReferenceExpression(SpliceMemberReferenceExpression node)
  128. {
  129. MethodInvocationExpression ctor = CreateInvocation(node, "Boo.Lang.Compiler.Ast.MemberReferenceExpression");
  130. ctor.Arguments.Add(Serialize(node.Target));
  131. ctor.Arguments.Add(LiftMemberName(node.NameExpression));
  132. Push(ctor);
  133. }
  134. public override void OnSpliceTypeMember(SpliceTypeMember node)
  135. {
  136. MethodInvocationExpression ctor = (MethodInvocationExpression)Serialize(node.TypeMember);
  137. SpliceName(ctor, node.NameExpression);
  138. Push(ctor);
  139. }
  140. private void SpliceName(MethodInvocationExpression ctor, Expression nameExpression)
  141. {
  142. ctor.NamedArguments.Add(
  143. new ExpressionPair(
  144. new ReferenceExpression(nameExpression.LexicalInfo, "Name"),
  145. LiftMemberName(nameExpression)));
  146. }
  147. public override void OnSpliceParameterDeclaration(SpliceParameterDeclaration node)
  148. {
  149. MethodInvocationExpression ctor = (MethodInvocationExpression)Serialize(node.ParameterDeclaration);
  150. SpliceName(ctor, node.NameExpression);
  151. Push(ctor);
  152. }
  153. public override void OnSpliceTypeReference(SpliceTypeReference node)
  154. {
  155. Push(LiftTypeReference(node.Expression));
  156. }
  157. public override void OnSpliceExpression(SpliceExpression node)
  158. {
  159. if (IsStatementExpression(node))
  160. {
  161. Push(LiftStatement(node.Expression));
  162. return;
  163. }
  164. Push(LiftExpression(node.Expression));
  165. }
  166. private MethodInvocationExpression LiftMemberName(Expression node)
  167. {
  168. return Lift("Boo.Lang.Compiler.Ast.CodeSerializer.LiftName", node);
  169. }
  170. private MethodInvocationExpression LiftStatement(Expression node)
  171. {
  172. return Lift("Boo.Lang.Compiler.Ast.Statement.Lift", node);
  173. }
  174. private MethodInvocationExpression LiftExpression(Expression node)
  175. {
  176. return Lift("Boo.Lang.Compiler.Ast.Expression.Lift", node);
  177. }
  178. private MethodInvocationExpression LiftTypeReference(Expression node)
  179. {
  180. return Lift("Boo.Lang.Compiler.Ast.TypeReference.Lift", node);
  181. }
  182. private MethodInvocationExpression Lift(string methodName, Expression node)
  183. {
  184. MethodInvocationExpression lift = CreateInvocation(node, methodName);
  185. lift.Arguments.Add(node);
  186. return lift;
  187. }
  188. private MethodInvocationExpression CreateInvocation(Node sourceNode, string reference)
  189. {
  190. return new MethodInvocationExpression(
  191. sourceNode.LexicalInfo,
  192. CreateReference(sourceNode, reference));
  193. }
  194. private static bool IsStatementExpression(SpliceExpression node)
  195. {
  196. if (node.ParentNode == null) return false;
  197. return node.ParentNode.NodeType == NodeType.ExpressionStatement;
  198. }
  199. private void Push(Expression node)
  200. {
  201. _stack.Push(node);
  202. }
  203. private Expression Pop()
  204. {
  205. return _stack.Pop();
  206. }
  207. }
  208. }