From e024b99b36496e309ce70abff0f1473e959c5de8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 16 Feb 2016 08:29:01 -0700 Subject: [PATCH] Fixes for type_conversion handling --- include/chaiscript/dispatchkit/boxed_cast.hpp | 10 +-- .../dispatchkit/boxed_cast_helper.hpp | 22 +++--- .../chaiscript/dispatchkit/boxed_number.hpp | 2 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 62 +++++++++------- .../dispatchkit/dynamic_object_detail.hpp | 14 ++-- .../chaiscript/dispatchkit/function_call.hpp | 14 ++-- .../dispatchkit/function_call_detail.hpp | 51 ++++++++++---- .../dispatchkit/proxy_functions.hpp | 52 +++++++------- .../dispatchkit/proxy_functions_detail.hpp | 26 +++---- .../dispatchkit/type_conversions.hpp | 70 +++++++++++++------ .../chaiscript/language/chaiscript_common.hpp | 4 +- .../chaiscript/language/chaiscript_engine.hpp | 6 +- .../chaiscript/language/chaiscript_eval.hpp | 28 ++++---- 13 files changed, 216 insertions(+), 145 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index 3880430..44450a0 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -69,9 +69,9 @@ namespace chaiscript /// assert(i == 5); /// \endcode template - typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions *t_conversions = nullptr) + typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr) { - if (!t_conversions || bv.get_type_info().bare_equal(user_type()) || (t_conversions && !t_conversions->convertable_type())) { + if (!t_conversions || bv.get_type_info().bare_equal(user_type()) || (t_conversions && !(*t_conversions)->convertable_type())) { try { return detail::Cast_Helper::cast(bv, t_conversions); } catch (const chaiscript::detail::exception::bad_any_cast &) { @@ -79,18 +79,18 @@ namespace chaiscript } - if (t_conversions && t_conversions->convertable_type()) + if (t_conversions && (*t_conversions)->convertable_type()) { try { // std::cout << "trying an up conversion " << typeid(Type).name() << '\n'; // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it // either way, we are not responsible if it doesn't work - return detail::Cast_Helper::cast(t_conversions->boxed_type_conversion(bv), t_conversions); + return detail::Cast_Helper::cast((*t_conversions)->boxed_type_conversion(t_conversions->saves(), bv), t_conversions); } catch (...) { try { // std::cout << "trying a down conversion " << typeid(Type).name() << '\n'; // try going the other way - down the inheritance graph - return detail::Cast_Helper::cast(t_conversions->boxed_type_down_conversion(bv), t_conversions); + return detail::Cast_Helper::cast((*t_conversions)->boxed_type_down_conversion(t_conversions->saves(), bv), t_conversions); } catch (const chaiscript::detail::exception::bad_any_cast &) { throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type)); } diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index bbcab16..505b1e1 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -16,7 +16,7 @@ namespace chaiscript { - class Type_Conversions; + class Type_Conversions_State; namespace detail { @@ -35,7 +35,7 @@ namespace chaiscript { typedef typename std::add_const::type Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { if (ob.get_type_info().bare_equal_type_info(typeid(Result))) { @@ -58,7 +58,7 @@ namespace chaiscript struct Cast_Helper_Inner { typedef const Result * Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { if (ob.get_type_info().bare_equal_type_info(typeid(Result))) { @@ -74,7 +74,7 @@ namespace chaiscript struct Cast_Helper_Inner { typedef Result * Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result)) { @@ -102,7 +102,7 @@ namespace chaiscript { typedef const Result& Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { if (ob.get_type_info().bare_equal_type_info(typeid(Result))) { @@ -122,7 +122,7 @@ namespace chaiscript { typedef Result& Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result))) { @@ -139,7 +139,7 @@ namespace chaiscript { typedef std::shared_ptr Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { return ob.get().cast >(); } @@ -151,7 +151,7 @@ namespace chaiscript { typedef std::shared_ptr Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { if (!ob.get_type_info().is_const()) { @@ -191,7 +191,7 @@ namespace chaiscript { typedef Boxed_Value Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { return ob; } @@ -203,7 +203,7 @@ namespace chaiscript { typedef std::reference_wrapper Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { return std::ref(const_cast(ob)); } @@ -259,7 +259,7 @@ namespace chaiscript { typedef typename Cast_Helper_Inner::Result_Type Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { return Cast_Helper_Inner::cast(ob, t_conversions); } diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 23e60c7..604d0d0 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -1011,7 +1011,7 @@ namespace chaiscript { typedef Boxed_Number Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) { return Boxed_Number(ob); } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 1f2e9d8..9670d0f 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -314,7 +314,7 @@ namespace chaiscript return arity; } - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return std::any_of(m_funcs.cbegin(), m_funcs.cend(), [&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); }); @@ -326,7 +326,7 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return dispatch::dispatch(m_funcs, params, t_conversions); } @@ -442,7 +442,8 @@ namespace chaiscript template typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) const { - return chaiscript::boxed_cast(bv, &m_conversions); + Type_Conversions_State state(m_conversions, m_conversions.conversion_saves()); + return chaiscript::boxed_cast(bv, &state); } /// Add a new conversion for upcasting to a base class @@ -911,7 +912,7 @@ namespace chaiscript } bool is_attribute_call(const std::vector &t_funs, const std::vector &t_params, - bool t_has_params) const + bool t_has_params, const Type_Conversions_State &t_conversions) const { if (!t_has_params || t_params.empty()) { return false; @@ -919,7 +920,7 @@ namespace chaiscript for (const auto &fun : t_funs) { if (fun->is_attribute_function()) { - if (fun->compare_first_type(t_params[0], m_conversions)) { + if (fun->compare_first_type(t_params[0], t_conversions)) { return true; } } @@ -934,14 +935,15 @@ namespace chaiscript #pragma warning(push) #pragma warning(disable : 4715) #endif - Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, bool t_has_params) + Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, bool t_has_params, + const Type_Conversions_State &t_conversions) { uint_fast32_t loc = t_loc.load(std::memory_order_relaxed); const auto funs = get_function(t_name, loc); if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed); const auto do_attribute_call = - [this](int l_num_params, const std::vector &l_params, const std::vector &l_funs, const Type_Conversions &l_conversions)->Boxed_Value + [this](int l_num_params, const std::vector &l_params, const std::vector &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value { std::vector attr_params{l_params.begin(), l_params.begin() + l_num_params}; Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions); @@ -974,14 +976,14 @@ namespace chaiscript } }; - if (is_attribute_call(*funs.second, params, t_has_params)) { - return do_attribute_call(1, params, *funs.second, m_conversions); + if (is_attribute_call(*funs.second, params, t_has_params, t_conversions)) { + return do_attribute_call(1, params, *funs.second, t_conversions); } else { std::exception_ptr except; if (!funs.second->empty()) { try { - return dispatch::dispatch(*funs.second, params, m_conversions); + return dispatch::dispatch(*funs.second, params, t_conversions); } catch(chaiscript::exception::dispatch_error&) { except = std::current_exception(); } @@ -997,7 +999,7 @@ namespace chaiscript for (const auto &f : *method_missing_funs) { - if(f->compare_first_type(params[0], m_conversions)) { + if(f->compare_first_type(params[0], t_conversions)) { fs.push_back(f); } } @@ -1021,9 +1023,9 @@ namespace chaiscript if (is_no_param) { std::vector tmp_params(params); tmp_params.insert(tmp_params.begin() + 1, var(t_name)); - return do_attribute_call(2, tmp_params, functions, m_conversions); + return do_attribute_call(2, tmp_params, functions, t_conversions); } else { - return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}, m_conversions); + return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}, t_conversions); } } catch (const dispatch::option_explicit_set &e) { throw chaiscript::exception::dispatch_error(params, std::vector(funs.second->begin(), funs.second->end()), @@ -1046,12 +1048,13 @@ namespace chaiscript - Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms) const + Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, + const Type_Conversions_State &t_conversions) const { uint_fast32_t loc = t_loc.load(std::memory_order_relaxed); const auto funs = get_function(t_name, loc); if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed); - return dispatch::dispatch(*funs.second, params, m_conversions); + return dispatch::dispatch(*funs.second, params, t_conversions); } @@ -1105,8 +1108,9 @@ namespace chaiscript } const Const_Proxy_Function &f = this->boxed_cast(params[0]); + const Type_Conversions_State conversions(m_conversions, m_conversions.conversion_saves()); - return Boxed_Value(f->call_match(std::vector(params.begin() + 1, params.end()), m_conversions)); + return Boxed_Value(f->call_match(std::vector(params.begin() + 1, params.end()), conversions)); } /// Dump all system info to stdout @@ -1208,19 +1212,19 @@ namespace chaiscript save_function_params(*m_stack_holder, t_params); } - void new_function_call(Stack_Holder &t_s) + void new_function_call(Stack_Holder &t_s, Type_Conversions::Conversion_Saves &t_saves) { if (t_s.call_depth == 0) { - m_conversions.enable_conversion_saves(true); + m_conversions.enable_conversion_saves(t_saves, true); } ++t_s.call_depth; - save_function_params(m_conversions.take_saves()); + save_function_params(m_conversions.take_saves(t_saves)); } - void pop_function_call(Stack_Holder &t_s) + void pop_function_call(Stack_Holder &t_s, Type_Conversions::Conversion_Saves &t_saves) { --t_s.call_depth; @@ -1229,18 +1233,18 @@ namespace chaiscript if (t_s.call_depth == 0) { t_s.call_params.back().clear(); - m_conversions.enable_conversion_saves(false); + m_conversions.enable_conversion_saves(t_saves, false); } } void new_function_call() { - new_function_call(*m_stack_holder); + new_function_call(*m_stack_holder, m_conversions.conversion_saves()); } void pop_function_call() { - pop_function_call(*m_stack_holder); + pop_function_call(*m_stack_holder, m_conversions.conversion_saves()); } Stack_Holder &get_stack_holder() @@ -1510,7 +1514,8 @@ namespace chaiscript public: Dispatch_State(Dispatch_Engine &t_engine) : m_engine(t_engine), - m_stack_holder(t_engine.get_stack_holder()) + m_stack_holder(t_engine.get_stack_holder()), + m_conversions(t_engine.conversions(), t_engine.conversions().conversion_saves()) { } @@ -1526,6 +1531,14 @@ namespace chaiscript return m_stack_holder.get(); } + const Type_Conversions_State &conversions() const { + return m_conversions; + } + + Type_Conversions::Conversion_Saves &conversion_saves() const { + return m_conversions.saves(); + } + void add_object(const std::string &t_name, Boxed_Value obj) const { m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get()); } @@ -1533,6 +1546,7 @@ namespace chaiscript private: std::reference_wrapper m_engine; std::reference_wrapper m_stack_holder; + Type_Conversions_State m_conversions; }; } } diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index 91fcc7d..8c9b8f6 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -84,7 +84,7 @@ namespace chaiscript virtual bool is_attribute_function() const CHAISCRIPT_OVERRIDE { return m_is_attribute; } - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions)) { @@ -106,7 +106,7 @@ namespace chaiscript protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions)) { @@ -116,7 +116,7 @@ namespace chaiscript } } - virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions); } @@ -134,7 +134,7 @@ namespace chaiscript } bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, - const std::unique_ptr &ti, const Type_Conversions &t_conversions) const + const std::unique_ptr &ti, const Type_Conversions_State &t_conversions) const { if (bv.get_type_info().bare_equal(m_doti)) { @@ -156,7 +156,7 @@ namespace chaiscript } bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, - const std::unique_ptr &ti, const Type_Conversions &t_conversions) const + const std::unique_ptr &ti, const Type_Conversions_State &t_conversions) const { if (bvs.size() > 0) { @@ -216,7 +216,7 @@ namespace chaiscript return dc && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); } - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { std::vector new_vals{Boxed_Value(Dynamic_Object(m_type_name))}; new_vals.insert(new_vals.end(), vals.begin(), vals.end()); @@ -230,7 +230,7 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { auto bv = Boxed_Value(Dynamic_Object(m_type_name), true); std::vector new_params{bv}; diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index e28bf61..ea0a61e 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -18,7 +18,7 @@ namespace chaiscript { class Boxed_Value; -class Type_Conversions; +class Type_Conversions_State; namespace detail { template struct Cast_Helper; } // namespace detail @@ -36,7 +36,7 @@ namespace chaiscript /// \param[in] funcs the set of functions to dispatch on. template std::function - functor(const std::vector &funcs, const Type_Conversions *t_conversions) + functor(const std::vector &funcs, const Type_Conversions_State *t_conversions) { const bool has_arity_match = std::any_of(funcs.begin(), funcs.end(), [](const Const_Proxy_Function &f) { @@ -64,7 +64,7 @@ namespace chaiscript /// \param[in] func A function to execute. template std::function - functor(Const_Proxy_Function func, const Type_Conversions *t_conversions) + functor(Const_Proxy_Function func, const Type_Conversions_State *t_conversions) { return functor(std::vector({std::move(func)}), t_conversions); } @@ -73,7 +73,7 @@ namespace chaiscript /// and creating a typesafe C++ function caller from it. template std::function - functor(const Boxed_Value &bv, const Type_Conversions *t_conversions) + functor(const Boxed_Value &bv, const Type_Conversions_State *t_conversions) { return functor(boxed_cast(bv, t_conversions), t_conversions); } @@ -86,7 +86,7 @@ namespace chaiscript { typedef std::function Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { @@ -103,7 +103,7 @@ namespace chaiscript { typedef std::function Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { @@ -120,7 +120,7 @@ namespace chaiscript { typedef std::function Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions) + static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 2fc3f96..8ed6115 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -31,9 +31,15 @@ namespace chaiscript struct Function_Caller_Ret { static Ret call(const std::vector &t_funcs, - const std::vector ¶ms, const Type_Conversions *t_conversions) + const std::vector ¶ms, const Type_Conversions_State *t_conversions) { - return boxed_cast(dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions()), t_conversions); + if (t_conversions) { + return boxed_cast(dispatch::dispatch(t_funcs, params, *t_conversions), t_conversions); + } else { + Type_Conversions conv; + Type_Conversions_State state(conv, conv.conversion_saves()); + return boxed_cast(dispatch::dispatch(t_funcs, params, state), t_conversions); + } } }; @@ -44,9 +50,15 @@ namespace chaiscript struct Function_Caller_Ret { static Ret call(const std::vector &t_funcs, - const std::vector ¶ms, const Type_Conversions *t_conversions) + const std::vector ¶ms, const Type_Conversions_State *t_conversions) { - return Boxed_Number(dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions())).get_as(); + if (t_conversions) { + return Boxed_Number(dispatch::dispatch(t_funcs, params, *t_conversions)).get_as(); + } else { + Type_Conversions conv; + Type_Conversions_State state(conv, conv.conversion_saves()); + return Boxed_Number(dispatch::dispatch(t_funcs, params, state)).get_as(); + } } }; @@ -58,9 +70,15 @@ namespace chaiscript struct Function_Caller_Ret { static void call(const std::vector &t_funcs, - const std::vector ¶ms, const Type_Conversions *t_conversions) + const std::vector ¶ms, const Type_Conversions_State *t_conversions) { - dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions()); + if (t_conversions) { + dispatch::dispatch(t_funcs, params, *t_conversions); + } else { + Type_Conversions conv; + Type_Conversions_State state(conv, conv.conversion_saves()); + dispatch::dispatch(t_funcs, params, state); + } } }; @@ -79,11 +97,18 @@ namespace chaiscript template Ret operator()(P&& ... param) { - return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, { - box

(std::forward

(param))... - }, m_conversions - - ); + if (m_conversions) { + Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves()); + return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, { + box

(std::forward

(param))... + }, &state + ); + } else { + return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, { + box

(std::forward

(param))... + }, nullptr + ); + } } @@ -114,7 +139,7 @@ namespace chaiscript /// \todo what happens if t_conversions is deleted out from under us?! template - std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Type_Conversions *t_conversions) + std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Type_Conversions_State *t_conversions) { /* if (funcs.size() == 1) @@ -132,7 +157,7 @@ namespace chaiscript } */ - return std::function(Build_Function_Caller_Helper(funcs, t_conversions)); + return std::function(Build_Function_Caller_Helper(funcs, t_conversions?t_conversions->get():nullptr)); } } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index e115d96..6128b33 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -43,7 +43,7 @@ namespace chaiscript namespace dispatch { template - std::function functor(std::shared_ptr func, const Type_Conversions *t_conversions); + std::function functor(std::shared_ptr func, const Type_Conversions_State *t_conversions); class Param_Types { @@ -72,7 +72,7 @@ namespace chaiscript return m_types == t_rhs.m_types; } - bool match(const std::vector &vals, const Type_Conversions &t_conversions) const + bool match(const std::vector &vals, const Type_Conversions_State &t_conversions) const { if (!m_has_types) return true; if (vals.size() != m_types.size()) return false; @@ -147,7 +147,7 @@ namespace chaiscript public: virtual ~Proxy_Function_Base() {} - Boxed_Value operator()(const std::vector ¶ms, const chaiscript::Type_Conversions &t_conversions) const + Boxed_Value operator()(const std::vector ¶ms, const chaiscript::Type_Conversions_State &t_conversions) const { if (m_arity < 0 || size_t(m_arity) == params.size()) { return do_call(params, t_conversions); @@ -163,7 +163,7 @@ namespace chaiscript const std::vector &get_param_types() const { return m_types; } virtual bool operator==(const Proxy_Function_Base &) const = 0; - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const = 0; + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const = 0; virtual bool is_attribute_function() const { return false; } @@ -179,7 +179,7 @@ namespace chaiscript //! Return true if the function is a possible match //! to the passed in values - bool filter(const std::vector &vals, const Type_Conversions &t_conversions) const + bool filter(const std::vector &vals, const Type_Conversions_State &t_conversions) const { if (m_arity < 0) { @@ -206,7 +206,7 @@ namespace chaiscript virtual std::string annotation() const = 0; - static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions &t_conversions) + static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions) { if (ti.is_undef() || ti.bare_equal(user_type()) @@ -214,7 +214,7 @@ namespace chaiscript && ( (ti.bare_equal(user_type()) && bv.get_type_info().is_arithmetic()) || ti.bare_equal(bv.get_type_info()) || bv.get_type_info().bare_equal(user_type >()) - || t_conversions.converts(ti, bv.get_type_info()) + || t_conversions->converts(ti, bv.get_type_info()) ) ) ) @@ -225,13 +225,13 @@ namespace chaiscript } } - virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const + virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const { return compare_type_to_param(m_types[1], bv, t_conversions); } protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const = 0; + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const = 0; Proxy_Function_Base(std::vector t_types, int t_arity) : m_types(std::move(t_types)), m_arity(t_arity), m_has_arithmetic_param(false) @@ -248,7 +248,7 @@ namespace chaiscript } - static bool compare_types(const std::vector &tis, const std::vector &bvs, const Type_Conversions &t_conversions) + static bool compare_types(const std::vector &tis, const std::vector &bvs, const Type_Conversions_State &t_conversions) { if (tis.size() - 1 != bvs.size()) { @@ -327,7 +327,7 @@ namespace chaiscript && this->m_param_types == prhs->m_param_types); } - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return (m_arity < 0 || (vals.size() == size_t(m_arity) && m_param_types.match(vals, t_conversions))) && test_guard(vals, t_conversions); @@ -351,7 +351,7 @@ namespace chaiscript protected: - bool test_guard(const std::vector ¶ms, const Type_Conversions &t_conversions) const + bool test_guard(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const { if (m_guard) { @@ -419,7 +419,7 @@ namespace chaiscript protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { if (call_match(params, t_conversions) && test_guard(params, t_conversions)) { @@ -469,7 +469,7 @@ namespace chaiscript virtual ~Bound_Function() {} - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return m_f->call_match(build_param_list(vals), t_conversions); } @@ -548,7 +548,7 @@ namespace chaiscript return retval; } - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return (*m_f)(build_param_list(params), t_conversions); } @@ -573,12 +573,12 @@ namespace chaiscript return ""; } - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return static_cast(vals.size()) == get_arity() && (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions)); } - virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const = 0; + virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const = 0; }; @@ -596,7 +596,7 @@ namespace chaiscript virtual ~Proxy_Function_Callable_Impl() {} - virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } @@ -608,7 +608,7 @@ namespace chaiscript protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { typedef typename detail::Function_Signature::Return_Type Return_Type; return detail::Do_Call::template go(m_f, params, t_conversions); @@ -648,7 +648,7 @@ namespace chaiscript virtual ~Assignable_Proxy_Function_Impl() {} - virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } @@ -668,7 +668,7 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { return detail::Do_Call::result_type>::template go(m_f.get(), params, t_conversions); } @@ -705,7 +705,7 @@ namespace chaiscript } } - virtual bool call_match(const std::vector &vals, const Type_Conversions &) const CHAISCRIPT_OVERRIDE + virtual bool call_match(const std::vector &vals, const Type_Conversions_State &) const CHAISCRIPT_OVERRIDE { if (vals.size() != 1) { @@ -721,7 +721,7 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE { const Boxed_Value &bv = params[0]; if (bv.is_const()) @@ -782,7 +782,7 @@ namespace chaiscript { template bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector &plist, - const Type_Conversions &t_conversions) + const Type_Conversions_State &t_conversions) { const std::vector &types = t_func->get_param_types(); @@ -801,7 +801,7 @@ namespace chaiscript template Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector &plist, - const Type_Conversions &t_conversions, const Funcs &t_funcs) + const Type_Conversions_State &t_conversions, const Funcs &t_funcs) { InItr matching_func(end); @@ -878,7 +878,7 @@ namespace chaiscript */ template Boxed_Value dispatch(const Funcs &funcs, - const std::vector &plist, const Type_Conversions &t_conversions) + const std::vector &plist, const Type_Conversions_State &t_conversions) { std::vector> ordered_funcs; ordered_funcs.reserve(funcs.size()); diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 5c2fe91..452a999 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -19,7 +19,7 @@ #include "callable_traits.hpp" namespace chaiscript { -class Type_Conversions; +class Type_Conversions_State; namespace exception { class bad_boxed_cast; } // namespace exception @@ -77,7 +77,7 @@ namespace chaiscript template struct Try_Cast { - static void do_try(const std::vector ¶ms, size_t generation, const Type_Conversions &t_conversions) + static void do_try(const std::vector ¶ms, size_t generation, const Type_Conversions_State &t_conversions) { boxed_cast(params[generation], &t_conversions); Try_Cast::do_try(params, generation+1, t_conversions); @@ -88,7 +88,7 @@ namespace chaiscript template<> struct Try_Cast<> { - static void do_try(const std::vector &, size_t, const Type_Conversions &) + static void do_try(const std::vector &, size_t, const Type_Conversions_State &) { } }; @@ -101,7 +101,7 @@ namespace chaiscript */ template bool compare_types_cast(Ret (*)(Params...), - const std::vector ¶ms, const Type_Conversions &t_conversions) + const std::vector ¶ms, const Type_Conversions_State &t_conversions) { try { Try_Cast::do_try(params, 0, t_conversions); @@ -118,7 +118,7 @@ namespace chaiscript template static Ret do_call(const Callable &f, - const std::vector ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams) + const std::vector ¶ms, const Type_Conversions_State &t_conversions, InnerParams &&... innerparams) { return Call_Func::do_call(f, params, t_conversions, std::forward(innerparams)..., params[sizeof...(Params) - count]); } @@ -133,7 +133,7 @@ namespace chaiscript #endif template static Ret do_call(const Callable &f, - const std::vector &, const Type_Conversions &t_conversions, InnerParams &&... innerparams) + const std::vector &, const Type_Conversions_State &t_conversions, InnerParams &&... innerparams) { return f(boxed_cast(std::forward(innerparams), &t_conversions)...); } @@ -150,7 +150,7 @@ namespace chaiscript */ template Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, const Callable &f, - const std::vector ¶ms, const Type_Conversions &t_conversions) + const std::vector ¶ms, const Type_Conversions_State &t_conversions) { if (params.size() == sizeof...(Params)) { @@ -190,7 +190,7 @@ namespace chaiscript */ template bool compare_types_cast(Indexes, Ret (*)(Params...), - const std::vector ¶ms, const Type_Conversions &t_conversions) + const std::vector ¶ms, const Type_Conversions_State &t_conversions) { try { (void)params; (void)t_conversions; @@ -204,7 +204,7 @@ namespace chaiscript template bool compare_types_cast(Ret (*f)(Params...), - const std::vector ¶ms, const Type_Conversions &t_conversions) + const std::vector ¶ms, const Type_Conversions_State &t_conversions) { typedef typename Make_Indexes::indexes indexes; return compare_types_cast(indexes(), f, params, t_conversions); @@ -213,7 +213,7 @@ namespace chaiscript template Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, Indexes, const Callable &f, - const std::vector ¶ms, const Type_Conversions &t_conversions) + const std::vector ¶ms, const Type_Conversions_State &t_conversions) { (void)params; (void)t_conversions; return f(boxed_cast(params[I], &t_conversions)...); @@ -228,7 +228,7 @@ namespace chaiscript */ template Ret call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, - const std::vector ¶ms, const Type_Conversions &t_conversions) + const std::vector ¶ms, const Type_Conversions_State &t_conversions) { typedef typename Make_Indexes::indexes indexes; return call_func(sig, indexes(), f, params, t_conversions); @@ -252,7 +252,7 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) + static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions_State &t_conversions) { return Handle_Return::handle(call_func(Function_Signature(), fun, params, t_conversions)); } @@ -262,7 +262,7 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions &t_conversions) + static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions_State &t_conversions) { call_func(Function_Signature(), fun, params, t_conversions); return Handle_Return::handle(); diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 6987389..3a4d239 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -315,6 +315,16 @@ namespace chaiscript class Type_Conversions { public: + struct Conversion_Saves + { + Conversion_Saves() + : enabled(false) + {} + + bool enabled; + std::vector saves; + }; + struct Less_Than { bool operator()(const std::type_info *t_lhs, const std::type_info *t_rhs) const @@ -386,15 +396,14 @@ namespace chaiscript } else { return false; } - } template - Boxed_Value boxed_type_conversion(const Boxed_Value &from) const + Boxed_Value boxed_type_conversion(Conversion_Saves &t_saves, const Boxed_Value &from) const { try { Boxed_Value ret = get_conversion(user_type(), from.get_type_info())->convert(from); - if (m_conversion_saves->enabled) m_conversion_saves->saves.push_back(ret); + if (t_saves.enabled) t_saves.saves.push_back(ret); return ret; } catch (const std::out_of_range &) { throw exception::bad_boxed_dynamic_cast(from.get_type_info(), typeid(To), "No known conversion"); @@ -404,11 +413,11 @@ namespace chaiscript } template - Boxed_Value boxed_type_down_conversion(const Boxed_Value &to) const + Boxed_Value boxed_type_down_conversion(Conversion_Saves &t_saves, const Boxed_Value &to) const { try { Boxed_Value ret = get_conversion(to.get_type_info(), user_type())->convert_down(to); - if (m_conversion_saves->enabled) m_conversion_saves->saves.push_back(ret); + if (t_saves.enabled) t_saves.saves.push_back(ret); return ret; } catch (const std::out_of_range &) { throw exception::bad_boxed_dynamic_cast(to.get_type_info(), typeid(From), "No known conversion"); @@ -417,15 +426,15 @@ namespace chaiscript } } - void enable_conversion_saves(bool t_val) + static void enable_conversion_saves(Conversion_Saves &t_saves, bool t_val) { - m_conversion_saves->enabled = t_val; + t_saves.enabled = t_val; } - std::vector take_saves() + std::vector take_saves(Conversion_Saves &t_saves) { std::vector ret; - std::swap(ret, m_conversion_saves->saves); + std::swap(ret, t_saves.saves); return ret; } @@ -449,6 +458,10 @@ namespace chaiscript } } + Conversion_Saves &conversion_saves() const { + return *m_conversion_saves; + } + private: std::set >::const_iterator find_bidir( const Type_Info &to, const Type_Info &from) const @@ -458,7 +471,6 @@ namespace chaiscript { return (conversion->to().bare_equal(to) && conversion->from().bare_equal(from)) || (conversion->bidir() && conversion->from().bare_equal(to) && conversion->to().bare_equal(from)); -; } ); } @@ -482,15 +494,6 @@ namespace chaiscript } - struct Conversion_Saves - { - Conversion_Saves() - : enabled(false) - {} - - bool enabled; - std::vector saves; - }; mutable chaiscript::detail::threading::shared_mutex m_mutex; std::set> m_conversions; @@ -500,6 +503,33 @@ namespace chaiscript mutable chaiscript::detail::threading::Thread_Storage m_conversion_saves; }; + class Type_Conversions_State + { + public: + Type_Conversions_State(const Type_Conversions &t_conversions, + Type_Conversions::Conversion_Saves &t_saves) + : m_conversions(t_conversions), + m_saves(t_saves) + { + } + + const Type_Conversions *operator->() const { + return &m_conversions.get(); + } + + const Type_Conversions *get() const { + return &m_conversions.get(); + } + + Type_Conversions::Conversion_Saves &saves() const { + return m_saves; + } + + private: + std::reference_wrapper m_conversions; + std::reference_wrapper m_saves; + }; + typedef std::shared_ptr Type_Conversion; /// \brief Used to register a to / parent class relationship with ChaiScript. Necessary if you @@ -608,8 +638,6 @@ namespace chaiscript return chaiscript::make_shared>(user_type>(), user_type(), func); } - - } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 76881d5..b44a5a3 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -582,12 +582,12 @@ namespace chaiscript Function_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds) : m_ds(t_ds) { - m_ds.get()->new_function_call(m_ds.get().stack_holder()); + m_ds.get()->new_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves()); } ~Function_Push_Pop() { - m_ds.get()->pop_function_call(m_ds.get().stack_holder()); + m_ds.get()->pop_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves()); } void save_params(const std::vector &t_params) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index bf2338b..f0c42be 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -368,11 +368,15 @@ namespace chaiscript // m_engine.add(fun &)>(std::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), std::placeholders::_1, std::placeholders::_2, std::ref(m_engine.conversions()))), "call"); // +// + m_engine.add(fun( [=](const dispatch::Proxy_Function_Base &t_fun, const std::vector &t_params) { - return t_fun(t_params, this->m_engine.conversions()); + Type_Conversions_State s(this->m_engine.conversions(), this->m_engine.conversions().conversion_saves()); + return t_fun(t_params, s); }), "call"); + m_engine.add(fun([this](const Type_Info &t_ti){ return m_engine.get_type_name(t_ti); }), "name"); 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"); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 451bd21..9cdc482 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -118,7 +118,7 @@ namespace chaiscript } else { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); fpp.save_params({t_lhs, t_rhs}); - return t_ss->call_function(t_oper_string, m_loc, {t_lhs, t_rhs}); + return t_ss->call_function(t_oper_string, m_loc, {t_lhs, t_rhs}, t_ss.conversions()); } } catch(const exception::dispatch_error &e){ @@ -255,7 +255,7 @@ namespace chaiscript Boxed_Value fn(this->children[0]->eval(t_ss)); try { - return (*t_ss->boxed_cast(fn))(params, t_ss->conversions()); + return (*t_ss->boxed_cast(fn))(params, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss); @@ -436,14 +436,14 @@ namespace chaiscript } else { if (!rhs.is_return_value()) { - rhs = t_ss->call_function("clone", m_clone_loc, {rhs}); + rhs = t_ss->call_function("clone", m_clone_loc, {rhs}, t_ss.conversions()); } rhs.reset_return_value(); } } try { - return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}); + return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss); @@ -463,7 +463,7 @@ namespace chaiscript } else { try { - return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}); + return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss); } @@ -546,7 +546,7 @@ namespace chaiscript try { fpp.save_params(params); - return t_ss->call_function("[]", m_loc, params); + return t_ss->call_function("[]", m_loc, params, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, *t_ss ); @@ -599,7 +599,7 @@ namespace chaiscript fpp.save_params(params); try { - retval = t_ss->call_member(m_fun_name, m_loc, std::move(params), has_function_params); + retval = t_ss->call_member(m_fun_name, m_loc, std::move(params), has_function_params, t_ss.conversions()); } catch(const exception::dispatch_error &e){ if (e.functions.empty()) @@ -615,7 +615,7 @@ namespace chaiscript if (this->children[2]->identifier == AST_Node_Type::Array_Call) { try { - retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[2]->children[1]->eval(t_ss)}); + retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[2]->children[1]->eval(t_ss)}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, *t_ss); @@ -941,7 +941,7 @@ namespace chaiscript if (this->children[currentCase]->identifier == AST_Node_Type::Case) { //This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here. try { - if (hasMatched || boxed_cast(t_ss->call_function("==", m_loc, {match_value, this->children[currentCase]->children[0]->eval(t_ss)}))) { + if (hasMatched || boxed_cast(t_ss->call_function("==", m_loc, {match_value, this->children[currentCase]->children[0]->eval(t_ss)}, t_ss.conversions()))) { this->children[currentCase]->eval(t_ss); hasMatched = true; } @@ -1011,7 +1011,7 @@ namespace chaiscript for (const auto &child : children[0]->children) { auto obj = child->eval(t_ss); if (!obj.is_return_value()) { - vec.push_back(t_ss->call_function("clone", m_loc, {obj})); + vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions())); } else { vec.push_back(std::move(obj)); } @@ -1044,7 +1044,7 @@ namespace chaiscript for (const auto &child : children[0]->children) { auto obj = child->children[1]->eval(t_ss); if (!obj.is_return_value()) { - obj = t_ss->call_function("clone", m_loc, {obj}); + obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()); } retval[t_ss->boxed_cast(child->children[0]->eval(t_ss))] = std::move(obj); @@ -1140,7 +1140,7 @@ namespace chaiscript } else { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); fpp.save_params({bv}); - return t_ss->call_function(children[0]->text, m_loc, {std::move(bv)}); + return t_ss->call_function(children[0]->text, m_loc, {std::move(bv)}, t_ss.conversions()); } } catch (const exception::dispatch_error &e) { throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, e.functions, false, *t_ss); @@ -1212,7 +1212,7 @@ namespace chaiscript try { auto oper1 = children[0]->children[0]->children[0]->eval(t_ss); auto oper2 = children[0]->children[0]->children[1]->eval(t_ss); - return t_ss->call_function("generate_range", m_loc, {oper1, oper2}); + return t_ss->call_function("generate_range", m_loc, {oper1, oper2}, t_ss.conversions()); } catch (const exception::dispatch_error &e) { throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, *t_ss); @@ -1257,7 +1257,7 @@ namespace chaiscript if (dispatch::Param_Types( std::vector>{Arg_List_AST_Node::get_arg_type(catch_block->children[0], t_ss)} - ).match(std::vector{t_except}, t_ss->conversions())) + ).match(std::vector{t_except}, t_ss.conversions())) { t_ss.add_object(name, t_except);