2010-05-28 3 views
11

J'essaie de définir mon propre opérateur dans Io, et j'ai du mal à le faire. J'ai un objet:Comment définir mes propres opérateurs dans le langage de programmation Io?

MyObject := Object clone do(
    lst := list() 
    !! := method(n, lst at(n)) 
) 

Mais quand je l'appelle, comme ceci:

x := MyObject clone do(lst appendSeq(list(1, 2, 3))) 
x !! 2 

Mais je reçois une exception cet argument 0 au ne dois pas être nul. Comment puis-je réparer?

Répondre

14

Eh bien, il y a un problème dans votre code. Tout simplement, vous n'avez pas ajouté !! à la table d'opérateur. Je vais vous donner un peu de contexte à ce sujet.

Les opérateurs dans Io sont mélangés avant la construction de l'AST. Cela signifie que nous devons maintenir une liste d'opérateurs connus avec certains niveaux de priorité pour savoir lesquels se lient plus étroitement que d'autres. Nous faisons cela dans le "OperatorTable". Si vous êtes dans le REPL, vous pouvez voir comment l'utiliser en tapant "OperatorTable" dans le REPL (sans les guillemets). Cela vous donnera une liste des opérateurs, (générés dynamiquement, ainsi de nouveaux opérateurs sont ajoutés comme ils sont définis), avec des exemples d'utilisation de chaque type d'opérateur. Il existe deux types:

  1. Opérateurs binaires (1 + 2 par exemple, appelé simplement "opérateurs")
  2. Opérateurs d'affectation (a: = b par exemple)

Donc, dans votre exemple, votre code est correct; nous ne devons rien changer là-bas. Cependant, il nous manque un bit de code pour que le sous-système d'analyse sache comment gérer votre opérateur. Je vais donner un exemple qui suppose que vous voulez qu'il se lie aussi étroitement que la multiplication.

OperatorTable addOperator("!!", 3) 

Maintenant, nous pouvons voir comment cela se traîna en construisant un message et en regardant la façon dont son arbre est représenté. Encore une fois dans le REPL, si nous entrons:

message(a !! b) 

Nous verrons quelque chose comme ceci:

==> a !!(b) 

Ceci est comme tout autre appel de méthode, il doit exister quelque part, ou bien vous obtiendrez un Erreur. Vous pouvez l'utiliser comme indiqué ci-dessus (avec une parenthèse explicite), ou vous pouvez l'utiliser comme vous le souhaitez dans votre question originale, sans parenthèse explicite. Comme avec n'importe quel opérateur, vous êtes soumis aux règles de priorité si vous n'utilisez pas de parenthèses explicites, juste pour que vous soyez au courant.

Espérons que cela répond à votre question.

+1

Merci pour votre réponse, utile de savoir. Cependant, je ne comprends pas pourquoi "n" est nul dans mon !! méthode. –

+3

Bien, simplement, dans Io, seules les CFunctions (c'est-à-dire, les méthodes qui sont implémentées dans le code C qui récupèrent des arguments spécifiques à des index spécifiques) ont l'obligation de fournir au moins N arguments. Quand un opérateur n'est pas connu, il n'est pas mélangé, ce qui signifie que votre x d'origine !! 2 était vu comme: message (x !! 2) et non message (x !! (2)). Depuis !! est défini dans le code Io avec la gestion des arguments par défaut, ce qui se produit est que tous les arguments non explicitement fournis sont remplis avec "nil". Autrement dit, les arguments sont définis, mais ils pointent à zéro. C'est la source de votre problème. – jer

+0

+1 pour une réponse complète, aussi pour la friperie sur l'OperatorTable représentant l'ordre de priorité. Je n'avais pas remarqué ça. – labyrinth

Questions connexes