Sunday, March 27, 2005

"Feature Creeps" in BMCS

This "Good Friday" weekend had been a "Good Hacking" weekend for me. I made good progress on the conversions between the primitive types.

As I was hacking, the following question constantly surfaced at the back of my head - "How will I be managing the features sneakily creeping in from gmcs world to the bmcs world?". There are two components to answering this question - Identifying that a feature is creeping in and tactfully "handling" the same.

To cite an example, "unsigned numeric types" are "feature creeps" from the C# world. The following pattern keeps recurring in the gmcs conversion routines.

static public Expression ImplicitNumericConversion (EmitContext ec, Expression expr,
                               Type target_type, Location loc)
{
    Type expr_type = expr.Type;
    if (expr_type == TypeManager.ushort_type){
        //
        // From ushort to int, uint, long, ulong, float, double
        //
        if (target_type == TypeManager.int32_type)
            return new OpcodeCast (expr, target_type, OpCodes.Conv_I4);
   }
}

The ushort_type above is cached in the TypeManager as follows:

public class Typemanager
{
    // cached unsigned short type
    static public Type ushort_type = typeof (System.UInt16);
}

One naive way of handling this is to remove all references to the unsigned types. I tried doing this snip, snip, snip ... and it's no fun but a plain drudgery.

Then I sat back and said to myself, sure enough, I can do better than this and ended up doing this -

namespace Mono.CSharp {
    public class NotDefinedAsPrimitiveType {
    }
}

public class TypeManager
{
    public static Type ushort_type = typeof (NotDefinedAsPrimitiveType);
}

Barely three lines of change and most of the feature creep is gone !

Btw, I should admit that it took more time writing these few lines of code than doing all those snips ...

Coming back to the question that I raised previously, the obvious answer is that I should start educating myself about the language semantics in the C# world. This will help me make educated and intelligent choices for handling of feature creeps.

Thursday, March 24, 2005

A Reference VB Parser

Paul Vick has earlier released a VB Parser under the Shared Source Licence. The parser is written in VB.NET and is apparently of beta 2 quality complying with 7.1 version of the spec.

The above parser could help Mono's VB.NET compilers (mbas and bmcs) in two ways:

  1. A reference implementation against which ambiguities in the language specification could be clarified
  2. As a test suite in itself

Saturday, March 12, 2005

Challenges in writing a compatible VB.NET compiler

Thanks to this user comment to my previous enty , I am realising that I need to be more aware of the happenings on in the VB.NET world.

Anyways, to answer this reader's comment, I should admit that my immediate focus is to get a compiler that complies to the VB.NET 7.1 Language Specification . When I get to grab a copy of the VB.NET 8.0 Language Specification, I would start getting in the related changes in to BMCS. Can anyone of you make this document available to me if at all Microsoft has made this available as part of their .NET 2.0 bundle ?

On a related note, let me register here that there are two "must haves" for making available a fully functional and compatible VB.NET compiler.

  1. The Languages Specification
  2. A functional and compatible "VB.NET Runtime"

The item (1) above is obvious in itself and it is indisputable that it is a "must have".

The item (2) above is less obvious and requires some elaboration and explanation. "VB.NET Runtime" broadly refers to a set of service routines that is implicitly made use of in any VB.NET executable. These service routines provide type conversion and late binding related functionality and is tucked away in the Microsoft.VisualBasic.CompilerServices namespace of the Microsoft.VisualBasic.dll. Any developer who had casually peeked in to a VB.NET execuatble would have noticed that Microsoft's VB.NET compiler - vbc sneaks in calls to the above namespace to provide the "VB.NET experience" to the programmer. So, a certain amount of base compiler functionality is made available as part of the Microsoft.VisualBasic.dll

The "VB.NET runtime" is a bit troublesome in that the Compiler Services APIs are not at all documented as part of Microsoft's SDK. As a result considerable reverse engineering needs to be done to get their functionality right.

I am particularly happy to note that both the above two "must haves" are taken care of vis a vis Mono's .NET 1.1 environment.

I am thankful to folks at Microsoft for having made the VB.NET 7.1 spec freely and widely accessible.

As for "VB.NET runtime", much of the groundwork had been done by Chris J Breisch, Rafael Teixeira, Martin Adoue, Dennis Hayes and Duncan Mak. Special thanks are due to folks at Mainsoft who made available a huge chunk of Java code that implements the whole of Microsoft.VisualBasic.dll.

It remains to be seen how the Mono community goes ahead and meets the above two challenges wrt VB.NET 8.0 language environment.

Btw, I thank Ankit Jain , for submitting the much required perl fixups to Mono's VB.NET runtime. The inexpressibility of "Default Parameter Values" in C#-based Microsoft.VisualBasic.dll has at last been addressed. I am waiting to see the corcompare results for this critical library once the patches have been successfully merged.

Saturday, March 05, 2005

Type Conversions in BMCS

BMCS now has the basic infrastructure in place to do VB.NET like Type Conversions - both Implicit and Explicit.

The changes turned out to be much simpler than I had earlier thought.

The main difficulty was the nomenclature used by the C# and VB.NET specifications. It took sometime for me to realize the following two facts:

  1. VB.NET 's notion of "Widening and Narrowing Conversions" is equivalent to C# 's notion of "Implicit and Explicit Conversions".
  2. VB.NET has no notion of "User Defined Conversions".

Once the above essential facts were in place, a quick renaming of gmcs's conversion methods and a little bit of refactoring put everything in perspective. (Whoever asked "What is in a name?" should definitely be a fool!)

One biggest challenge introduced by the above renaming and considerable deletions (VB.NET has no unsigned data type other than "Byte", you see) is the increased lexical distance between the gmcs and bmcs trees.

I was immediately tempted to assess how much of a overhead that it introduces in merging of the two trees. After my second merge, I would say that it makes my life more difficult. Eventhough merging in itself is more of a pain, verifying that it indeed is just fine is actually much easier - just do a "diff of diffs" and verify that the only diffs are in the "positions of the diff".

Once I am done with giving final touches to the conversion changes, I think I might resort to "re renaming" the methods. (Whoever asked "What's in a name?" definitely has his feet firmly on the ground!)

My next goal is to VBify expression semantics and follow that up with a "rigorous" article on how C# and VB.NET differ with respect to Type Conversions.