Вычисление выражений в интерпретаторе
Пишу интерпретатор с типами переменных int, double, string. Парсер разбивает на элементы языка, но не знаю как правильно реализовать вычислений выражений. Вычисление реализовано как автомат по уровню операции и он в принципе работает, но я храню ответ в float, при присваивании если это int беру только целую часть. Для string я реализовал похожие функции.
У меня следующие вопросы
- Для каждого типа писать свой обработчик выражений?
- Если не для каждого типа, то в чем хранить ответ после разбора выражения?
- Если для каждого типа, то в случае как if,while какой тип выбрать?
Ответы (1 шт):
так как сам писал такое, то
Для каждого типа писать свой обработчик выражений?
да, а также возможно и для пар. У меня, к примеру, можно было строку умножать на целое ("**" * 2 == "****"), но это зависит от конкретных желаний.
Если не для каждого типа, то в чем хранить ответ после разбора выражения?
есть чудесный тип std::variant. И Вам подойдет std::variant<int, float, std::string>. Ну или свой тип, с помощью union, но это отдельная история, в которой очень легко выхватить UB.
Если для каждого типа, то в случае как if,while какой тип выбрать?
тут много вариантов. Можно воспользоваться get_if, я пользовался index. Так как index возвращает число от 0 до кол-ва типов-1 (с примера выше это получается 2), то можно сделать где то так
using myval = std::variant<int, float, std::string>;
myval a1,a2;
size_t op_index = a1.index() * 3 + a2.index();
switch(op_index) {
case 0: //int-int
return myval(a1.get<int>() + a2.get<int>()); // прям так вызываем
case 3*2+1: // string-float
throw ups();// а так нельзя.
}
но если такое лень для каждой операции писать, то можно воспользоваться перегрузками и передавать операцию как параметр в функцию выше.
Второй вариант заключается в том, что делается базовый тип и от него наследуются типы для каждого нужного - то есть, для числа и строки. А потом, с помощью двойной диспетчеризации разбираются операции. Я так пробовал, получилось сильно сильно сложнее и не поддерживаемо.