Определение констант и операторов в Иронии - PullRequest
4 голосов
/ 02 августа 2011

Я новичок в Ирония и вся языковая реализация shebang, так что я играл с ExpressionEvaluator сэмплом, который поставляется с Иронией что, кажется, (почти) соответствует моим потребностям в проекте, над которым я работаю.

Однако мне бы хотелось, чтобы он также поддерживал логические значения, поэтому я добавил операторы сравнения в список бинарных операторов как таковой:

BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
  | "==" | "<=" | ">=" | "<" | ">" | "!=" | "<>"; // added comparison operators

Вот пример того, чего я пытаюсь достичь:

x = 1
y = 2
eval = x < 2
eval2 = y < x
bool = true
bool2 = (eval == eval2)

Из-за добавленных бинарных операторов, он преуспел в анализе выше. Однако при компиляции и запуске кода в двух последних строках происходит сбой.

  1. Сбой строки bool = true с сообщением: Ошибка: переменная true не определена. В (5: 8). Как определить true и false как константы?
  2. Сбой строки bool2 = (eval == eval2) с сообщением: Ошибка: Оператор '==' не определен для типов System.Boolean и System.Boolean. В (6:15).

Редактировать: Решены обе проблемы, см. Ответ ниже.

1 Ответ

9 голосов
/ 02 августа 2011

Хорошо, решены обе проблемы.Надеюсь, это может помочь другим.

Выпуск 1

Насколько я понимаю из этой ветки обсуждения Иронии , true и false константы должны рассматриваться как предопределенные глобальные переменные, а не реализовываться непосредственно как часть языка.Поэтому я определяю их как глобальные при создании ScriptInterpreter .

Следует помнить, что, делая это таким образом, они могут быть изменены сценарием, поскольку они не являются константами, нопросто глобальные переменные.Возможно, есть лучший способ сделать это, но сейчас он подойдет:

var interpreter = new Irony.Interpreter.ScriptInterpreter(
  new ExpressionEvaluatorGrammar());
interpreter.Globals["true"] = true;
interpreter.Globals["false"] = false;
interpreter.Evaluate(parsedSample);

Issue 2

Прежде всего, оператор <> должен стоять перед < и> операторы в правиле бинарных операторов:

BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
  | "<>" | "==" | "<=" | ">=" | "<" | ">" | "!="; // added comparison operators

Далее я создал пользовательскую реализацию класса LanguageRuntime , которая реализует необходимые операторы.

public class CustomLanguageRuntime : LanguageRuntime
{
  public CustomLanguageRuntime(LanguageData data)
    : base(data)
  {
  }

  public override void InitOperatorImplementations()
  {
    base.InitOperatorImplementations();
    AddImplementation("<>", typeof(bool), (x, y) => (bool)x != (bool)y);
    AddImplementation("!=", typeof(bool), (x, y) => (bool)x != (bool)y);
    AddImplementation("==", typeof(bool), (x, y) => (bool)x == (bool)y);
  }
}

В ExpressionEvaluatorGrammar переопределите метод CreateRuntime , чтобы вернуть экземпляр CustomLanguageRuntime :

public override LanguageRuntime CreateRuntime(LanguageData data)
{
  return new CustomLanguageRuntime(data);
}
...