Я пишу язык, используя деревья Antlr и Expression.
Я определил стандартный метод фабрики для моего анализатора деревьев, который будет использоваться при генерации сложения, и он очень хорошо работает для встроенных целочисленных типов, теперь я перехожу к более общим типам.
На данный момент это невероятно наивно, он просто делает это (незавершенный TDD-код часто выглядит наивным, верно!?):
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);
}
Где Promote7_2_6_2
генерирует выражения Convert, которые следуют правилам интегрального продвижения, изложенным в спецификации C # 7.2.6.2 (язык будет похож на C #, но будет пересекаться с JScript, а также с другими совершенно новыми ключевые слова).
Естественно, я перешел к тестированию добавления строк - т.е. "a" + "b";
, и я получаю ошибку:
System.InvalidOperationException: The binary operator Add is not defined for the types 'System.String' and 'System.String'.
Достаточно справедливо - я отражаю System.String и уверен, что оператор действительно не определен. Генерация дерева выражений в тестовом методе, подобном следующему:
Expression<Func<string, string, string>> e = (s1, s2) => s1 + s2;
Показывает, что Add BinaryExpression действительно создано, но с методом реализации, установленным на один из string.Concat
методов.
Я знал, что в некоторых случаях мне придется смотреть на что-то подобное, но сколько других типов определяют сложение таким образом? Это просто string
?
Это правило, встроенное в компилятор C #, или есть какие-то обнаруживаемые метаданные, которые я могу использовать для автоматического обнаружения таких методов в других типах?
Заранее спасибо!