[Ironpython-users] Modifying ASTs when embedding IronPython

Dino Viehland dinov at microsoft.com
Thu Mar 1 22:58:15 CET 2012

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:ironpython-users-bounces+dinov=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
Subject: [Ironpython-users] Modifying ASTs when embedding IronPython


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/20120301/e0250440/attachment.html>

More information about the Ironpython-users mailing list