Какой хороший способ обработки встроенных функций в интерпретаторе, написанном на C++?

Я пишу интерпретатор на C++ для лиспоподобного языка моей скромной конструкции. Это для развлечения и обучения, поэтому я не стремлюсь к абсолютной эффективности. Но я стараюсь иметь очень чистый код на C++. Сейчас я задаюсь вопросом, как реализовать встроенные функции.

В основном, я делаю следующее :

У меня есть абстрактный базовый класс DataObject, который просто предоставляет информацию о типе (в настоящее время double, int, bool) и наследуется конкретными контейнерами данных, например :

class DataObject
{
public:
    virtual const Type *type() = 0;
};

template<class T, const Type * myType>
class DataObjectValue : public DataObject
{
T value;
public:
    const Type *type(){return myType;}
};

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

DataObject * sum(DataObject *a, DataObject *b)
{
    if(a->type() == &Integer and b->type == &Integer)
    {
        DataObjectValue<int>* ia = dynamic_cast< DataObjectValue<int>* >(a);
        DataObjectValue<int>* ib = dynamic_cast< DataObjectValue<int>* >(b);
        return new DataObjectValue<int>(ia->value+ib->value);
    }
    else if(a->type() == &Real and b->type == &Real)
    {
        DataObjectValue<double>* ra = dynamic_cast< DataObjectValue<double>* >(a);
        DataObjectValue<double>* rb = dynamic_cast< DataObjectValue<double>* >(b);
        return new DataObjectValue<double>(ra->value+rb->value);
    }
    else...
}

Что становится довольно раздражающим довольно быстро (сделайте это для - * / < <= >= < > ....) и для нескольких других типов. Это трудно поддерживать. Конечно, я упростил процесс настолько, насколько мог придумать, внедрив повсюду множество шаблонов, но все же я не могу отделаться от мысли, что должен быть более чистый способ. Вы а) видите, в чем моя проблема (я сомневаюсь в своих объяснениях, а не в вашей компетентности) б) можете предложить что-нибудь?

5
задан Lightness Races with Monica 9 December 2011 в 10:00
поделиться