[IronPython] Building via AST

Justin Chase justin.m.chase at gmail.com
Tue Apr 13 01:09:02 CEST 2010


Ok, so at risk of being a nuissance I have one last question because I feel
like I'm half way there. I have the following example that seems to work:

# sample.py
from ConsoleApplication4 import IExample

class Example(IExample):
test = "hello python"
def Do(self):
return self.test

# program.cs
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
var runtime = Python.CreateRuntime();
runtime.LoadAssembly(typeof(IExample).Assembly);

dynamic python = runtime.UseFile("sample.py");
IExample example = (IExample)python.Example();

Console.WriteLine(example.Do());
Console.ReadKey(true);
}
}

public interface IExample
{
string Do();
}
}

Which prints out "hello python" as expected and is the *exact *behavior I
would like to have. So now, say I did this instead:

# program.cs
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
var runtime = Python.CreateRuntime();
runtime.LoadAssembly(typeof(IExample).Assembly);

var import = new IronPython.Compiler.Ast.ImportStatement(
new[] { new ModuleName(new[] { "ConsoleApplication4" }) },
new[] { "IExample" },
false);

var classDefinition = new IronPython.Compiler.Ast.ClassDefinition("Example",
new Expression[] { new NameExpression("IExample") },
new FunctionDefinition(
"Do",
new[] { new Parameter("self") },
new ReturnStatement(new ConstantExpression("hello python!"))));

*// TODO: Compile the above AST into something!*
* **dynamic python = null;*

IExample example = (IExample)python.Example();
Console.WriteLine(example.Do());

Console.ReadKey(true);
}
}

public interface IExample
{
string Do();
}
}

Is there anyway to fill in the line below the TODO such that I will get the
exact same behavior as the first example? If you say no this time then I'll
finally stop asking you questions (except maybe why not :-P). If you do say
no this time, then I might be interested in trying to extend things such
that it is possible.


On Mon, Apr 12, 2010 at 5:20 PM, Dino Viehland <dinov at microsoft.com> wrote:

>  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 J
>
>
>
> 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>
> 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] *On Behalf Of *Justin Chase
> *Sent:* Monday, April 12, 2010 1:21 PM
> *To:* 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
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>
>
>
>
> --
> Justin Chase
> http://www.justnbusiness.com
>
> _______________________________________________
> Users mailing list
> 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/a15a8bed/attachment.html>


More information about the Ironpython-users mailing list