DLR の AST 取得
IronPython 2.0 がβ4になって、AST が System.Linq.Expressions 名前空間に移動したことだし、前に作った式木の階層構造を WPF で GUI 表示ってのの DLR AST 版を作りたいなぁとか思ったり思わなかったり。
とか思いながら、DLR を触ってみたんですけども、動的にコード実行はできても、中間生成物の AST を取れないんですね。普通の方法では。調べ足りてないだけ?それなりに探してみた感じとしては、internal プロパティに無理やりアクセスしないと取得できなかったんですけど。以下のような感じで。
using System; using System.Scripting; using Microsoft.Scripting.Hosting; using System.Reflection; class Program { static void Main(string[] args) { var engine = ScriptRuntime.Create().GetEngine("py"); var source = engine.CreateScriptSourceFromString("x + y"); var scope = engine.CreateScope(); scope.SetVariable("x", 2); scope.SetVariable("y", 3); //↓中間生成物の System.Linq.Expressions.LambdaExpression を取得 // (internal なプロパティの値を無理やり取得) var t = typeof(ScriptSource); var prop = typeof(ScriptSource) .GetProperty("SourceUnit", BindingFlags.NonPublic | BindingFlags.Instance); SourceUnit unit = (SourceUnit)prop.GetValue(source, null); var code = unit.Compile(); var lambda = code.Code; //↑ここまで int result = (int)source.Execute(scope); Console.Write(result); } }
(IronPython 2.0 β4 をインストールして、IronPython がらみの DLL を参照すれば動くはず。)
あと、たった1式「x + y」って書くだけで、生成される AST は結構でかいんですね・・・。ScopeExpression とか Block とか TryStatement とかが追加されちゃってて、「x + y」の部分だけ取り出せないっぽい。
DLR を C# 3.0 のラムダ式×System.Linq.Expressions 式木の代わりに使うのは無理がありそう。4.0 に期待しながら待つしかないのか・・・。