Определение констант и операторов в Иронии
Я новичок в иронии и всей языковой реализации shebang, поэтому я играл с образцом ExpressionEvaluator, который поставляется с источником иронии, который, кажется, (почти) соответствует моим потребностям для проекта, над которым я работаю.
Однако я хотел бы, чтобы он также поддерживал булевы, поэтому я добавил операторы сравнения в список двоичных операторов, как таковые:
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
| "==" | "<=" | ">=" | "<" | ">" | "!=" | "<>"; // added comparison operators
Вот пример того, что я пытаюсь сделать. достижение:
x = 1
y = 2
eval = x < 2
eval2 = y < x
bool = true
bool2 = (eval == eval2)
Из-за добавленных бинарных операторов он успешно анализирует вышеизложенное. Однако при компиляции и запуске кода он завершается неудачей на последних двух строках.
- строка
bool = true
завершается ошибкой с сообщением: ошибка: переменная true не определена. В (5: 8). Как определить true и false как константы? - строка
bool2 = (eval == eval2)
завершается с сообщением: ошибка: оператор '==' не определен для системы типов.Логическое и Система.Логический. В (6: 15).
Edit: решены обе проблемы, см. ответ ниже.
1 ответ:
Хорошо, решены обе проблемы. Надеюсь, это может помочь другим.
Выпуск 1
Насколько я могу понять из этой темы обсуждения иронии, истинные иложные константы следует рассматривать как предопределенные глобальные переменные, а не реализовывать непосредственно как часть языка. Таким образом, я определяю их как глобалы при создании ScriptInterpreter.
Следует осознавать, что, делая это таким образом, они могут быть модифицированные скриптом, так как они не являются константами, а просто глобальными переменными. Возможно, есть лучший способ сделать это, но на данный момент это будет сделано:
var interpreter = new Irony.Interpreter.ScriptInterpreter( new ExpressionEvaluatorGrammar()); interpreter.Globals["true"] = true; interpreter.Globals["false"] = false; interpreter.Evaluate(parsedSample);
Выпуск 2
Во-первых, оператор
<>
должен стоять перед операторами<
и>
в двоичном операторном правиле:Затем я создал пользовательскую реализацию классаLanguageRuntime , которая реализует необходимые операторы.BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**" | "<>" | "==" | "<=" | ">=" | "<" | ">" | "!="; // added comparison operators
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); }