Expression tree from IronPython - linq

I use this code to execute a python expression using IronPython.
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
scope.SetVariable("m", mobject);
string code = "m.ID > 5 and m.ID < 10";
ScriptSource source =
engine.CreateScriptSourceFromString(code, SourceCodeKind.Expression);
source.Execute(scope);
Is there a way to get the produced Expression Tree as c# object, e.g. the BlockExpression
?

IronPython's internal ASTs also happen to be Expression trees, so you just need to get the AST for your code, which you can do using the IronPython.Compiler.Parser class. The Parser.ParseFile method will return a IronPython.Compiler.Ast.PythonAst instance representing the code.
Using the parser is a bit tricky, but you can look at the BuildAst method of the _ast module for some hints. Basically, it's:
Parser parser = Parser.CreateParser(
new CompilerContext(sourceUnit, opts, ThrowingErrorSink.Default),
(PythonOptions)context.LanguageContext.Options);
PythonAst ast = parser.ParseFile(true);
ThrowingErrorSink also comes from the _ast module. You can get a SourceUnit instance like so (c.f. compile builtin):
SourceUnit sourceUnit = context.LanguageContext.CreateSnippet(source, filename, SourceCodeKind.Statements);
You then have to walk the AST to get useful information out of it, but they should be similar (but not identical to) C# expression trees.

Related

Converting C# Expression Parsing to F#

As a newbie to F#, I routinely try to convert bits of C# over as a learning exercise. In this case, I am trying to convert the following C# expression parsing code. It's simple, the idea is to pass a lambda into this function to get the string representation of a property name, rather than using standard reflection techniques. I have omitted the other GetMemberName function as I think I can figure it out once I get some guidance on what approach to take.
public static string GetMemberName<T>(Expression<Func<T, object>> expression)
{
if (expression == null)
{
throw new ArgumentException("The expression cannot be null.");
}
return GetMemberName(expression.Body);
}
I know that F# has quotations. I also know I could use Linq Expressions in F#. I would like to try it the F# way first using quotations, but I am stumbling. Could someone give me a kickstart?
I'm not sure if an exact translation of this is possible using quotations because quotations have a different shape than C# expressions. However, here's something along the same lines:
open Microsoft.FSharp.Quotations.Patterns
let GetMemberName = function
| Call (_,methodInfo,_) -> methodInfo.Name
| PropertyGet (_,propertyInfo,_) -> propertyInfo.Name
| _ -> failwith "Not a member expression"
GetMemberName <# [].IsEmpty #>
// val it : string = "IsEmpty"

How to parse Ruby Code using IronRuby?

I am new to IronRuby. I am trying to integrate it with C#.
I have created following example and it is working fine.
string rubyCode = #"
def function_111(test)
print 1
end
";
ScriptEngine engine = Ruby.CreateEngine();
ScriptScope scope = engine.CreateScope();
engine.Execute(rubyCode, scope);
dynamic sayHelloFun = scope.GetVariable("function_111");
sayHelloFun("test");
If you look at above code then I am using execute method that compile and execute code but instead of that I only want to parse code it means its syntax are correct or not.
How can that possible ?
The link posted appears dead, and the search engine cache copies appear to be rotting, so I'm going to scrape what is left of the post and interpret it below.
You can use IronRuby along with the Dynamic Language Runtime (DLR) to parse the Ruby code. The steps are to: create a Ruby engine instance, create a script source and unit, create a parser and parse to an AST, and walk the AST with a Walker.
Create the Engine
var runtime = IronRuby.Ruby.CreateRuntime();
var engine = runtime.GetEngine("rb");
Create the Source Unit
var src = engine.CreateScriptSourceFromString(#"puts 'hello'"); // also: engine.CreateScriptSourceFromFile
var srcUnit = HostingHelpers.GetSourceUnit(src);
Parse
var parser = new Parser();
var srcTreeUnit = parser.Parse(srcUnit, new RubyCompilerOptions(), ErrorSink.Default);
Walk the AST
var walker = new MyWalker();
walker.Walk(srcTreeUnit);
You'll need to subclass the Walker class, which has numerous virtual methods to handle visiting various nodes in the AST. The one used in the LinqPad Query looks like so:
public class MyWalker : Walker
{
protected override void Walk(MethodCall node)
{
Console.WriteLine("Method call: " + node.MethodName);
base.Walk(node);
}
protected override void Walk(StringLiteral node)
{
Console.WriteLine("String Literal: " + node.GetMutableString().ToString());
base.Walk(node);
}
}
When you run this walker on the AST generated above, you get the following:
Method call: puts
String Literal: hello
I used LinqPad and added the IronRuby 1.1.3 nuget package and created a LinqPad Query with the above.

Building a lambda with an Expression Tree

I'm having a hard time grasping the expression trees. I would like to be able to build an expression tree manually for the following statement:
c => c.Property
A lot of the tutorials focus around comparing, while I just want it to return this one property. Any help?
ParameterExpression parameter = Expression.Parameter(typeof(YourClass), "c");
Expression property = Expression.PropertyOrField(parameter, "Property");
Expression<Func<YourClass, PropertyType>> lamda = Expression.Lambda<Func<YourClass, PropertyType>>(property, parameter);

What is does expression<T> do?

What does Expression<T> do?
I have seen it used in a method similar to:
private Expression<Func<MyClass,bool>> GetFilter(...)
{
}
Can't you just return the Func<MyClass,bool> ?
Google and SO searches have failed me due to the < and > signs.
If TDelegate represents a delegate type, then Expression<TDelegate> represents a lambda expression that can be converted to a delegate of type TDelegate as an expression tree. This allows you to programatically inspect a lambda expression to extract useful information.
For example, if you have
var query = source.Where(x => x.Name == "Alan Turing");
then x => x.Name == "Alan Turning" can be inspected programatically if it's represented as an expression tree, but not so much if it's thought of as a delegate. This is particularly useful in the case of LINQ providers which will walk the expression tree to convert the lambda expression into a different representation. For example, LINQ to SQL would convert the above expression tree to
SELECT * FROM COMPUTERSCIENTIST WHERE NAME = 'Alan Turing'
It can do that because of the representation of the lambda expression as a tree whose nodes can be walked and inspected.
An Expression allows you to inspect the structure of the code inside of the delegate rather than just storing the delegate itself.
As usual, MSDN is pretty clear on the matter:
MSDN - Expression(TDelegate)
Yes, Func<> can be used in place of place of an Expression. The utility of an expression tree is that it gives remote LINQ providers such as LINQ to SQL the ability to look ahead and see what statements are required to allow the query to function. In other words, to treate code as data.
//run the debugger and float over multBy2. It will be able to tell you that it is an method, but it can't tell you what the implementation is.
Func<int, int> multBy2 = x => 2 * x;
//float over this and it will tell you what the implmentation is, the parameters, the method body and other data
System.Linq.Expressions.Expression<Func<int, int>> expression = x => 2 * x;
In the code above you can compare what data is available via the debugger. I invite you to do this. You will see that Func has very little information available. Try it again with Expressions and you will see a lot of information including the method body and parameters are visible at runtime. This is the real power of Expression Trees.

How do dictionary lookups work in IronRuby?

I have this line of IronPython code:
Traits['Strength'].Score + Traits['Dexterity'].Score
Traits is defined as such:
Dim m_Traits As New Dictionary(Of String, Trait)
scope.SetVariable("Traits", m_Traits)
I would like to translate the IronPython code into IronRuby, but I'm having trouble finding the correct syntax.
In Ruby (and IronRuby), variables must begin with a lowercase letter. Therefore, just change the Traits variable to traits to make your code works:
var engine = IronRuby.Ruby.CreateEngine();
var scope = engine.CreateScope();
scope.SetVariable("traits", traits);
dynamic result = engine.Execute("traits['Strength'].Score + traits['Dexterity'].Score", scope);
(this code works, I checked).
By the way, creating a variable that starts with a capital letter makes it a constant (that's how Ruby works) and adding a constant to the scope is done in a slightly different way.

Resources