11#ifndef CHAISCRIPT_ENGINE_HPP_
12#define CHAISCRIPT_ENGINE_HPP_
35#if defined(__linux__) || defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
39#if !defined(CHAISCRIPT_NO_DYNLOAD) && defined(_POSIX_VERSION) && !defined(__CYGWIN__)
43#if defined(CHAISCRIPT_NO_DYNLOAD)
45#elif defined(CHAISCRIPT_WINDOWS)
71 mutable chaiscript::detail::threading::recursive_mutex m_use_mutex;
73 std::set<std::string> m_used_files;
74 std::map<std::string, detail::Loadable_Module_Ptr> m_loaded_modules;
75 std::set<std::string> m_active_loaded_modules;
77 std::vector<std::string> m_module_paths;
78 std::vector<std::string> m_use_paths;
80 std::unique_ptr<parser::ChaiScript_Parser_Base> m_parser;
84 std::map<std::string, std::function<
Namespace&()>> m_namespace_generators;
87 Boxed_Value do_eval(
const std::string &t_input,
const std::string &t_filename =
"__EVAL__",
bool =
false)
90 const auto p = m_parser->parse(t_input, t_filename);
101 const Boxed_Value internal_eval_file(
const std::string &t_filename) {
102 for (
const auto &path : m_use_paths)
105 const auto appendedpath = path + t_filename;
106 return do_eval(load_file(appendedpath), appendedpath,
true);
122 const Boxed_Value internal_eval(
const std::string &t_e) {
124 return do_eval(t_e,
"__EVAL__",
true);
136 void build_eval_system(
const ModulePtr &t_lib,
const std::vector<Options> &t_opts) {
142 m_engine.
add(
fun([
this](){ m_engine.dump_system(); }),
"dump_system");
143 m_engine.add(
fun([
this](
const Boxed_Value &t_bv){ m_engine.dump_object(t_bv); }),
"dump_object");
144 m_engine.add(
fun([
this](
const Boxed_Value &t_bv,
const std::string &t_type){
return m_engine.is_type(t_bv, t_type); }),
"is_type");
145 m_engine.add(
fun([
this](
const Boxed_Value &t_bv){
return m_engine.type_name(t_bv); }),
"type_name");
146 m_engine.add(
fun([
this](
const std::string &t_f){
return m_engine.function_exists(t_f); }),
"function_exists");
147 m_engine.add(
fun([
this](){
return m_engine.get_function_objects(); }),
"get_functions");
148 m_engine.add(
fun([
this](){
return m_engine.get_scripting_objects(); }),
"get_objects");
152 [
this](
const std::vector<Boxed_Value> &t_params) {
153 return m_engine.call_exists(t_params);
161 return t_fun(t_params, s);
165 m_engine.add(
fun([
this](
const Type_Info &t_ti){
return m_engine.get_type_name(t_ti); }),
"name");
167 m_engine.add(
fun([
this](
const std::string &t_type_name,
bool t_throw){
return m_engine.get_type(t_type_name, t_throw); }),
"type");
168 m_engine.add(
fun([
this](
const std::string &t_type_name){
return m_engine.get_type(t_type_name,
true); }),
"type");
174 ),
"add_type_conversion");
181 m_engine.add(
fun([
this](
const std::string &t_module,
const std::string &t_file){
return load_module(t_module, t_file); }),
"load_module");
182 m_engine.add(
fun([
this](
const std::string &t_module){
return load_module(t_module); }),
"load_module");
188 m_engine.add(
fun([
this](
const std::string &t_file){
return use(t_file); }),
"use");
189 m_engine.add(
fun([
this](
const std::string &t_file){
return internal_eval_file(t_file); }),
"eval_file");
192 m_engine.add(
fun([
this](
const std::string &t_str){
return internal_eval(t_str); }),
"eval");
193 m_engine.add(
fun([
this](
const AST_Node &t_ast){
return eval(t_ast); }),
"eval");
195 m_engine.add(
fun([
this](
const std::string &t_str,
const bool t_dump){
return parse(t_str, t_dump); }),
"parse");
196 m_engine.add(
fun([
this](
const std::string &t_str){
return parse(t_str); }),
"parse");
200 m_engine.add(
fun([
this](
const Boxed_Value &t_bv,
const std::string &t_name){
add_global(t_bv, t_name); }),
"add_global");
201 m_engine.add(
fun([
this](
const Boxed_Value &t_bv,
const std::string &t_name){
set_global(t_bv, t_name); }),
"set_global");
203 m_engine.add(
fun([
this](
const std::string& t_namespace_name) {
register_namespace([](
Namespace& ) {}, t_namespace_name);
import(t_namespace_name); }),
"namespace");
204 m_engine.add(
fun([
this](
const std::string& t_namespace_name) {
import(t_namespace_name); }),
"import");
208 static bool skip_bom(std::ifstream &infile) {
209 size_t bytes_needed = 3;
212 memset(buffer,
'\0', bytes_needed);
214 infile.read(buffer,
static_cast<std::streamsize
>(bytes_needed));
216 if ((buffer[0] ==
'\xef')
217 && (buffer[1] ==
'\xbb')
218 && (buffer[2] ==
'\xbf')) {
230 static std::string load_file(
const std::string &t_filename) {
231 std::ifstream infile(t_filename.c_str(), std::ios::in | std::ios::ate | std::ios::binary );
233 if (!infile.is_open()) {
237 auto size = infile.tellg();
238 infile.seekg(0, std::ios::beg);
242 if (skip_bom(infile)) {
247 if (
size == std::streampos(0))
249 return std::string();
251 std::vector<char> v(
static_cast<size_t>(
size));
252 infile.read(&v[0],
static_cast<std::streamsize
>(
size));
253 return std::string(v.begin(), v.end());
257 std::vector<std::string> ensure_minimum_path_vec(std::vector<std::string> paths)
259 if (paths.empty()) {
return {
""}; }
260 else {
return paths; }
270 std::unique_ptr<parser::ChaiScript_Parser_Base> &&
parser,
271 std::vector<std::string> t_module_paths = {},
272 std::vector<std::string> t_use_paths = {},
273 const std::vector<chaiscript::Options> &t_opts = chaiscript::default_options())
274 : m_module_paths(ensure_minimum_path_vec(
std::move(t_module_paths))),
275 m_use_paths(ensure_minimum_path_vec(
std::move(t_use_paths))),
276 m_parser(
std::move(parser)),
279#if !defined(CHAISCRIPT_NO_DYNLOAD) && defined(_POSIX_VERSION) && !defined(__CYGWIN__)
285 Boxed_Value (ChaiScript_Basic::*in_ptr)(
const std::string&);
290 memset( &rInfo, 0,
sizeof(rInfo) );
293 if ( (dladdr(
static_cast<void*
>(u.out_ptr), &rInfo) != 0) && (rInfo.dli_fname !=
nullptr) ) {
294 std::string dllpath(rInfo.dli_fname);
295 const size_t lastslash = dllpath.rfind(
'/');
296 if (lastslash != std::string::npos)
298 dllpath.erase(lastslash);
302 std::vector<char> buf(2048);
303 const auto pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size());
304 if (pathlen > 0 &&
static_cast<size_t>(pathlen) < buf.size())
306 dllpath = std::string(&buf.front(),
static_cast<size_t>(pathlen));
309 m_module_paths.insert(m_module_paths.begin(), dllpath+
"/");
312 build_eval_system(t_lib, t_opts);
315#ifndef CHAISCRIPT_NO_DYNLOAD
324 std::vector<std::string> t_module_paths = {},
325 std::vector<std::string> t_use_paths = {},
326 const std::vector<chaiscript::Options> &t_opts = chaiscript::default_options())
327 :
ChaiScript_Basic({}, std::move(parser), t_module_paths, t_use_paths, t_opts)
332 }
catch (
const exception::load_module_error &t_err) {
333 std::cout <<
"An error occured while trying to load the chaiscript standard library.\n"
335 <<
"You must either provide a standard library, or compile it in.\n"
336 <<
"For an example of compiling the standard library in,\n"
337 <<
"see: https://gist.github.com/lefticus/9456197\n"
338 <<
"Compiling the stdlib in is the recommended and MOST SUPPORTED method.\n"
346explicit ChaiScript_Basic(std::unique_ptr<parser::ChaiScript_Parser_Base> &&parser,
347 std::vector<std::string> t_module_paths = {},
348 std::vector<std::string> t_use_paths = {},
349 const std::vector<chaiscript::Options> &t_opts = chaiscript::default_options()) =
delete;
368 auto ast = m_parser->parse(t_input,
"PARSE");
370 m_parser->debug_print(*ast);
378 return m_engine.get_type_name(ti);
395 for (
const auto &path : m_use_paths)
397 const auto appendedpath = path + t_filename;
405 if (m_used_files.count(appendedpath) == 0)
410 m_used_files.insert(appendedpath);
415 if (
e.filename != appendedpath) {
435 m_engine.add_global_const(t_bv, t_name);
447 m_engine.add_global(t_bv, t_name);
454 m_engine.set_global(t_bv, t_name);
490 s.engine_state = m_engine.get_state();
491 s.active_loaded_modules = m_active_loaded_modules;
522 return m_engine.get_locals();
530 void set_locals(
const std::map<std::string, Boxed_Value> &t_locals)
532 m_engine.set_locals(t_locals);
554 m_engine.add(t_t, t_name);
578 t_p->apply(*
this, this->get_eval_engine());
596#ifdef CHAISCRIPT_NO_DYNLOAD
600 std::vector<exception::load_module_error> errors;
601 std::string version_stripped_name = t_module_name;
603 if (version_pos != std::string::npos)
605 version_stripped_name.erase(version_pos);
608 std::vector<std::string> prefixes{
"lib",
"cyg",
""};
610 std::vector<std::string> postfixes{
".dll",
".so",
".bundle",
""};
612 for (
auto & elem : m_module_paths)
614 for (
auto & prefix : prefixes)
616 for (
auto & postfix : postfixes)
619 const auto name = elem + prefix + t_module_name + postfix;
643 void load_module(
const std::string &t_module_name,
const std::string &t_filename)
647 if (m_loaded_modules.count(t_module_name) == 0)
650 m_loaded_modules[t_module_name] = lm;
651 m_active_loaded_modules.insert(t_module_name);
652 add(lm->m_moduleptr);
653 }
else if (m_active_loaded_modules.count(t_module_name) == 0) {
654 m_active_loaded_modules.insert(t_module_name);
655 add(m_loaded_modules[t_module_name]->m_moduleptr);
670 return eval(t_script, t_handler);
689 return m_engine.boxed_cast<
T>(
eval(t_input, t_handler, t_filename));
693 template<
typename Type>
696 return(m_engine.boxed_cast<
Type>(bv));
713 return do_eval(t_input, t_filename);
716 t_handler->handle(bv, m_engine);
728 return eval(load_file(t_filename), t_handler, t_filename);
741 return m_engine.boxed_cast<
T>(
eval_file(t_filename, t_handler));
747 void import(
const std::string& t_namespace_name)
751 if (m_engine.get_scripting_objects().count(t_namespace_name)) {
752 throw std::runtime_error(
"Namespace: " + t_namespace_name +
" was already defined");
754 else if (m_namespace_generators.count(t_namespace_name)) {
755 m_engine.add_global(
var(std::ref(m_namespace_generators[t_namespace_name]())), t_namespace_name);
758 throw std::runtime_error(
"No registered namespace: " + t_namespace_name);
770 if (!m_namespace_generators.count(t_namespace_name)) {
772 m_namespace_generators.emplace(std::make_pair(t_namespace_name, [=, space =
Namespace()]()
mutable ->
Namespace& { t_namespace_generator(space);
return space; }));
775 throw std::runtime_error(
"Namespace: " + t_namespace_name +
" was already registered.");
Env e
Definition Common.cc:2
Type
Definition Database.hh:9
A wrapper for holding any valid C++ type. All types in ChaiScript are Boxed_Value objects.
Definition boxed_value.hpp:28
void load_module(const std::string &t_module_name, const std::string &t_filename)
Load a binary module from a dynamic library. Works on platforms that support dynamic libraries.
Definition chaiscript_engine.hpp:643
ChaiScript_Basic & add(const Type_Conversion &d)
Add a new conversion for upcasting to a base class.
Definition chaiscript_engine.hpp:567
std::map< std::string, Boxed_Value > get_locals() const
Definition chaiscript_engine.hpp:520
const Boxed_Value eval(const AST_Node &t_ast)
Definition chaiscript_engine.hpp:357
T eval_file(const std::string &t_filename, const Exception_Handler &t_handler=Exception_Handler())
Loads the file specified by filename, evaluates it, and returns the type safe result.
Definition chaiscript_engine.hpp:740
std::string load_module(const std::string &t_module_name)
Load a binary module from a dynamic library. Works on platforms that support dynamic libraries.
Definition chaiscript_engine.hpp:594
ChaiScript_Basic(std::unique_ptr< parser::ChaiScript_Parser_Base > &&parser, std::vector< std::string > t_module_paths={}, std::vector< std::string > t_use_paths={}, const std::vector< chaiscript::Options > &t_opts=chaiscript::default_options())
Constructor for ChaiScript.
Definition chaiscript_engine.hpp:323
void set_locals(const std::map< std::string, Boxed_Value > &t_locals)
Sets all of the locals for the current thread state.
Definition chaiscript_engine.hpp:530
ChaiScript_Basic & add_global_const(const Boxed_Value &t_bv, const std::string &t_name)
Adds a constant object that is available in all contexts and to all threads.
Definition chaiscript_engine.hpp:432
Boxed_Value eval(const std::string &t_input, const Exception_Handler &t_handler=Exception_Handler(), const std::string &t_filename="__EVAL__")
Evaluates a string.
Definition chaiscript_engine.hpp:710
decltype(auto) boxed_cast(const Boxed_Value &bv) const
casts an object while applying any Dynamic_Conversion available
Definition chaiscript_engine.hpp:694
ChaiScript_Basic & add(const T &t_t, const std::string &t_name)
Adds a type, function or object to ChaiScript. Objects are added to the local thread state.
Definition chaiscript_engine.hpp:551
AST_NodePtr parse(const std::string &t_input, const bool t_debug_print=false)
Definition chaiscript_engine.hpp:366
State get_state() const
Returns a state object that represents the current state of the global system.
Definition chaiscript_engine.hpp:483
Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler=Exception_Handler())
Loads the file specified by filename, evaluates it, and returns the result.
Definition chaiscript_engine.hpp:727
void register_namespace(const std::function< void(Namespace &)> &t_namespace_generator, const std::string &t_namespace_name)
Registers a namespace generator, which delays generation of the namespace until it is imported,...
Definition chaiscript_engine.hpp:766
ChaiScript_Basic(const ModulePtr &t_lib, std::unique_ptr< parser::ChaiScript_Parser_Base > &&parser, std::vector< std::string > t_module_paths={}, std::vector< std::string > t_use_paths={}, const std::vector< chaiscript::Options > &t_opts=chaiscript::default_options())
Constructor for ChaiScript.
Definition chaiscript_engine.hpp:269
void set_state(const State &t_state)
Sets the state of the system.
Definition chaiscript_engine.hpp:509
Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler=Exception_Handler())
Evaluates a string. Equivalent to ChaiScript::eval.
Definition chaiscript_engine.hpp:668
T eval(const std::string &t_input, const Exception_Handler &t_handler=Exception_Handler(), const std::string &t_filename="__EVAL__")
Evaluates a string and returns a typesafe result.
Definition chaiscript_engine.hpp:687
Boxed_Value use(const std::string &t_filename)
Loads and parses a file. If the file is already, it is not reloaded The use paths specified at ChaiSc...
Definition chaiscript_engine.hpp:393
ChaiScript_Basic & add_global(const Boxed_Value &t_bv, const std::string &t_name)
Adds a mutable object that is available in all contexts and to all threads.
Definition chaiscript_engine.hpp:444
ChaiScript_Basic & set_global(const Boxed_Value &t_bv, const std::string &t_name)
Definition chaiscript_engine.hpp:451
std::string get_type_name() const
Definition chaiscript_engine.hpp:382
std::string get_type_name(const Type_Info &ti) const
Definition chaiscript_engine.hpp:376
ChaiScript_Basic & add(const ModulePtr &t_p)
Adds all elements of a module to ChaiScript runtime.
Definition chaiscript_engine.hpp:576
parser::ChaiScript_Parser_Base & get_parser()
Definition chaiscript_engine.hpp:352
Definition type_conversions.hpp:512
Conversion_Saves & conversion_saves() const
Definition type_conversions.hpp:466
Compile time deduced information about a type.
Definition type_info.hpp:34
Definition dispatchkit.hpp:438
void add(const Type_Conversion &d)
Add a new conversion for upcasting to a base class.
Definition dispatchkit.hpp:469
const Type_Conversions & conversions() const
Definition dispatchkit.hpp:933
Definition dispatchkit.hpp:1513
Definition dynamic_object.hpp:44
Definition proxy_functions.hpp:196
Definition chaiscript_common.hpp:623
d
Definition meshpage.php:3895
iVBORw0KGgoAAAANSUhEUgAAANcAAAB5CAMAAACdtUQZAAAA51BMVEX</div ></div >< div style="padding: 0px 0px; width: 1324px;">< div style="height: 400px; width: 1324px;"></div >< div itemscope itemtype="https: </div><div itemscope itemtype="https:</div >< div itemscope itemtype="https: </div></div><p><div style="padding:0px 0px;width:1324px;"><div></div><div itemscope itemtype="https:< ul >< li >< b > Application name
8AkrcAgqgAs9wqQ0ey2tkAo8gAuuQfeI4hPUH09fXHy8z4+fng4uNKXF/Lz9BzfoAcgpkQMTUAKjAbOT4Qr9AXhJ8Rl7ktMCwTosA...
Definition meshpage.php:1610
n< br > font size
Definition meshpage.php:3536
std::lock_guard< T > lock_guard
Definition chaiscript_threading.hpp:55
std::unique_lock< T > shared_lock
Definition chaiscript_threading.hpp:52
std::mutex shared_mutex
Definition chaiscript_threading.hpp:58
std::unique_lock< T > unique_lock
Definition chaiscript_threading.hpp:49
Classes and functions reserved for internal use. Items in this namespace are not supported.
std::shared_ptr< Loadable_Module > Loadable_Module_Ptr
Definition chaiscript_engine.hpp:63
Proxy_Function make_dynamic_proxy_function(Callable &&c, Arg &&... a)
Definition proxy_functions.hpp:504
Classes and functions used during the parsing process.
Definition dispatchkit.hpp:44
Namespace chaiscript contains every API call that the average user will be concerned with.
Type_Conversion type_conversion(const Type_Info &t_from, const Type_Info &t_to, const Callable &t_func)
Definition type_conversions.hpp:583
constexpr Type_Info user_type(const T &)
Creates a Type_Info object representing the type passed in.
Definition type_info.hpp:221
@ No_External_Scripts
Definition chaiscript_defines.hpp:231
@ External_Scripts
Definition chaiscript_defines.hpp:232
@ No_Load_Modules
Definition chaiscript_defines.hpp:229
@ Load_Modules
Definition chaiscript_defines.hpp:230
dispatch::Dynamic_Object Namespace
Namespace alias to provide cleaner and more explicit syntax to users.
Definition chaiscript_engine.hpp:59
Proxy_Function fun(const T &t)
Creates a new Proxy_Function object from a free function, member function or data member.
Definition register_function.hpp:43
std::shared_ptr< chaiscript::detail::Type_Conversion_Base > Type_Conversion
Definition type_conversions.hpp:538
Boxed_Value var(T &&t)
Creates a Boxed_Value. If the object passed in is a value type, it is copied. If it is a pointer,...
Definition boxed_value.hpp:387
std::shared_ptr< detail::Exception_Handler_Base > Exception_Handler
Used in the automatic unboxing of exceptions thrown during script evaluation.
Definition exception_specification.hpp:104
std::shared_ptr< Module > ModulePtr
Convenience typedef for Module objects to be added to the ChaiScript runtime.
Definition dispatchkit.hpp:263
std::unique_ptr< AST_Node > AST_NodePtr
Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree.
Definition proxy_functions.hpp:44
Struct that doubles as both a parser ast_node and an AST node.
Definition chaiscript_common.hpp:497
virtual Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const =0
static std::string version()
Definition chaiscript_defines.hpp:122
Represents the current state of the ChaiScript system. State and be saved and restored.
Definition chaiscript_engine.hpp:464
std::set< std::string > active_loaded_modules
Definition chaiscript_engine.hpp:467
std::set< std::string > used_files
Definition chaiscript_engine.hpp:465
chaiscript::detail::Dispatch_Engine::State engine_state
Definition chaiscript_engine.hpp:466
static void validate_object_name(const std::string &name)
Definition chaiscript_common.hpp:48
Definition dispatchkit.hpp:446
Definition chaiscript_posix.hpp:15
Special type for returned values.
Definition chaiscript_common.hpp:651
Boxed_Value retval
Definition chaiscript_common.hpp:652
Errors generated during parsing or evaluation.
Definition chaiscript_common.hpp:168
Errors generated when loading a file.
Definition chaiscript_common.hpp:481
Thrown if an error occurs while attempting to load a binary module.
Definition chaiscript_common.hpp:138