Click here to Skip to main content
Email Password   helpLost your password?

What does the Sample do

It compiles C# lambda expressions into 16-bit executable files.

Why is it Interesting?

C# expression trees allow you to analyze C# code and reinterpret it in a different way. E.g. LINQ-to-SQL takes expressions written in C# and turns them into SQL statements.

This sample turns (a small subset of) C# into 8086 machine code.

Background

I have read many blogs about LINQ expression trees and how "cool" they are. However, very few posts explained what actually expression trees are for. This sample demonstrates one possible usage. Some day, I may expand this article to further discuss the place of expression trees in life.

Why .Com Files 

I chose .com files because they are as simple as executable format gets. Just an array of 8086 machine codes with absolutely no headers or metadata. A compiler writer heaven. And it is still executable on all versions of Windows.

NB: "com" here is merely a file extension, as in xy.com. It has nothing to do with Component Object Model which appeared 10 or so years after .com files.  

Compiling Expressions

An expression may contain variables and three arithmetic operations: +, -, and *. All arithmetic is done in unsigned 16-bit integers.

When the generated COM file executes, it prints a banner, prompts the user for parameter values (if any), calculates the result and displays it. COM files shall be executed in a console window, e.g. from cmd.exe.

E.g. expression (x,y) => 2*x + 3*y when compiled and executed produces the following output (user input in bold):

C# for MS-DOS, version 1.0
x? 10
y? 20
((2 * x) + (3 * y)) = 80

Calling Expression Compiler

The sample provides class ExpressionCompiler86 with the method Compile(Expression expr). Here is how main class Program compiles three expressions:

    // a little wrapper to makes things simpler
    static void Compile<T>(string file, Expression<T> expr)
    {
        using (ExpressionCompiler86 compiler = new ExpressionCompiler86(file))
        {
            compiler.Compile(expr);
        }
    }

    ...

    Compile<Func<int>>( "constant.com", () => 42);
    Compile<Func<int>>( "noparams.com&", () => 1+2+3*4);
    Compile<Func<int,int,int>>( "xy.com", (x,y) => 2*x + 3*y );

Disclaimer 

Please be lenient to the quality of code. It is not production code. It's a sample, or, rather, a proof of concept. It was written in one day. It contains absolutely no automated tests. There are absolutely no overflow checks or anything like that. Class names may be questionable. Bugs are likely.  

Enjoy! 

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralGot my 5
Lee Humphries
14:16 8 Sep '08  
In the end it's articles like this that I really appreciate on CP.

As regards new features, I'd specifically add anything that requires referencing memory addresses - just so you can have some really unmanaged code being generated. Laugh

I am convinced that lobotomising users will make little to no difference.

GeneralRe: Got my 5
Ivan Krivyakov
16:32 9 Sep '08  
Would you like to elaborate on referencing memory?
How would you do it in the lambda?
Remember that the source expression is still C#
GeneralRe: Got my 5
Lee Humphries
19:07 9 Sep '08  
Hi Ivan,

I was being facetious, and referring to how the handling of arrays, pointers, parameters in function calls etc. get performed in assembler.

It just struck me as ironic to use managed code (C#) to generate pure com executables, that are very unmanaged by their very nature.

Still think your work is great though.

I am convinced that lobotomising users will make little to no difference.

GeneralExcellent
torial
5:57 5 Sep '08  
I gave you a 5, but would love to see the examples expanded!
GeneralNice...
Rob Philpott
2:43 5 Sep '08  
... and a bit mad! Smile

Regards,
Rob Philpott.

Generalgenius
Unruled Boy
21:20 4 Sep '08  
u r really Cool

Regards,
unruledboy (at) gmail (dot) com
http://www.xnlab.com

GeneralAwesome
Tarnacious Barfish
20:37 4 Sep '08  
I remember loving writing 16 bit assembly and expression trees are cool. I had a play round with your code, it does what you say it does, and I think its really cool. I'd love to extend your example to be a bit more generic or add support for strings (although I don't think that would be easy), but I doubt I'll find the time. I'm glad you found the time and posted the code. Thanks!

Tarn
http://blog.sharpthinking.com.au


Last Updated 4 Sep 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010