Pregunta

Estoy escribiendo un idioma usando Antlr de expresión y árboles.

He definido un método estándar de fábrica para mi Analizador árbol a utilizar al generar Además, y funciona muy bien para el construido en tipos integrales, ahora estoy de pasar a tipos más generales.

En el momento en que es increíblemente ingenuo, simplemente se hace esto (en progreso código TDD menudo parece ingenua derecho!?):

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);
}

Cuando Promote7_2_6_2 genera expresiones Convertir los que siguen las reglas para la promoción integral según lo establecido por el C # spec 7.2.6.2 (El idioma será similar a C #, pero será cross-over con JScript, además de tener otras marcas nuevas palabras clave) .

Por supuesto, pasé a probar suma de cadenas - es decir, "a" + "b"; y me sale el error:

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

suficiente

Feria - reflexiono System.String y bastante seguro de que el operador está de hecho no definido. La generación de un árbol de expresión en un método de ensayo de la siguiente manera:

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

Muestra que un complemento BinaryExpression es, en efecto creado, pero con la implementación de conjunto método para uno de los métodos string.Concat.

Yo era consciente de que iba a tener que mirar a hacer algo como esto en algunos casos, pero ¿cuántos otros tipos defino Además de esta forma? ¿Es sólo string?

¿Es una regla incrustado dentro del compilador de C # - o hay algún tipo de metadatos pueden descubrir que puedo utilizar para detectar automáticamente tales métodos en otros tipos

?

Gracias de antemano!

¿Fue útil?

Solución

Parece que hago una gran línea en responder a mis propias preguntas!

Mis disculpas, esta respuesta podría ser mejor formateado, pero estoy en mi HTC deseo y su teclado no es compatible con todos los símbolos!

parece que no hay manera de 'descubrir' estas reglas en tiempo de ejecución, es responsabilidad de la lengua de acogida para decidir cómo implementar cosas tales como la suma de cadenas. C # se adapte al número de mandatos consecutivos en una adición, que llaman al método .Concat que más apropiadamente eso.

Así que, si me gustaría que mi lengua a la adición apoyo de instancias de la clase en que un operador no está definido para que, por ejemplo, que simplemente hay que escribir o encontrar un método estático de hacerlo (de la firma correcta, por supuesto!) Y luego cablear el idioma a utilizar en ese caso. Un ejemplo clásico aquí es si apoyar array1 + array2 a través de los métodos de matriz estática.

En cuanto a descubrimiento de los operadores, el método Expression.Add se encarga de eso, pero no realiza automáticamente cualquier conversión, por lo que, al igual que con la integral / punto de referencia método de promoción que flota en la pregunta, de nuevo, es de hasta a las reglas del lenguaje para determinar si se requieren otras conversiones antes de intentar la construcción de la expresión.

Como tal, es probablemente la mejor manera de reflejar el operador primero, para ver si uno se define para los dos tipos, a continuación, antes de considerar una conversión si es que existe.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top