Thanks to Eric Hodel and Ryan Davis for pointing me to RubyInline for yet another source of inspiration.

I first saw RubyInline at last years’ RubyConf – it’s a remarkable piece of code that lets you drop inline C into your Ruby programs. However, I don’t really need most of the features in RubyInline since the managed CSharpCodeProvider class already does most of what they do (and a bit more), and RubyCLR does the rest (handling marshaling of parameter types).

However, I did look at their implementation and lifted how they added an inline method to the Module class, and yielding a block that contains the correct compiler wrapper.

The current implementation now does both C# and VB.NET code (and I’ll add support for JScript.NET once I ship this blog entry). Here’s how it looks now:

class InliningTests < TestCase
inline :csharp do |compiler|
compiler.reference('System.Windows.Forms.dll')
compiler.compile <<-EOF
namespace Scratch {
public class Fibonnaci {
public static long Calc(long n) {
long x1 = 1, x2 = 2, tmp;
for (long i = 1; i < n; ++i) {
x1 += x2;
tmp = x2; x2 = x1; x1 = tmp;
}
return x1;
}
public static void SayHello() {
System.Windows.Forms.MessageBox.Show("Hello, World!");
}
}
}
EOF
inline :vb do |compiler|
compiler.compile <<-EOF
Namespace VBScratch
Public Class Fibonnaci
Public Shared Function Calc(n As Long) As Long
Dim x1 As Long = 1
Dim x2 As Long = 2
Dim tmp As Long
Dim i As Long
For i = 1 To n - 1
x1 = x1 + x2
tmp = x2
x2 = x1
x1 = tmp
Next
Return x1
End Function
End Class
End Namespace
EOF
end
def test_csharp_inline
assert_equal 8, Scratch::Fibonnaci.calc(5)
assert_equal 8, VBScratch::Fibonnaci.calc(5)
end
end
end

Notice how I can add references to external assemblies as well via compiler.reference.

So please disregard the implementation that I posted yesterday :)