[Ironpython-users] Modifying ASTs when embedding IronPython

Dino Viehland dinov at microsoft.com
Fri Mar 2 01:57:56 CET 2012


Yep, but all of the main IronPython nodes will show up as an extension node so you'll want to override VisitExtension instead of VisitBinary.  VisitBinary is for simple binary operations such as adding two primitive values and doesn't include dynamic binary operations.

From: ironpython-users-bounces+dinov=microsoft.com at python.org [mailto:ironpython-users-bounces+dinov=microsoft.com at python.org] On Behalf Of Tuomas Utrecht
Sent: Thursday, March 01, 2012 4:01 PM
To: ironpython-users at python.org
Subject: Re: [Ironpython-users] Modifying ASTs when embedding IronPython

Ok, I'm going to read up on this, but to confirm, I'd need something like the following (from reading http://stackoverflow.com/questions/7944521/interrupt-interpreted-user-code-in-silverlight)?

public class ExpressionRewriter : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {
            ...
    }
}

ExpressionVisitor comes from System.Linq.Expressions? I see BinaryExpression in both System.Linq.Expressions and IronPython.Compiler.Ast. I don't see that I can override the above unless I use the Linq one. I will look into Ipy's code further, but I thought I'd pose these questions.

Thank you for your guidance.
Le 1 mars 2012 16:58, Dino Viehland <dinov at microsoft.com<mailto:dinov at microsoft.com>> a écrit :
The ASTs are generally immutable so to re-write you'll create a copy of the AST and any parent nodes.  The ExpressionVisitor class makes this easy in that you can override VisitExtension method and re-write any Python nodes you care about there.  You return a modified node somewhere within the tree and then the rest of the tree will be re-written for you and you get it back out after the visitor completes.

Overall I'd say you might be able to make this work, but you might also hit a wall and need to tweak Ipy a little bit so you can actually compile the re-written code in a useful way.  I'm thinking you might start running into internal APIs when you start trying to create a ScriptCode or compile it, but I'm not 100% certain.

From: ironpython-users-bounces+dinov=exchange.microsoft.com at python.org<mailto:exchange.microsoft.com at python.org> [mailto:ironpython-users-bounces+dinov<mailto:ironpython-users-bounces%2Bdinov>=exchange.microsoft.com at python.org<mailto:exchange.microsoft.com at python.org>] On Behalf Of Tuomas Utrecht
Sent: Thursday, March 01, 2012 12:32 PM
To: ironpython-users at python.org<mailto:ironpython-users at python.org>
Subject: [Ironpython-users] Modifying ASTs when embedding IronPython

Hello,

I apologize if this has been answered elsewhere, but I am unable to find anything up to date, or that covers my question in particular.

The short version is: Can I modify the AST of a parsed file before compiling/executing in an embedded context? I want to allow simple, Excel-like statements to be executed from a .NET application. One major hitch is that Excel uses ^ for power whereas Python uses **. Ideally, I would be able to catch calls to ^ and replace with ** at compile time.

If this is just not possible without rebuilding IronPython, do let me know.

I have gotten as far as the below, although the BinaryExpression node's Operator is only gettable. I also am unsure how to take an AST and compile it, or if that is even public/allowed.

    var engine = Python.CreateEngine();
    var s = HostingHelpers.GetSourceUnit(engine.CreateScriptSourceFromString("3^4"));
    var cc = new CompilerContext(s, new PythonCompilerOptions(), ErrorSink.Default);
    var p = Parser.CreateParser(cc, new PythonOptions());
    PythonAst ast = p.ParseFile(false);

    // I originally tried this with a PythonWalker, but this is more succinct for the purpose of this example
    SuiteStatement body = (SuiteStatement)ast.Body;
    ExpressionStatement st = (ExpressionStatement)body.Statements[0];
    BinaryExpression exp = (BinaryExpression) st.Expression;
    //exp.Operator = PythonOperator.Power; // Were it only so easy...


Thanks for reading!

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20120302/cdff7dcb/attachment.html>


More information about the Ironpython-users mailing list