views:

39

answers:

1

I'm writing a language using Antlr and Expression trees.

I've defined a standard factory method for my Tree Parser to use when generating addition, and it works very nicely for the built in integral types, now I'm moving on to more general types.

At the moment it's incredibly naive, it simply does this (in-progress TDD code often looks naive right!?):

protected Expression GenerateAdd(Expression left, Expression right)
{
  if (left.Type.Equals(right.Type))
    return Expression.Add(left, right);
  if (left.Type.IsValueType && right.Type.IsValueType)
    Promote7_2_6_2(ref left, ref right);
  return Expression.Add(left, right);
}

Where Promote7_2_6_2 generates Convert expressions that follow the rules for integral promotion as laid out by the C# spec 7.2.6.2 (The language will be similar to C#, but will cross-over with JScript as well as having other brand new keywords).

Naturally, I moved on to testing string addition - i.e. "a" + "b"; and I get the error:

System.InvalidOperationException: The binary operator Add is not defined for the types 'System.String' and 'System.String'.

Fair enough - I reflect System.String and sure enough that operator is indeed not defined. Generating an expression tree in a test method like this:

Expression<Func<string, string, string>> e = (s1, s2) => s1 + s2;

Shows that an Add BinaryExpression is indeed created, but with the implementing method set to one of the string.Concat methods.

I was aware that I was going to have to look at doing something like this in some cases, but how many other types define addition in this way? Is it just string?

Is it a rule embedded within the C# compiler - or is there some kind of discoverable meta data that I can use to auto-discover such methods on other types?

Thanks in advance!

A: 

It seems I do a great line in answering my own questions!

My apologies, this answer could be better formatted, but I'm on my HTC desire and its keyboard doesn't support all the symbols!

it appears that there is no way to 'discover' these rules at runtime, it is the host language's responsibility to decide how to implement such things as string addition. C# adapts to the number of consecutive terms in an addition, calling the the .Concat method that most appropriately matches that.

So, if I wish my language to support addition of class instances where an operator is not defined for it, for example, I can simply write or find a static method to do it (of the correct signature of course!) and then hardwire the language to use it in that case. A classic example here is whether to support array1 + array2 through the static Array methods.

As for discovery of operators, the Expression.Add method takes care of that, but it doesn't automatically perform any conversions, so, as with the integral/floating point promotion method I reference in the question, again it is up to the language's rules to determine if other conversions are required before attempting to build the expression.

As such, it is probably best to reflect the operator first, to see if one is defined for the two types, before then considering a conversion if one exists.

Andras Zoltan