|
Goals
Our goal is to create a compiler for the Ruby language that targets the .NET CLR.
We aim to support 100% of Ruby language semantics, including all dynamic constructs
such as closures and continuations. We plan to generate 100% managed and verifiable
CIL code.
We will support the core language, including the built-in Ruby classes
such as Class, Object, Array, String and the built-in Ruby modules such as Math and
Kernel. We do not; however plan to implement the other Ruby libraries that commonly
ship with the Ruby distribution, such as CGI and DBM (except for those implemented
100% in Ruby). We will leave it to others in the community to implement these
libraries; or alternatively equivalent .NET libraries could be used in their place.
Licensing
It is currently our intension to release this software under a relatively liberal
open source license that largely allows it to be freely used by anyone in any way
and for any purpose.
Technical Overview
We will support separate compilation of individual Ruby source files into dlls or
.exes as well as a compile-load-and-run option to achieve behaviour identical to
the existing Ruby interpreter.
Ruby’s dynamic semantics mean that variables are not typed and methods can be
dynamically added and removed from Ruby classes. So in general, Ruby method
invocation cannot rely entirely on the CLR’s normal dynamic dispatch mechanisms.
We instead explicitly represent Ruby classes, methods etc as CLR objects and
implement a custom Ruby call interface that locates the appropriate Ruby method
to call based on Ruby’s inheritance and mixin semantics.
Ruby also allows existing Ruby classes to be extended by adding and replacing
methods, properties, etc. Ruby classes may be extended in different source files
from where they were initially defined and there may exist no direct static
connection between the two source files. So, in a separate compilation context,
there will not in general always be a one-to-one correspondence between Ruby
classes and CLR classes. The key invariant to ensure correct Ruby semantics is
that any two instances of the same Ruby type must link to the same Ruby Class
object at runtime. The separate compilation issue described above also makes
it very problematic to represent Ruby instance variables as CLR data members
as the same class defined in separate source files may make reference to
different but overlapping sets of instance variables.
For efficiency reasons, we represent some Ruby types as primitive CLR types rather
than inheriting from the generic Ruby Object class. For example, Fixnums are
represented as CLR ints. In such cases, the link between the instance and its Ruby
Class is implicit (by way of its CLR type).
Local variables in Ruby can be captured by closures which come in the form of Ruby
blocks. Such local variables (and parameters) need to be accessible even after the
method has returned, so in general Ruby local variables are not stored as CLR local
variables.
Implementation Progress/Status
Our implementation consists of two main components; the compiler and a runtime library.
The runtime library is implemented in C# and includes all of the built-in Ruby classes
and modules such as Class, Object, Method, Array, String and Kernel. Much of Ruby’s
semantics manifests itself in this library. The implementation of the runtime library
is approximately 40% complete.
The compiler consists of a parser/scanner that builds an abstract syntax tree and a code
generator that traverses this abstract syntax tree. There is currently no semantic
analysis phase as Ruby requires no static type checking. Like many dynamic languages,
Ruby’s scanner is complex and its behaviour is context dependent so as to resolve a
number of otherwise ambiguous language constructs. Our implementation is coded in C# and
is largely based on the standard Ruby interpreter distribution as there is no other formal
syntax specification for the language. Our parser is generated from a YACC grammar with
embedded C# actions. We use our own parser generator (the Gardens Point
Parser Generator) to perform this task. It is available for separate download, and we
seek feedback from the community on its utility for other .NET compiler projects. The
implementation of the parser and scanner is approximately 95% complete. The code generator
uses our home grown PE file reader and writer (PERWAPI), also
available for separate download. The initial implementation of the code generator is
approximately 90% complete, but it will need to be considerably revised to provide support
for reflection style methods in the Ruby runtime library that are yet to be implemented.
Release Schedule
We hope to have an alpha release ready by mid 2006. This release will concentrate
on achieving correct Ruby semantics and will not attempt to address performance or .NET
interoperability issues. We seek supportive parties to help us out with testing and
constructive feedback at that stage.
A public beta release should be available by the end of 2006 that will include
performance optimizations for commonly occurring special cases and better support for
interoperability with other .NET programs.
Contact
To register for release announcements please use the online
registration form or for further information please contact:
Acknowledgements
This project is receiving technical and financial support from Microsoft, and has the
general aim of improving support for dynamic languages on the CLR.
|