I'm working on a typed scripting language backed by C# Expression Trees. I'm stuck on one issue around proper type conversion with binary operators. Here is an example of the behavior I'm trying to mimic: (The conversion rules should be the same C#'s compiler)
var value = "someString" + 10; // yields a string
var value = 5 + "someString"; // also yields a string, I don't know why
var x = 10f + 10; // yields a float
var y = 10 + 10f; // also yields a float, I don't know why
How does the C# compiler know to call ToString() on the integer in the first line and to convert the integers to floats in both directions when adding with a float? Are these conversion rules hard coded?
My compiler basically works like this now for binary operators:
Expression Visit(Type tryToConvertTo, ASTNode node) {
// details don't matter. If tryToConvertTo is not null
// the resulting expression is cast to that type if not already of that type
}
// very simplified but this is the gist of it
Expression VisitBinaryOperator(Operator operator) {
Expression lhs = Visit(null, operator.lhs);
Expression rhs = Visit(lhs, operator.rhs); // wrong, but mostly works unless we hit one of the example cases or something similar
switch(operator.opType) {
case OperatorType.Add: {
return Expression.Add(lhs, rhs);
}
// other operators / error handling etc omitted
}
}
I know always accepting the left hand side's type is wrong, but I have no idea what the proper approach to resolving the example expressions might be other than hard coding the rules for primitive types.
If anyone can point me in the right direction I'd be very grateful!
This kind of questions can only be answered accurately via the language specification.
+
operator with string
and int
operandsHere, under String concatenation
you will see:
These overloads of the binary
+
operator perform string concatenation. If an operand of string concatenation isnull
, an empty string is substituted. Otherwise, any non-string
operand is converted to its string representation by invoking the virtualToString
method inherited from typeobject
. IfToString
returnsnull
, an empty string is substituted.
+
operator with float
and int
operandsThe int
here is implicitly converted to float
, specified here: