How do I write an implicit cast for my strongly typed interpreter? (C++)

87 Views Asked by At

I'm currently writing an interpreter and it's strongly typed. It has short, int, long, float, and double. I want to make binary operation between 2 numbers and have an implicit cast. For example, I want to be able to add an int to a double and return a double, or adding a long to a double and return a double.

The code for the evaulator for a binary expression is written like this

std::any Interpreter::visitBinaryExpression(BinaryExpression& binaryExpression)
{
    std::any left = binaryExpression.left->accept(*this);
    std::any right = binaryExpression.right->accept(*this);
    Token_t op = binaryExpression.op;

    if (left.type() == typeid(short) && right.type() == typeid(short))
    {
        return eva_num(std::any_cast<short>(left), op, std::any_cast<short>(right));
    }
    if (left.type() == typeid(int) && right.type() == typeid(int))
    {
        return eva_num(std::any_cast<int>(left), op, std::any_cast<int>(right));
    }
    if (left.type() == typeid(long) && right.type() == typeid(long))
    {
        return eva_num(std::any_cast<long>(left), op, std::any_cast<long>(right));
    }
    if (left.type() == typeid(float) && right.type() == typeid(float))
    {
        return eva_num(std::any_cast<float>(left), op, std::any_cast<float>(right));
    }
    if (left.type() == typeid(double) && right.type() == typeid(double))
    {
        return eva_num(std::any_cast<double>(left), op, std::any_cast<double>(right));
    }

    if (left.type() == typeid(bool) && right.type() == typeid(bool))
    {
        return eva_bool(std::any_cast<bool>(left), op, std::any_cast<bool>(right));
    }
    std::string left_err = left.type().name();
    std::string right_err = right.type().name();
    throw std::invalid_argument("Runtime Error: couldn't evaluate type '" + left_err + "' with type '" + right_err + "'");
}

The parser generates an AST and then I interpret each statements using the visitor pattern.

The problem is that, since I'm using std::any I need to check each scenario for the variable type. And by doing this, I'll end up with more than 100 IF statements, which doesn't sound right.

i tried to replace std::any with std::variant but i'll still have 100+ if statements. I tried to use metaprogramming, but i really don't know how to implemenet this (I'm a beginner)

does anyone know how to solve this problem without brutally writing all the if statements?

0

There are 0 best solutions below