[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