diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp index 92483fd..c07e64c 100644 --- a/include/chaiscript/chaiscript_stdlib.hpp +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -18,6 +18,7 @@ #include "dispatchkit/bootstrap.hpp" #include "dispatchkit/bootstrap_stl.hpp" #include "dispatchkit/boxed_value.hpp" +#include "language/chaiscript_prelude.chai" #ifndef CHAISCRIPT_NO_THREADS #include @@ -47,9 +48,11 @@ namespace chaiscript #ifndef CHAISCRIPT_NO_THREADS lib->add(standard_library::future_type>("future")); - lib->add(chaiscript::fun (const std::function &)>([](const std::function &t_func){ return std::async(std::launch::async, t_func);}), "async"); + lib->add(chaiscript::fun([](const std::function &t_func){ return std::async(std::launch::async, t_func);}), "async"); #endif + lib->eval(ChaiScript_Prelude::chaiscript_prelude() /*, "standard prelude"*/ ); + return lib; } diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index ad31f6b..650124c 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -243,18 +243,18 @@ namespace chaiscript template ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = std::make_shared()) { - // cppcheck-suppress syntaxError - typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); - //In the interest of runtime safety for the m, we prefer the at() method for [] access, //to throw an exception in an out of bounds condition. m->add( - fun(std::function - (std::mem_fn(static_cast(&ContainerType::at)))), "[]"); + fun( + [](ContainerType &c, int index) -> typename ContainerType::reference { + return c.at(index); + }), "[]"); + m->add( fun( - [](const ContainerType *c, int index) -> typename ContainerType::const_reference { - return c->at(index); + [](const ContainerType &c, int index) -> typename ContainerType::const_reference { + return c.at(index); }), "[]"); return m; diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 2344e09..15b4f8c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -251,7 +251,7 @@ namespace chaiscript } template - static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + inline static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { const auto &inp_ = t_rhs.get_type_info(); @@ -292,7 +292,7 @@ namespace chaiscript } } - static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { const Type_Info &inp_ = t_lhs.get_type_info(); diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp new file mode 100644 index 0000000..9954eea --- /dev/null +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -0,0 +1,96 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_ +#define CHAISCRIPT_CALLABLE_TRAITS_HPP_ + +#include + +namespace chaiscript { + namespace dispatch { + namespace detail { + + template + struct Constructor + { + template + std::shared_ptr operator()(Inner&& ... inner) const { + return std::make_shared(std::forward(inner)...); + } + }; + + template + struct Const_Caller + { + Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {} + + template + Ret operator()(const Class &o, Inner&& ... inner) const { + return (o.*m_func)(std::forward(inner)...); + } + + Ret (Class::*m_func)(Param...) const; + }; + + template + struct Fun_Caller + { + Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {} + + template + Ret operator()(Inner&& ... inner) const { + return (m_func)(std::forward(inner)...); + } + + Ret(*m_func)(Param...); + }; + + template + struct Caller + { + Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {} + + template + Ret operator()(Class &o, Inner&& ... inner) const { + return (o.*m_func)(std::forward(inner)...); + } + + Ret (Class::*m_func)(Param...); + }; + + + template + struct Function_Signature + { + }; + + template + struct Function_Signature + { + typedef Ret Return_Type; + typedef Ret (Signature)(Params...); + }; + + template + struct Function_Signature + { + typedef Ret Return_Type; + typedef Ret (Signature)(Params...); + }; + + + template + struct Callable_Traits + { + typedef typename Function_Signature::Signature Signature; + typedef typename Function_Signature::Return_Type Return_Type; + }; + } + } +} + +#endif + diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 9410d15..fb6b5fc 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -95,6 +95,7 @@ namespace chaiscript template std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Type_Conversions *t_conversions) { + /* if (funcs.size() == 1) { std::shared_ptr> pfi = @@ -108,6 +109,7 @@ namespace chaiscript // looks like this either wasn't a Proxy_Function_Impl or the types didn't match // we cannot make any other guesses or assumptions really, so continuing } +*/ return std::function(Build_Function_Caller_Helper(funcs, t_conversions?*t_conversions:Type_Conversions())); } diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index d028e85..e3a8254 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include "boxed_number.hpp" @@ -23,7 +22,7 @@ namespace chaiscript { namespace dispatch { - template class Proxy_Function_Impl; + template class Proxy_Function_Callable_Impl; template class Assignable_Proxy_Function_Impl; namespace detail @@ -54,7 +53,7 @@ namespace chaiscript { static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>(f) + chaiscript::make_shared>>(f) ); } }; @@ -64,7 +63,7 @@ namespace chaiscript { static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>(f) + chaiscript::make_shared>>(f) ); } }; @@ -111,7 +110,7 @@ namespace chaiscript static Boxed_Value handle(const std::function &f) { return Boxed_Value( - chaiscript::make_shared>(f) + chaiscript::make_shared>>(f) ); } }; diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index 2866d97..063c557 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -16,21 +16,14 @@ namespace chaiscript { namespace detail { - /** - * A constructor function, used for creating a new object - * of a given type with a given set of params - */ - template - std::shared_ptr constructor_(Params ... params) - { - return std::make_shared(params...); - } template Proxy_Function build_constructor_(Class (*)(Params...)) { - typedef std::shared_ptr (sig)(Params...); - return Proxy_Function(static_cast(new Proxy_Function_Impl(std::function(&(constructor_))))); + auto call = dispatch::detail::Constructor(); + + return Proxy_Function( + chaiscript::make_shared (Params...), decltype(call)>>(call)); } } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 39011ca..e0a413a 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -549,48 +549,44 @@ namespace chaiscript virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const = 0; }; - /// The standard typesafe function call implementation of Proxy_Function - /// It takes a std::function<> object and performs runtime - /// type checking of Boxed_Value parameters, in a type safe manner - template - class Proxy_Function_Impl : public Proxy_Function_Impl_Base + + + /// For any callable object + template + class Proxy_Function_Callable_Impl : public Proxy_Function_Impl_Base { public: - Proxy_Function_Impl(std::function f) + Proxy_Function_Callable_Impl(Callable f) : Proxy_Function_Impl_Base(detail::build_param_type_list(static_cast(nullptr))), - m_f(std::move(f)), m_dummy_func(nullptr) + m_f(std::move(f)) { } - virtual ~Proxy_Function_Impl() {} + virtual ~Proxy_Function_Callable_Impl() {} virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::compare_types_cast(m_dummy_func, vals, t_conversions); + return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE { - return dynamic_cast *>(&t_func) != nullptr; + return dynamic_cast *>(&t_func) != nullptr; } - std::function internal_function() const - { - return m_f; - } protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::Do_Call::result_type>::go(m_f, params, t_conversions); + typedef typename detail::Function_Signature::Return_Type Return_Type; + return detail::Do_Call::template go(m_f, params, t_conversions); } - private: - std::function m_f; - Func *m_dummy_func; + Callable m_f; }; + class Assignable_Proxy_Function : public Proxy_Function_Impl_Base { public: @@ -613,17 +609,16 @@ namespace chaiscript public: Assignable_Proxy_Function_Impl(std::reference_wrapper> t_f, std::shared_ptr> t_ptr) : Assignable_Proxy_Function(detail::build_param_type_list(static_cast(nullptr))), - m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr)), m_dummy_func(nullptr) + m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr)) { assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get()); - } virtual ~Assignable_Proxy_Function_Impl() {} virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::compare_types_cast(m_dummy_func, vals, t_conversions); + return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE @@ -643,14 +638,13 @@ namespace chaiscript protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return detail::Do_Call::result_type>::go(m_f.get(), params, t_conversions); + return detail::Do_Call::result_type>::template go(m_f.get(), params, t_conversions); } private: std::reference_wrapper> m_f; std::shared_ptr> m_shared_ptr_holder; - Func *m_dummy_func; }; /// Attribute getter Proxy_Function implementation template diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index ccfe83f..130d3c1 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -16,6 +16,7 @@ #include "boxed_value.hpp" #include "handle_return.hpp" #include "type_info.hpp" +#include "callable_traits.hpp" namespace chaiscript { class Type_Conversions; @@ -68,6 +69,7 @@ namespace chaiscript #ifdef CHAISCRIPT_GCC_4_6 /// \todo REMOVE THIS WHEN WE DROP G++4.6 + // Forward declaration template struct Try_Cast; @@ -100,7 +102,7 @@ namespace chaiscript template bool compare_types_cast(Ret (*)(Params...), const std::vector ¶ms, const Type_Conversions &t_conversions) - { + { try { Try_Cast::do_try(params, 0, t_conversions); } catch (const exception::bad_boxed_cast &) { @@ -114,8 +116,8 @@ namespace chaiscript struct Call_Func { - template - static Ret do_call(const std::function &f, + template + static Ret do_call(const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams) { return Call_Func::do_call(f, params, t_conversions, std::forward(innerparams)..., params[sizeof...(Params) - count]); @@ -129,8 +131,8 @@ namespace chaiscript #pragma warning(push) #pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this #endif - template - static Ret do_call(const std::function &f, + template + static Ret do_call(const Callable &f, const std::vector &, const Type_Conversions &t_conversions, InnerParams &&... innerparams) { return f(boxed_cast(std::forward(innerparams), &t_conversions)...); @@ -146,8 +148,8 @@ namespace chaiscript * if any unboxing fails the execution of the function fails and * the bad_boxed_cast is passed up to the caller. */ - template - Ret call_func(const std::function &f, + template + Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions) { if (params.size() == sizeof...(Params)) @@ -158,6 +160,8 @@ namespace chaiscript throw exception::arity_error(static_cast(params.size()), sizeof...(Params)); } + + #else template @@ -206,8 +210,9 @@ namespace chaiscript return compare_types_cast(indexes(), f, params, t_conversions); } - template - Ret call_func(Indexes, const std::function &f, + + template + Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, Indexes, const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions) { (void)params; (void)t_conversions; @@ -221,17 +226,12 @@ namespace chaiscript * if any unboxing fails the execution of the function fails and * the bad_boxed_cast is passed up to the caller. */ - template - Ret call_func(const std::function &f, + template + Ret call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, const std::vector ¶ms, const Type_Conversions &t_conversions) { - if (params.size() == sizeof...(Params)) - { - typedef typename Make_Indexes::indexes indexes; - return call_func(indexes(), f, params, t_conversions); - } - - throw exception::arity_error(static_cast(params.size()), sizeof...(Params)); + typedef typename Make_Indexes::indexes indexes; + return call_func(sig, indexes(), f, params, t_conversions); } #endif @@ -251,20 +251,20 @@ namespace chaiscript template struct Do_Call { - template - static Boxed_Value go(const std::function &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) + template + static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) { - return Handle_Return::handle(call_func(fun, params, t_conversions)); + return Handle_Return::handle(call_func(Function_Signature(), fun, params, t_conversions)); } }; template<> struct Do_Call { - template - static Boxed_Value go(const std::function &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) + template + static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) { - call_func(fun, params, t_conversions); + call_func(Function_Signature(), fun, params, t_conversions); return Handle_Return::handle(); } }; diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 4998ede..598dd8b 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -7,7 +7,6 @@ #ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_ #define CHAISCRIPT_REGISTER_FUNCTION_HPP_ -#include #include #include "bind_first.hpp" @@ -15,75 +14,6 @@ namespace chaiscript { - namespace dispatch - { - namespace detail - { - template - struct FunctionSignature - { - }; - - template - struct FunctionSignature > - { - typedef Sig Signature; - }; - - template - std::function to_function(Ret (*func)(Args...)) - { - return std::function(func); - } - - - template - std::function to_function(Ret (Class::*func)(Args...)) - { -#ifdef CHAISCRIPT_MSVC - /// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for - /// std::function for member function pointers seems to be broken in MSVC - return std::function(std::mem_fn(func)); -#else - return std::function(func); -#endif - } - - template - std::function to_function(Ret (Class::*func)(Args...) const) - { -#if defined(CHAISCRIPT_MSVC) || defined(CHAISCRIPT_LIBCPP) - /// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for - /// std::function for member function pointers seems to be broken in MSVC - return std::function([func](const Class &o, Args... args)->Ret { - return (o.*func)(std::forward(args)...); - }); -#else - return std::function(func); -#endif - } - - template - std::function to_function_callable(Ret (Class::*)(Args...), T t) - { - return std::function(t); - } - - template - std::function to_function_callable(Ret (Class::*)(Args...) const, T t) - { - return std::function(t); - } - - - template - auto to_function(T t) -> decltype(to_function_callable(&T::operator(), t)) - { - return to_function_callable(&T::operator(), t); - } - - } - } /// \brief Creates a new Proxy_Function object from a free function, member function or data member /// \param[in] t Function / member to expose @@ -108,22 +38,39 @@ namespace chaiscript template Proxy_Function fun(const T &t) { + typedef typename dispatch::detail::Callable_Traits::Signature Signature; + return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(t))); + chaiscript::make_shared>(t)); + } + + template + Proxy_Function fun(Ret (*func)(Param...)) + { + auto fun_call = dispatch::detail::Fun_Caller(func); + + return Proxy_Function( + chaiscript::make_shared>(fun_call)); + } template - Proxy_Function fun(Ret (Class::*func)(Param...) const) + Proxy_Function fun(Ret (Class::*t_func)(Param...) const) { + auto call = dispatch::detail::Const_Caller(t_func); + return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(func))); + chaiscript::make_shared>(call)); } template - Proxy_Function fun(Ret (Class::*func)(Param...)) + Proxy_Function fun(Ret (Class::*t_func)(Param...)) { + auto call = dispatch::detail::Caller(t_func); + return Proxy_Function( - chaiscript::make_shared::Signature>>(dispatch::detail::to_function(func))); + chaiscript::make_shared>(call)); + } @@ -134,22 +81,6 @@ namespace chaiscript } - /// \brief Creates a new Proxy_Function object from a std::function object - /// \param[in] f std::function to expose to ChaiScript - /// - /// \b Example: - /// \code - /// std::function f = get_some_function(); - /// chaiscript::ChaiScript chai; - /// chai.add(fun(f), "some_function"); - /// \endcode - /// - /// \sa \ref adding_functions - template - Proxy_Function fun(const std::function &f) - { - return Proxy_Function(chaiscript::make_shared>(f)); - } /// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 5b3602b..a7d3bad 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -44,7 +44,6 @@ #include "../dispatchkit/exception_specification.hpp" #include "chaiscript_parser.hpp" -#include "chaiscript_prelude.chai" namespace chaiscript { @@ -356,13 +355,14 @@ namespace chaiscript add(t_lib); } - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, std::ref(m_engine)), "dump_system"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, std::ref(m_engine)), "dump_object"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, std::ref(m_engine)), "is_type"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, std::ref(m_engine)), "type_name"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, std::ref(m_engine)), "function_exists"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, std::ref(m_engine)), "get_functions"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, std::ref(m_engine)), "get_objects"); + m_engine.add(fun([this](){ m_engine.dump_system(); }), "dump_system"); + m_engine.add(fun([this](const Boxed_Value &t_bv){ m_engine.dump_object(t_bv); }), "dump_object"); + 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"); + m_engine.add(fun([this](const Boxed_Value &t_bv){ return m_engine.type_name(t_bv); }), "type_name"); + m_engine.add(fun([this](const std::string &t_f){ return m_engine.function_exists(t_f); }), "function_exists"); + m_engine.add(fun([this](){ return m_engine.get_function_objects(); }), "get_functions"); + m_engine.add(fun([this](){ return m_engine.get_scripting_objects(); }), "get_objects"); + m_engine.add(chaiscript::make_shared( [this](const std::vector &t_params) { return m_engine.call_exists(t_params); @@ -375,10 +375,10 @@ namespace chaiscript return t_fun(t_params, this->m_engine.conversions()); }), "call"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name"); + m_engine.add(fun([this](const Type_Info &t_ti){ return m_engine.get_type_name(t_ti); }), "name"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type, std::ref(m_engine)), "type"); - m_engine.add(fun([this](const std::string &t_type_name){ return this->m_engine.get_type(t_type_name, true); }), "type"); + 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"); + m_engine.add(fun([this](const std::string &t_type_name){ return m_engine.get_type(t_type_name, true); }), "type"); m_engine.add(fun( [=](const Type_Info &t_from, const Type_Info &t_to, const std::function &t_func) { @@ -387,26 +387,23 @@ namespace chaiscript ), "add_type_conversion"); - typedef std::string (ChaiScript::*load_mod_1)(const std::string&); - typedef void (ChaiScript::*load_mod_2)(const std::string&, const std::string&); - m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); - m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); + m_engine.add(fun([this](const std::string &t_module, const std::string &t_file){ return load_module(t_module, t_file); }), "load_module"); + m_engine.add(fun([this](const std::string &t_module){ return load_module(t_module); }), "load_module"); - m_engine.add(fun(&ChaiScript::use, this), "use"); - m_engine.add(fun(&ChaiScript::internal_eval_file, this), "eval_file"); - m_engine.add(fun(&ChaiScript::internal_eval, this), "eval"); - m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval"); + m_engine.add(fun([this](const std::string &t_file){ return use(t_file); }), "use"); + m_engine.add(fun([this](const std::string &t_file){ return internal_eval_file(t_file); }), "eval_file"); + m_engine.add(fun([this](const std::string &t_str){ return internal_eval(t_str); }), "eval"); + m_engine.add(fun([this](const AST_NodePtr &t_ast){ return internal_eval_ast(t_ast); }), "eval"); m_engine.add(fun(&ChaiScript::version_major), "version_major"); m_engine.add(fun(&ChaiScript::version_minor), "version_minor"); m_engine.add(fun(&ChaiScript::version_patch), "version_patch"); m_engine.add(fun(&ChaiScript::version), "version"); - m_engine.add(fun(&ChaiScript::add_global_const, this), "add_global_const"); - m_engine.add(fun(&ChaiScript::add_global, this), "add_global"); + m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const"); + m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global"); - do_eval(ChaiScript_Prelude::chaiscript_prelude(), "standard prelude"); } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 2e8a922..895dcad 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1418,36 +1418,40 @@ namespace chaiscript std::shared_ptr guard; if (guardnode) { guard = std::make_shared - (std::bind(chaiscript::eval::detail::eval_function, - std::ref(t_ss), guardnode, - t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), guardnode); + ([&t_ss, t_param_names, guardnode](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, guardnode, t_param_names, t_params, std::map()); + }, static_cast(numparams), guardnode); } try { const std::string & l_annotation = annotation?annotation->text:""; - const std::string & function_name = children[static_cast(1 + class_offset)]->text; + auto node = children.back(); if (function_name == class_name) { param_types.push_front(class_name, Type_Info()); - t_ss.add(std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, - std::ref(t_ss), children.back(), t_param_names, std::placeholders::_1, std::map()), - static_cast(numparams), children.back(), param_types, l_annotation, guard)), + + t_ss.add(std::make_shared(class_name, + std::make_shared( + [&t_ss, t_param_names, node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map()); + }, + static_cast(numparams), node, param_types, l_annotation, guard)), function_name); } else { - // if the type is unknown, then this generates a function that looks up the type // at runtime. Defining the type first before this is called is better auto type = t_ss.get_type(class_name, false); param_types.push_front(class_name, type); - t_ss.add( - std::make_shared(class_name, - std::make_shared(std::bind(chaiscript::eval::detail::eval_function, - std::ref(t_ss), children.back(), - t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), children.back(), - param_types, l_annotation, guard), type), function_name); + t_ss.add(std::make_shared(class_name, + std::make_shared( + [&t_ss, t_param_names, node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map()); + }, + static_cast(numparams), node, param_types, l_annotation, guard), type), + function_name); } } catch (const exception::reserved_word_error &e) { @@ -1473,15 +1477,14 @@ namespace chaiscript std::string class_name = (itr != d.end())?std::string(boxed_cast(itr->second)):this->children[0]->text; try { + std::string attr_name = this->children[static_cast(1 + class_offset)]->text; + t_ss.add( std::make_shared( std::move(class_name), - fun(std::function( - std::bind(static_cast(&dispatch::Dynamic_Object::get_attr), - std::placeholders::_1, - this->children[static_cast(1 + class_offset)]->text - )) - ), + fun([attr_name](dispatch::Dynamic_Object &t_obj) { + return t_obj.get_attr(attr_name); + }), true ), this->children[static_cast(1 + class_offset)]->text); diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 1fdc4f5..7588d40 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -7,8 +7,6 @@ #ifndef CHAISCRIPT_PARSER_HPP_ #define CHAISCRIPT_PARSER_HPP_ -#include -#include #include #include #include @@ -16,6 +14,8 @@ #include #include #include +#include + #include "../dispatchkit/boxed_value.hpp" #include "chaiscript_common.hpp" diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index b49f90e..c856e9a 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -37,8 +37,7 @@ TEST_CASE("C++11 Lambdas Can Be Registered") // in an std::function or provide the signature chaiscript::ChaiScript chai; - // provide the signature - chai.add(chaiscript::fun([] { return "hello"; } ), "f1"); + chai.add(chaiscript::fun([]()->std::string { return "hello"; } ), "f1"); // wrap chai.add(chaiscript::fun(std::function([] { return "world"; } )), "f2");