Interpreter in C++: Function table storage problem
In my interpreter I have built-in functions available in the language like print
exit
input
, etc.
These functions can obviously be accessed from inside the language. The interpreter then looks for the corresponding function with the right name in a vector and calls it via a pointer stored with its name.
So I gather all these functions in files like io.cpp
, s开发者_JAVA技巧tring.cpp
, arithmetic.cpp
. But I have to add every function to the function list in the interpreter in order for it to be found.
So in these function files I have things like:
void print( arg )
{
cout << arg.ToString;
}
I'd add this print function to the interpreter function list with:
interpreter.AddFunc( "print", print );
- But where should I call the
interpreter.AddFunc
?
I can't just put it there below the print function as it has to be in a function according to the C++ syntax.
- Where and how should all the functions be added to the list?
In each module (io, string, etc.), define a method that registers the module with the interpreter, e.g.:
void IOModule::Register(Interpreter &interpreter) {
interpreter.AddFunc( "print", print );
//...
}
This can also be a normal function if your module is not implemented in a class.
Then in your application's main initialization, call the register method of all modules.
This approach helps keep things modular: The main application initialization needs to know which modules exist, but the details of which functions are exported are left to the module itself.
The simplest is to keep a map
of function names to function pointers and load that at program startup. You already have the functions linked into the interpreter executable, so they are accessible at the time main()
is called.
You can also come up with a scheme where functions are defiled in the dynamic libraries (.dll
or .so
depending on the platform) and some configuration file maps function names to libraries/entry points.
Is everything included in every interpreter? If so, I would recommend adding it either in a constructor (assuming the interpreter is an object) or an init method.
If not, you may want to consider adding an "include" type directive in your language. Then you do it when you encounter the include directive.
精彩评论