Question

J'écris une langue à l'aide d'arbres Antlr et d'expression.

J'ai défini une méthode de fabrication standard pour mon arbre Parser à utiliser lors de la génération plus, et il fonctionne très bien pour la construction dans les types entiers, maintenant je me déplace sur les types plus généraux.

À l'heure actuelle, il est incroyablement naïf, il fait tout simplement ce (en cours code TDD semble souvent bien naïf!):

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

Si Promote7_2_6_2 génère des expressions Convertir qui suivent les règles de promotion intégrale comme prévu par le C # spec 7.2.6.2 (La langue sera similaire à C #, mais cross-over avec JScript ainsi que d'avoir d'autres mots-clés flambant neuf) .

Bien sûr, je suis passé à tester plus de chaîne - à savoir "a" + "b"; et je reçois l'erreur:

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

Juste assez - je pense System.String et bien sûr que l'opérateur est en effet pas défini. Génération d'un arbre d'expression dans une méthode d'essai comme ceci:

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

Indique qu'une BinaryExpression Ajouter est en effet créé, mais avec la méthode d'implémentation ensemble à l'une des méthodes de string.Concat.

Je savais que j'allais devoir regarder faire quelque chose comme ça, dans certains cas, mais combien d'autres types définis plus de cette façon? Est-ce juste string?

Est-ce une règle intégrée dans le compilateur C # - ou est-il une sorte de méta données décelables que je peux utiliser pour découvrir automatiquement ces méthodes sur d'autres types

?

Merci à l'avance!

Était-ce utile?

La solution

Il semble que je fais une grande ligne pour répondre à mes propres questions!

Mes excuses, cette réponse pourrait être mieux mis en forme, mais je suis sur mon désir HTC et son clavier ne supporte pas tous les symboles!

il semble qu'il n'y a aucun moyen de « découvrir » ces règles lors de l'exécution, il est de la responsabilité de la langue hôte de décider comment mettre en œuvre des choses telles que plus de chaînes. C # Se adapte à nombre de mandats consécutifs dans un ajout, en appelant la méthode la .Concat qui correspond à la plus appropriée que.

Alors, si je veux que ma langue plus de soutien des instances de classe où un opérateur n'est pas défini pour, par exemple, je peux simplement écrire ou de trouver une méthode statique pour le faire (de la signature correcte bien sûr!) Et puis câbler la langue à utiliser dans ce cas. Un exemple classique est de savoir si pour soutenir array1 + array2 par les méthodes Array statique.

En ce qui concerne la découverte des opérateurs, la méthode Expression.Add prend en charge, mais il n'a pas effectuer automatiquement les conversions, donc, comme la méthode de promotion intégrale / virgule flottante I référence dans la question, encore une fois c'est aux règles de la langue afin de déterminer si d'autres conversions sont nécessaires avant de tenter de construire l'expression.

En tant que tel, il est probablement préférable de tenir compte de l'opérateur d'abord, pour voir si l'on est défini pour les deux types, avant d'envisager ensuite une conversion si l'on existe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top