интерпретатор — Хранение элементов разного типа в векторе / массиве в C ++?

Я пытаюсь создать простой динамический интерпретатор языка в C ++. Я хотел бы иметь возможность объявлять динамически типизированные массивы, но я не уверен, как хранить их в каком-либо объекте в C ++.

В Ruby / Python я могу хранить все, что захочу, но как эффективный способ сделать это в C ++?

(Также, если у кого-то есть ссылка на просто лексер / парсер / интерпретатор с открытым исходным кодом для динамических языков, таких как Ruby, я был бы признателен за ссылку).

0

Решение

Вам нужно будет выбрать какое-то нестандартное решение, основанное на семантике вашего языка. Например, вы можете использовать boost::any в хранить любой объект, но вы не сможете выполнить, например, поиск по имени. Знание некоторого ассемблера полезно здесь, потому что вы в основном подражаете этому. То, что делает большинство людей, это что-то вроде

struct Object {
boost::any cppobject;
std::unordered_map<std::string, std::function<void(boost::any&, std::vector<boost::any>&)> funcs;
};

std::vector<Object> stuff;

Когда, на вашем гипотетическом языке, у вас есть что-то вроде

stuff[0].hi();

Тогда вы можете преобразовать его в нечто вроде

std::vector<boost::any> args;
// fill args
stuff.at(0).funcs["hi"](stuff.at(0).cppobject, args);
// now args holds the result

Вполне возможно и дальше оптимизировать эту схему, но не обобщать ее дальше, поскольку она уже максимально общая.

1

Другие решения

Динамические языки хранят универсальные объекты с помощью указателей, вы можете сделать то же самое в C ++. Храните указатель на общий «объект», который вы определяете в своих классах C ++, это эффективный способ сделать это.

0

Альтернативой использованию объединений или динамического выделения объектов общего базового типа (и их снижения в зависимости от ситуации с помощью dynamic_cast или эквивалентной конструкции) является повышение :: вариант, который позволяет вам писать код, такой как:

typedef boost::variant<int, float, char, std::string> LangType;
std::vector<LangType> langObjects;

Если ваша конструкция допускает такую ​​реализацию, то она имеет преимущество в том, что она безопасна во время компиляции и позволяет избежать любого штрафа, налагаемого использованием кучи, виртуальных функций и полиморфных снижений производительности.

0
По вопросам рекламы [email protected]