Интерпретатор в C ++: проблема хранения таблицы функций - PullRequest
3 голосов
/ 04 апреля 2010

В моем переводчике есть встроенные функции, доступные на языке, например print exit input и т. Д. Эти функции, очевидно, могут быть доступны изнутри языка. Затем интерпретатор ищет соответствующую функцию с правильным именем в векторе и вызывает ее через указатель, сохраненный с ее именем.

Итак, я собираю все эти функции в такие файлы, как io.cpp, string.cpp, arithmetic.cpp. Но мне нужно добавить каждую функцию в список функций в интерпретаторе, чтобы ее можно было найти.

Итак, в этих файлах функций у меня есть такие вещи:

void print( arg )
{
     cout << arg.ToString;
}

Я бы добавил эту функцию печати в список функций переводчика с помощью:

interpreter.AddFunc( "print", print );
  • Но куда мне звонить interpreter.AddFunc?

Я не могу просто поместить его там под функцией печати, поскольку она должна быть в функции в соответствии с синтаксисом C ++.

  • Где и как все функции должны быть добавлены в список?

Ответы [ 3 ]

2 голосов
/ 05 апреля 2010

В каждом модуле (io, string и т. Д.) Определите метод, который регистрирует модуль с помощью интерпретатора, например ::

void IOModule::Register(Interpreter &interpreter) {
    interpreter.AddFunc( "print", print );
    //...
}

Это также может быть нормальной функцией, если ваш модуль не реализован в классе.

Затем при основной инициализации вашего приложения вызовите метод register всех модулей.

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

1 голос
/ 05 апреля 2010

Все ли включено в каждый переводчик? Если это так, я бы порекомендовал добавить его в конструктор (при условии, что интерпретатор является объектом) или в методе init.

Если нет, вы можете рассмотреть возможность добавления директивы типа include на вашем языке. Затем вы делаете это, когда сталкиваетесь с директивой include.

1 голос
/ 04 апреля 2010

Самое простое - сохранить map имен функций для указателей функций и загрузить их при запуске программы . У вас уже есть функции, связанные с исполняемым файлом интерпретатора, поэтому они доступны во время вызова main().

Также можно придумать схему, в которой функции дефилируются в динамических библиотеках (.dll или .so в зависимости от платформы), а некоторые файлы конфигурации отображают имена функций в библиотеки / точки входа.

...