2010-05-28 1 views
11

Я пытаюсь определить своего оператора в Ио, и мне тяжело. У меня есть объект:Как определить собственные операторы на языке программирования Io?

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

Но когда я это называю, как это:

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

Но я получаю исключение, что аргумент 0, чтобы при не должен быть равен нулю. Как я могу исправить?

ответ

14

В коде есть одна проблема. Проще говоря, вы не добавили !! к таблице операторов. Я расскажу вам немного об этом.

Операторы в Io перетасовываются до сборки AST. Это означает, что мы должны поддерживать список известных операторов с определенными уровнями приоритетов, чтобы знать, какие из них связаны сильнее других. Мы делаем это в «OperatorTable». Если вы находитесь в REPL, вы можете увидеть, как его использовать, набрав «OperatorTable» в REPL (без кавычек). Это даст вам список операторов (генерируется динамически, поэтому новые операторы добавляются по мере их определения), а также примеры использования каждого типа оператора. Есть два типа:

  1. Бинарные операторы (1 + 2, например, так называемые просто "операторы")
  2. операторы присваивания (а: = Ь например)

Таким образом, в вашем примере, ваш код прав; мы ничего не должны менять. Однако нам не хватает одного бита кода, чтобы подсистема синтаксического анализа знала, как обращаться с вашим оператором. Я приведу пример, предполагающий, что вы хотите, чтобы он привязывался так же сильно, как умножение.

OperatorTable addOperator("!!", 3) 

Теперь мы можем увидеть, как это получает перемешиваются, построив сообщение и, глядя на то, как представляется его дерево. Опять же в РЕПЛ, если мы вводим:

message(a !! b) 

мы увидим что-то вроде этого:

==> a !!(b) 

Это так же, как и любой другой метод вызова, он должен где-то существовать, иначе вы получаете ошибка. Вы можете использовать его, как показано выше (с явным скобкой), или вы можете использовать его так, как вы хотите в своем исходном вопросе, без явных скобок. Как и в случае с любым оператором, вы подчиняетесь правилам приоритета, если вы не используете явные скобки, просто чтобы вы знали.

Надеюсь, это ответит на ваш вопрос.

+1

Спасибо за ваш ответ, полезно знать. Тем не менее, я не понимаю, почему «n» - это ноль в моей !! метод. – 2010-05-28 04:29:38

+3

Хорошо, просто просто положим в Io только функции CFunctions (то есть методы, которые реализованы в коде C, которые извлекают определенные аргументы при определенных индексах), требуют, чтобы вы должны предоставить не менее N аргументов. Когда оператор не известен, он не перетасовывается, что означает ваш оригинал x !! 2 рассматривалось как: message (x !! 2), а не сообщение (x !! (2)). Поскольку !! определяется в коде Io с обработкой аргументов по умолчанию, происходит то, что любые аргументы, явно не предоставленные, заполняются «nil». То есть аргументы определяются, но они указывают на нуль. Это источник вашей проблемы. – jer

+0

+1 для подробного ответа, а также для лаконичной информации об OperatorTable, представляющей порядок приоритета. Я этого не заметил. – labyrinth

 Смежные вопросы

  • Нет связанных вопросов^_^