2010-05-28 18 views
11

Estoy tratando de definir mi propio operador en Io, y estoy teniendo un momento difícil. Tengo un objeto:¿Cómo puedo definir mis propios operadores en el lenguaje de programación Io?

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

Pero cuando yo lo llamo, como esto:

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

Pero consigo una excepción que el argumento de 0 a por lo que no debe ser nulo. ¿Cómo puedo arreglarlo?

Respuesta

14

Bueno, hay un problema en su código. En pocas palabras, ¡no has añadido! a la mesa del operador. Te daré un poco de información sobre esto.

Los operadores en Io se barajan antes de que se construya el AST. Esto significa que tenemos que mantener una lista de operadores conocidos con ciertos niveles de precedencia para saber cuáles se unen más estrechamente que otros. Hacemos esto en la "OperatorTable". Si está en REPL, puede ver cómo usarlo escribiendo "OperatorTable" en REPL (sin las comillas). Esto le dará una lista de los operadores (generados dinámicamente para que los nuevos operadores se agreguen tal como están definidos), junto con ejemplos de cómo usar cada tipo de operador. Hay dos tipos:

  1. operadores binarios (1 + 2, por ejemplo, llamadas simplemente "operadores")
  2. Los operadores de asignación (a: = b, por ejemplo)

Así que en su ejemplo, tu código es correcto; no tenemos que cambiar nada allí. Sin embargo, nos falta un poco de código para que el subsistema de análisis sepa cómo manejar su operador. Proporcionaré un ejemplo que asume que desea que se una tanto como la multiplicación.

OperatorTable addOperator("!!", 3) 

Ahora, podemos ver cómo esto se barajan mediante la construcción de un mensaje y mirando cómo se representa el árbol. Una vez más en el REPL, si escribimos:

message(a !! b) 

veremos algo como esto:

==> a !!(b) 

Esto es igual que cualquier otra llamada a un método, tiene que existir en algún lugar o de lo contrario obtendrá una error. Puede usarlo como se muestra arriba (con paréntesis explícitos), o puede usarlo como desee en su pregunta original, sin paréntesis explícitos. Como con cualquier operador, usted está sujeto a las reglas de precedencia si no usa paréntesis explícitos, solo para que sepa.

Espero que responda a tu pregunta.

+1

Gracias por su respuesta, útil saber. Sin embargo, no entiendo por qué "n" es nulo en mi !! método. –

+3

Muy bien, simplemente, en Io, solo las funciones de CF (es decir, los métodos que se implementan en el código C que captan argumentos específicos en índices específicos) tienen el requisito de que debe proporcionar al menos N argumentos. Cuando un operador no es conocido, no se baraja, lo que significa su x original. 2 fue visto como: mensaje (x !! 2) y no mensaje (x !! (2)). Ya que !! se define en el código Io con manejo de argumentos predeterminado, lo que ocurre es que los argumentos no proporcionados explícitamente se completan con "nil". Es decir, los argumentos se definen, pero apuntan a nil. Esta es la fuente de tu problema. – jer

+0

+1 para obtener una respuesta completa, también para el tidbit sobre la OperatorTable que representa el orden de precedencia. No me había dado cuenta de eso. – labyrinth

Cuestiones relacionadas