Определение констант и операторов в Иронии


Я новичок в иронии и всей языковой реализации 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)завершается с сообщением: ошибка: оператор '==' не определен для системы типов.Логическое и Система.Логический. В (6: 15).

Edit: решены обе проблемы, см. ответ ниже.

1 4

1 ответ:

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

Выпуск 1

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

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

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

Выпуск 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);
  }
}

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

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