ChaiScript
|
ChaiScript is a scripting language designed specifically for integration with C++. It provides seamless integration with C++ on all levels, including shared_ptr objects, functors and exceptions.
The parts of the ChaiScript API that the average user will be concerned with are contained in the chaiscript namespace and the chaiscript::ChaiScript class.
The end user parts of the API are extremely simple both in size and ease of use.
Currently, all source control and project management aspects of ChaiScript occur on github.
Basic simple example:
ChaiScript is a header only library with only one dependency: The operating system provided dynamic library loader, which has to be specified on some platforms.
To compile the above application on a Unix like operating system (MacOS, Linux) with GCC you need to link the dynamic loader. For example:
Alternatively, you may compile without threading support.
Scripts can be evaluated with the () operator, eval method or eval_file method.
operator() can be used as a handy shortcut for evaluating ChaiScript snippets.
The eval method is somewhat more verbose and can be used to get type safely return values from the script.
The 'eval_file' method loads a file from disk and executes the script in it
ChaiScript supports 4 basic things that can be added: objects, functions, type infos and Modules
Named objects can be created with the chaiscript::var function. Note: adding a object adds it to the current thread scope, not to a global scope. If you have multiple threads that need to access the same variables you will need to add them separately for each thread, from the thread itself.
Immutable objects can be created with the chaiscript::const_var function.
Named variables can only be accessed from the context they are created in. If you want a global variable, it must be const, and created with the chaiscript::ChaiScript::add_global_const function.
Functions, methods and members are all added using the same function: chaiscript::fun.
Overloaded methods will need some help, to hint the compiler as to which overload you want:
There are also shortcuts built into chaiscript::fun for binding up to the first two parameters of the function.
ChaiScript will automatically support any type implicitly provided to it in the form of objects and function parameters / return types. However, it can be nice to let ChaiScript know more details about the types you are giving it. For instance, the "clone" functionality cannot work unless there is a copy constructor registered and the name of the type is known (so that ChaiScript can look up the copy constructor).
Continuing with the example "MyClass" from above:
Modules are holders for collections of ChaiScript registrations.
Operators are just like any other function in ChaiScript, to overload an operator, simply register it.
Much of the work of adding new classes to ChaiScript can be reduced with the help of the add_class helper utility.
As much as possible, ChaiScript attempts to convert between &, *, const &, const *, std::shared_ptr<T>, std::shared_ptr<const T>, std::reference_wrapper<T>, std::reference_wrapper<const T> and value types automatically.
If a chaiscript::var object was created in C++ from a pointer, it cannot be converted to a shared_ptr (this would add invalid reference counting). Const may be added, but never removed.
The take away is that you can pretty much expect function calls to Just Work when you need them to.
See the unit test unittests/boxed_cast_test.cpp for a complete breakdown of the automatic casts that available and tested.
ChaiScript supports handling of passing a derived class object to a function expecting a base class object. For the process to work, the base/derived relationship must be registered with the engine.
Functions are first class objects in ChaiScript and ChaiScript supports automatic conversion between ChaiScript functions and std::function objects.
Thread safety is automatically handled within the ChaiScript system. Objects can be added and scripts executed from multiple threads. For each thread that executes scripts, a new context is created and managed by the engine.
Thread safety can be disabled by defining CHAISCRIPT_NO_THREADS when using the library.
Disabling thread safety increases performance in many cases.
Exceptions can be thrown in ChaiScript and caught in C++ or thrown in C++ and caught in ChaiScript.
As an alternative to the manual unboxing of exceptions shown above, exception specifications allow the user to tell ChaiScript what possible exceptions are expected from the script being executed.
Example: