On Mon, Oct 13, 2008 at 3:50 PM, Dino Viehland <[EMAIL PROTECTED]> wrote: > In the mean time I would assume you just need the FunctionDefinition and > Expression exposed off of GeneratorExpression. Is that right or is it > something else? I should be able to do that for RC1. >
That's initially what I did, but exposing an optimization in a public interface did not sit well with me. I thought ideally it should offer the same public interface as a ListComprehension node, so I implemented that. Benefit is it provides a consistent interface to users of the IronPython ast (me included). I'm attaching the modified .cs file here, you can use it as a reference if you decide to take that approach. > For compile I think you could back-patch the built-in modules. You can add a > [SpecialName] void PerformModuleReload(PythonContext, IAttributeCollection) > method to your module to know when it gets imported/reloaded and you can then > patch builtin.compile with a version of your own which calls the built-in > version. I like the sound of that. It could be possible for people to use _ast with an official IronPython 2.0 distribution. I've seen the PerformModuleReload around in the source code, but I'm not clear on how to replace the builtin compile from there. If you could give me a brief example I can fix my code to work that way. Thanks, -Dan
/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * [EMAIL PROTECTED] By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System; using Microsoft; using System.Collections.Generic; using System.Diagnostics; using IronPython.Runtime; using IronPython.Runtime.Binding; using Microsoft.Scripting.Actions; using MSAst = Microsoft.Linq.Expressions; namespace IronPython.Compiler.Ast { public class GeneratorExpression : Expression { private readonly FunctionDefinition _function; private readonly Expression _iterable; public GeneratorExpression(FunctionDefinition function, Expression iterable) { _function = function; _iterable = iterable; } public Expression Item { get { ExtractYield walker = new ExtractYield(); _function.Walk(walker); return walker.Yield.Expression; } } public ListComprehensionIterator[] Iterators { get { ExtractListComprehensionIterators walker = new ExtractListComprehensionIterators(); _function.Body.Walk(walker); ListComprehensionIterator[] iters = walker.Iterators; Debug.Assert(iters.Length != 0, "A generator expression cannot have zero iterators."); iters[0] = new ListComprehensionFor(((ListComprehensionFor) iters[0]).Left, _iterable); return iters; } } internal override MSAst.Expression Transform(AstGenerator ag, Type type) { MSAst.Expression func = _function.TransformToFunctionExpression(ag); Debug.Assert(func.Type == typeof(PythonFunction)); // Generator expressions always return functions. We could do even better here when all PythonFunction's are in the same class. return Binders.Invoke( ag.BinderState, typeof(object), new CallSignature(1), func, ag.TransformAsObject(_iterable) ); } public override void Walk(PythonWalker walker) { if (walker.Walk(this)) { _function.Walk(walker); _iterable.Walk(walker); } walker.PostWalk(this); } } internal class ExtractYield : PythonWalker { public YieldExpression Yield; public override bool Walk(YieldExpression node) { Yield = node; return false; } } internal class ExtractListComprehensionIterators : PythonWalker { private readonly List<ListComprehensionIterator> _iterators = new List<ListComprehensionIterator>(); public ListComprehensionIterator[] Iterators { get { return _iterators.ToArray(); } } public override bool Walk(ForStatement node) { _iterators.Add(new ListComprehensionFor(node.Left, node.List)); node.Body.Walk(this); return false; } public override bool Walk(IfStatement node) { _iterators.Add(new ListComprehensionIf(node.Tests[0].Test)); node.Tests[0].Body.Walk(this); return false; } } }
_______________________________________________ Users mailing list Users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com