March 15th, 2011, 09:33 PM
Using stored class names in script interpreter
I've been trying to make a small, very simple scripting language (interpreted at runtime by a C++ program/parser), for my own use, more as an experiment than as anything practical. I don't want to use Flex, Bison, Yacc, Boost::Spirit, or other tools. I'd just like to make something that can take a script-based text file and essentially call and use existing C++ functions and classes from it.
The first brick wall I keep coming up against (next up: argument lists) is turning string-stored class names into C++ types usable in code. For example, take this simple scope class, which assumes created objects of Test1 and Test2 will descend from the base class Interpretable:
As you can see, it's missing one critical component: It doesn't (maybe can't) call some function or macro to analyze className and produce the actual type of the class for the code, so I have to do a check and refer to Test1 directly. Plus, later on when I actually access the object, the same problem applies when finding out what to cast the Interpretable* to: even if I'm using RTTI to get Test1's name, I can't get access to a #defined or something C++ token that means "Test1" -- and that's probably a problem that pokes a huge hole in this whole methodology.
for(map<string,Interpretable*>::iterator it = vars.begin(); it != vars.end(); ++it)
it->second = 0;
void AddVariable(const string& varName, const string& className)
if(className == "Test1")
vars.insert(vars.end(), pair<string,Interpretable*>(varName, new Test1));
else if(className == "Test2")
vars.insert(vars.end(), pair<string,Interpretable*>(varName, new Test2));
throw "Invalid type";
Interpretable* FindVariable(const string& varName)
map<string,Interpretable*>::iterator it = vars.find(varName);
if(it == vars.end())
Obviously, this type of checking, particularly with many classes and in many places throughout the code, is pretty ugly. My ideal is to be able to define some class (say Test1) and follow it with some blanket MAKE_INTERPRETABLE(Test1, "Test1") macro, requiring no later modification to, say, the Scope class to make Test1 universally supported... I just have no idea how to make that work, or, after much searching, if it's even possible.
Similar problems exist when trying to call functions when you only have a string containing their name.
Any ideas, or is this just misguided and hopeless?
Last edited by jtanama; March 16th, 2011 at 09:14 AM.
March 16th, 2011, 07:14 AM
Re: Using stored class names in script interpreter
The key thing to understand here is that class names and function names only exist at compile time, not at run-time. However, the script is unknown at compile time. Hence, you need to program the translation. I.e. if your script language allows to define variables of a specified type, then you need to program something to translate the type name to a C++ class. If your script language allows to call a member function on a variable, then you need to program something that will translate the member function name, name of the variable the function is called on and function arguments to a function call in C++.
To instantiate an object of a type that is specified at run-time, you can use a factory function quite like what you've show above.
Once you have such an object, you can use inheritance to do other things. E.g. calling a member function (in the script) can be part of the base class interface.
Interpretable* CreateVariable(const std::string& typeName);
virtual Interpretable* CallMemberFunction(const std::string& functionName, const std::vector<Interpretable*>& arguments) = 0;
Cheers, D Drmmr
Please put [code][/code] tags
around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Click Here to Expand Forum to Full Width