[IronPython] Building via AST

Dino Viehland dinov at microsoft.com
Tue Apr 13 00:20:08 CEST 2010


Yes – there is the TypeGen class but really it’s just a thin wrapper around TypeBuilder w/ some helper APIs.  If we were to implement it today it might just be extension methods instead of a wrapper class.

Unfortunately there is currently no way to go from an expression tree to an instance method.  It’s on the top of the things to fix in the DLR for a future .NET release.  It’s sad that it hasn’t been solved yet but that is the state of the world.  If you really wanted to get crazy you could look at forking the DLR expression tree compiler and adding support ☺

As far as how Python does this – we do generate classes and we do this via our NewTypeMaker class.  But the IL that we create is rather minimal.  We just derive and override every virtual method and have it dispatch either to the method defined in a PythonType type (which is stored as an instance field in the object).  So while it sucks that we need to generate the IL by hand it’s small enough that it’s not a big deal.

From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Justin Chase
Sent: Monday, April 12, 2010 2:03 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Building via AST

Ok so I'm wondering if I'm perhaps using the wrong words to try to say what I mean. Because when I look into the IronPython source code I see a class called Microsoft.Scripting.Generation.TypeGen (http://ironpython.codeplex.com/SourceControl/changeset/view/65328#1011039). Which appears to be code for generating a .net type contrary to your response. Am I misinterpreting that?

Thanks for your examples below but that is about as far as I have gotten already, what I need is a way to actually generate types and instances members. And I was just looking at the ILGen class and all it's interesting helpers but what I'd really love to find is a way to generate this by just giving it an AST (including "this" references) instead of having to mess around with IL (hasn't this been solved already??).

I know that Python has a "class" construct and that if I compile scripts I can create instances of these objects, does this translate into actual .net types under the hood? Or something else? Can you add attributes or annotations to these classes for example? For my grand finale what I would really like to do is to generate types that implement interfaces and load them via MEF (by means of the Export attribute). Is this just the wrong way to be thinking about this entirely? Or am I just missing something?


On Mon, Apr 12, 2010 at 3:33 PM, Dino Viehland <dinov at microsoft.com<mailto:dinov at microsoft.com>> wrote:
Nope – the DLR doesn’t have any support for building .NET types – dynamic or otherwise.  If you’d like to just build an object which behaves dynamically I’d suggest looking at DynamicObject.  You can just subclass it and override various Try* methods and you’ll have a dynamic object.

If you really do need to do ILGen into a type, and as long as you’re building only static methods, you can use expression trees via Lambda<T>.CompileToMethod (unfortunately currently instance methods are not supported).  Here’s an example of that:

using System;
using System.Linq.Expressions;
using System.Reflection;

class Foo {
    public static void Main(string[] args) {
        var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("foo"), System.Reflection.Emit.AssemblyBuilderAccess.Save);
        var module = asm.DefineDynamicModule("foo.dll");
        var type = module.DefineType("TestType");

        var param1 = Expression.Parameter(typeof(Foox), "arg1");
        var param2 = Expression.Parameter(typeof(Foox), "arg2");
        var method = type.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static);

        Expression.Lambda<Func<Foox, Foox, bool>>(
            Expression.Equal(param1, param2),
            new[] { param1, param2 }
        ).CompileToMethod(method);
        type.CreateType();
        asm.Save("foo.dll");
    }
}
enum Foox {
    Bar,
    Baz
}

From: users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com> [mailto:users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com>] On Behalf Of Justin Chase
Sent: Monday, April 12, 2010 1:21 PM
To: users at lists.ironpython.com<mailto:users at lists.ironpython.com>
Subject: [IronPython] Building via AST

Suppose I would like to build an AST programmatically and compile that into an assembly dynamically (meaning an assembly flagged with RunAndCollect) from C#. How would I do that with IronPython's help? I do not what to author Python code and compile that I would like to just deal directly with the AST.

Currently I have working code where I'm using System.Linq.Expression namespace to build statements and expressions into delegates but what I would like is to leverage the DLR to build dynamic types as well (without having to use ILGenerator preferably). Is this possible today?

--
Justin Chase
http://www.justnbusiness.com

_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



--
Justin Chase
http://www.justnbusiness.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20100412/6b54ca63/attachment.html>


More information about the Ironpython-users mailing list