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

Reply via email to