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

/DICK.B1/IronPython/Compiler/Ast/ListComprehension.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 108 lines | 74 code | 17 blank | 17 comment | 6 complexity | 9a9cddbd463913359b6e1b9bdca35a05 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. 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 Microsoft Public License, 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 Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System;
  16. using System.Collections.Generic;
  17. using IronPython.Runtime;
  18. #if !CLR2
  19. using MSAst = System.Linq.Expressions;
  20. #else
  21. using MSAst = Microsoft.Scripting.Ast;
  22. #endif
  23. using AstUtils = Microsoft.Scripting.Ast.Utils;
  24. namespace IronPython.Compiler.Ast {
  25. using Ast = MSAst.Expression;
  26. public abstract class ListComprehensionIterator : Node {
  27. internal abstract MSAst.Expression Transform(MSAst.Expression body);
  28. }
  29. public class ListComprehension : Expression {
  30. private readonly Expression _item;
  31. private readonly ListComprehensionIterator[] _iterators;
  32. public ListComprehension(Expression item, ListComprehensionIterator[] iterators) {
  33. _item = item;
  34. _iterators = iterators;
  35. }
  36. public Expression Item {
  37. get { return _item; }
  38. }
  39. public IList<ListComprehensionIterator> Iterators {
  40. get { return _iterators; }
  41. }
  42. public override MSAst.Expression Reduce() {
  43. MSAst.ParameterExpression list = Ast.Parameter(typeof(List), "list_comprehension_list");
  44. // 1. Initialization code - create list and store it in the temp variable
  45. MSAst.Expression initialize =
  46. Ast.Assign(
  47. list,
  48. Ast.Call(AstMethods.MakeList)
  49. );
  50. // 2. Create body from _item: list.Append(_item)
  51. MSAst.Expression body = GlobalParent.AddDebugInfo(
  52. Ast.Call(
  53. AstMethods.ListAddForComprehension,
  54. list,
  55. AstUtils.Convert(_item, typeof(object))
  56. ),
  57. _item.Span
  58. );
  59. // 3. Transform all iterators in reverse order, building the true body:
  60. int current = _iterators.Length;
  61. while (current-- > 0) {
  62. ListComprehensionIterator iterator = _iterators[current];
  63. body = iterator.Transform(body);
  64. }
  65. return Ast.Block(
  66. new[] { list },
  67. initialize,
  68. body,
  69. list // result
  70. );
  71. }
  72. public override string NodeName {
  73. get {
  74. return "list comprehension";
  75. }
  76. }
  77. public override void Walk(PythonWalker walker) {
  78. if (walker.Walk(this)) {
  79. if (_item != null) {
  80. _item.Walk(walker);
  81. }
  82. if (_iterators != null) {
  83. foreach (ListComprehensionIterator lci in _iterators) {
  84. lci.Walk(walker);
  85. }
  86. }
  87. }
  88. walker.PostWalk(this);
  89. }
  90. }
  91. }