diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 29d1b3b..e970210 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -31,7 +31,7 @@ namespace chaiscript P1 &assign_pod(P1 &p1, Boxed_POD_Value v) { - if (v.m_isfloat) + if (v.isfloat) { return (p1 = P1(v.d)); } else { @@ -42,7 +42,7 @@ namespace chaiscript template P1 construct_pod(Boxed_POD_Value v) { - if (v.m_isfloat) + if (v.isfloat) { return P1(v.d); } else { @@ -53,7 +53,7 @@ namespace chaiscript template P1 &assign_bitwise_and_pod(P1 &p1, Boxed_POD_Value r) { - if (!r.m_isfloat) + if (!r.isfloat) { return p1 &= P1(r.i); } @@ -64,7 +64,7 @@ namespace chaiscript template P1 &assign_xor_pod(P1 &p1, Boxed_POD_Value r) { - if (!r.m_isfloat) + if (!r.isfloat) { return p1 ^= P1(r.i); } @@ -75,7 +75,7 @@ namespace chaiscript template P1 &assign_bitwise_or_pod(P1 &p1, Boxed_POD_Value r) { - if (!r.m_isfloat) + if (!r.isfloat) { return p1 |= P1(r.i); } @@ -86,7 +86,7 @@ namespace chaiscript template P1 &assign_difference_pod(P1 &p1, Boxed_POD_Value r) { - if (r.m_isfloat) + if (r.isfloat) { return p1 -= P1(r.d); } else { @@ -97,7 +97,7 @@ namespace chaiscript template P1 &assign_left_shift_pod(P1 &p1, Boxed_POD_Value r) { - if (!r.m_isfloat) + if (!r.isfloat) { return p1 <<= P1(r.i); } @@ -109,7 +109,7 @@ namespace chaiscript template P1 &assign_product_pod(P1 &p1, Boxed_POD_Value r) { - if (r.m_isfloat) + if (r.isfloat) { return p1 *= P1(r.d); } else { @@ -120,7 +120,7 @@ namespace chaiscript template P1 &assign_quotient_pod(P1 &p1, Boxed_POD_Value r) { - if (r.m_isfloat) + if (r.isfloat) { return p1 /= P1(r.d); } else { @@ -131,7 +131,7 @@ namespace chaiscript template P1 &assign_remainder_pod(P1 &p1, Boxed_POD_Value r) { - if (!r.m_isfloat) + if (!r.isfloat) { return p1 %= P1(r.i); } @@ -143,7 +143,7 @@ namespace chaiscript template P1 &assign_right_shift_pod(P1 &p1, Boxed_POD_Value r) { - if (!r.m_isfloat) + if (!r.isfloat) { return p1 >>= P1(r.i); } @@ -155,7 +155,7 @@ namespace chaiscript template P1 &assign_sum_pod(P1 &p1, Boxed_POD_Value r) { - if (r.m_isfloat) + if (r.isfloat) { return p1 += P1(r.d); } else { @@ -458,7 +458,7 @@ namespace chaiscript Const_Proxy_Function f = boxed_cast(params[0]); - return Boxed_Value(Const_Proxy_Function(new Bound_Function(f, + return Boxed_Value(Const_Proxy_Function(new dispatch::Bound_Function(f, std::vector(params.begin() + 1, params.end())))); } @@ -480,7 +480,7 @@ namespace chaiscript static bool has_guard(const Const_Proxy_Function &t_pf) { - boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); + boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); if (pf) { return pf->get_guard(); @@ -491,7 +491,7 @@ namespace chaiscript static Const_Proxy_Function get_guard(const Const_Proxy_Function &t_pf) { - boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); + boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); if (pf) { if (pf->get_guard()) @@ -509,7 +509,7 @@ namespace chaiscript throw bv; } - static boost::shared_ptr bootstrap2(boost::shared_ptr e = boost::shared_ptr (new Dispatch_Engine())) + static boost::shared_ptr bootstrap2(boost::shared_ptr e = boost::shared_ptr (new chaiscript::detail::Dispatch_Engine())) { e->add(user_type(), "void"); return e; @@ -535,7 +535,7 @@ namespace chaiscript template static std::vector do_return_boxed_value_vector(FunctionType f, - const Proxy_Function_Base *b) + const dispatch::Proxy_Function_Base *b) { typedef typename boost::function_types::result_type::type Vector; Vector v = (b->*f)(); @@ -552,7 +552,7 @@ namespace chaiscript } template - static boost::function (const Proxy_Function_Base*)> return_boxed_value_vector(const Function &f) + static boost::function (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f) { return boost::bind(&do_return_boxed_value_vector, f, _1); } @@ -570,14 +570,14 @@ namespace chaiscript m->add(user_type(), "function"); m->add(user_type(), "exception"); - m->add(fun(&Proxy_Function_Base::get_arity), "get_arity"); - m->add(fun(&Proxy_Function_Base::annotation), "get_annotation"); - m->add(fun(&Proxy_Function_Base::operator()), "call"); - m->add(fun(&Proxy_Function_Base::operator==), "=="); + m->add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity"); + m->add(fun(&dispatch::Proxy_Function_Base::annotation), "get_annotation"); + m->add(fun(&dispatch::Proxy_Function_Base::operator()), "call"); + m->add(fun(&dispatch::Proxy_Function_Base::operator==), "=="); - m->add(fun(return_boxed_value_vector(&Proxy_Function_Base::get_param_types)), "get_param_types"); - m->add(fun(return_boxed_value_vector(&Proxy_Function_Base::get_contained_functions)), "get_contained_functions"); + m->add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_param_types)), "get_param_types"); + m->add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_contained_functions)), "get_contained_functions"); m->add(user_type(), "runtime_error"); @@ -587,11 +587,11 @@ namespace chaiscript m->add(constructor(), "runtime_error"); m->add(fun(boost::function(&what)), "what"); - m->add(user_type(), "Dynamic_Object"); - m->add(constructor(), "Dynamic_Object"); - m->add(fun(&Dynamic_Object::get_type_name), "get_type_name"); - m->add(fun(&Dynamic_Object::get_attrs), "get_attrs"); - m->add(fun(&Dynamic_Object::get_attr), "get_attr"); + m->add(user_type(), "Dynamic_Object"); + m->add(constructor(), "Dynamic_Object"); + m->add(fun(&dispatch::Dynamic_Object::get_type_name), "get_type_name"); + m->add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs"); + m->add(fun(&dispatch::Dynamic_Object::get_attr), "get_attr"); m->eval("def Dynamic_Object::clone() { var new_o := Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }"); @@ -648,14 +648,14 @@ namespace chaiscript m->add(fun(&print), "print_string"); m->add(fun(&println), "println_string"); - m->add(Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&bind_function, _1))), + m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&bind_function, _1))), "bind"); - m->add(fun(&shared_ptr_unconst_clone), "clone"); - m->add(fun(&ptr_assign::type>), "="); - m->add(fun(&ptr_assign::type>), "="); + m->add(fun(&shared_ptr_unconst_clone), "clone"); + m->add(fun(&ptr_assign::type>), "="); + m->add(fun(&ptr_assign::type>), "="); - m->add(Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&call_exists, _1))), + m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&call_exists, _1))), "call_exists"); m->add(fun(&type_match), "type_match"); diff --git a/include/chaiscript/dispatchkit/boxed_pod_value.hpp b/include/chaiscript/dispatchkit/boxed_pod_value.hpp index 42d7fae..57b5266 100644 --- a/include/chaiscript/dispatchkit/boxed_pod_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_pod_value.hpp @@ -21,205 +21,205 @@ namespace chaiscript * Object which attempts to convert a Boxed_Value into a generic * POD type and provide generic POD type operations */ - struct Boxed_POD_Value + class Boxed_POD_Value { - Boxed_POD_Value(const Boxed_Value &v) - : d(0), i(0), m_isfloat(false) - { - if (v.get_type_info().is_undef()) + public: + Boxed_POD_Value(const Boxed_Value &v) + : d(0), i(0), isfloat(false) { - throw boost::bad_any_cast(); + if (v.get_type_info().is_undef()) + { + throw boost::bad_any_cast(); + } + + const Type_Info &inp_ = v.get_type_info(); + + if (inp_ == typeid(double)) + { + d = boxed_cast(v); + isfloat = true; + } else if (inp_ == typeid(float)) { + d = boxed_cast(v); + isfloat = true; + } else if (inp_ == typeid(bool)) { + i = boxed_cast(v); + } else if (inp_ == typeid(char)) { + i = boxed_cast(v); + } else if (inp_ == typeid(int)) { + i = boxed_cast(v); + } else if (inp_ == typeid(unsigned int)) { + i = boxed_cast(v); + } else if (inp_ == typeid(long)) { + i = boxed_cast(v); + } else if (inp_ == typeid(unsigned long)) { + i = boxed_cast(v); + } else if (inp_ == typeid(boost::int8_t)) { + i = boxed_cast(v); + } else if (inp_ == typeid(boost::int16_t)) { + i = boxed_cast(v); + } else if (inp_ == typeid(boost::int32_t)) { + i = boxed_cast(v); + } else if (inp_ == typeid(boost::int64_t)) { + i = boxed_cast(v); + } else if (inp_ == typeid(boost::uint8_t)) { + i = boxed_cast(v); + } else if (inp_ == typeid(boost::uint16_t)) { + i = boxed_cast(v); + } else if (inp_ == typeid(boost::uint32_t)) { + i = boxed_cast(v); + } else { + throw boost::bad_any_cast(); + } } - const Type_Info &inp_ = v.get_type_info(); - - if (inp_ == typeid(double)) + bool operator==(const Boxed_POD_Value &r) const { - d = boxed_cast(v); - m_isfloat = true; - } else if (inp_ == typeid(float)) { - d = boxed_cast(v); - m_isfloat = true; - } else if (inp_ == typeid(bool)) { - i = boxed_cast(v); - } else if (inp_ == typeid(char)) { - i = boxed_cast(v); - } else if (inp_ == typeid(int)) { - i = boxed_cast(v); - } else if (inp_ == typeid(unsigned int)) { - i = boxed_cast(v); - } else if (inp_ == typeid(long)) { - i = boxed_cast(v); - } else if (inp_ == typeid(unsigned long)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int8_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int16_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int32_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int64_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint8_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint16_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint32_t)) { - i = boxed_cast(v); - } else { - throw boost::bad_any_cast(); - } - } - - bool operator==(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i); - } - - bool operator<(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) < ((r.m_isfloat)?r.d:r.i); - } - - bool operator>(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) > ((r.m_isfloat)?r.d:r.i); - } - - bool operator>=(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) >= ((r.m_isfloat)?r.d:r.i); - } - - bool operator<=(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) <= ((r.m_isfloat)?r.d:r.i); - } - - bool operator!=(const Boxed_POD_Value &r) const - { - return ((m_isfloat)?d:i) != ((r.m_isfloat)?r.d:r.i); - } - - Boxed_Value operator+(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) - { - return smart_size(i + r.i); + return ((isfloat)?d:i) == ((r.isfloat)?r.d:r.i); } - return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i)); - } - - Boxed_Value operator-(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + bool operator<(const Boxed_POD_Value &r) const { - return smart_size(i - r.i); + return ((isfloat)?d:i) < ((r.isfloat)?r.d:r.i); } - return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i)); - } - - Boxed_Value operator&(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + bool operator>(const Boxed_POD_Value &r) const { - return Boxed_Value(i & r.i); + return ((isfloat)?d:i) > ((r.isfloat)?r.d:r.i); } - throw exception::bad_boxed_cast("& only valid for integer types"); - } - - Boxed_Value operator^(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + bool operator>=(const Boxed_POD_Value &r) const { - return Boxed_Value(i ^ r.i); + return ((isfloat)?d:i) >= ((r.isfloat)?r.d:r.i); } - throw exception::bad_boxed_cast("^ only valid for integer types"); - } - - Boxed_Value operator|(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + bool operator<=(const Boxed_POD_Value &r) const { - return Boxed_Value(i | r.i); + return ((isfloat)?d:i) <= ((r.isfloat)?r.d:r.i); } - throw exception::bad_boxed_cast("| only valid for integer types"); - } - - Boxed_Value operator/(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + bool operator!=(const Boxed_POD_Value &r) const { - return smart_size(i / r.i); + return ((isfloat)?d:i) != ((r.isfloat)?r.d:r.i); } - return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i)); - } - - Boxed_Value operator<<(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + Boxed_Value operator+(const Boxed_POD_Value &r) const { - return smart_size(i << r.i); + if (!isfloat && !r.isfloat) + { + return smart_size(i + r.i); + } + + return Boxed_Value(((isfloat)?d:i) + ((r.isfloat)?r.d:r.i)); } - throw exception::bad_boxed_cast("<< only valid for integer types"); - } - - - Boxed_Value operator*(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + Boxed_Value operator-(const Boxed_POD_Value &r) const { - return smart_size(i * r.i); + if (!isfloat && !r.isfloat) + { + return smart_size(i - r.i); + } + + return Boxed_Value(((isfloat)?d:i) - ((r.isfloat)?r.d:r.i)); } - return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i)); - } - - - Boxed_Value operator%(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + Boxed_Value operator&(const Boxed_POD_Value &r) const { - return smart_size(i % r.i); + if (!isfloat && !r.isfloat) + { + return Boxed_Value(i & r.i); + } + + throw exception::bad_boxed_cast("& only valid for integer types"); } - throw exception::bad_boxed_cast("% only valid for integer types"); - } - - Boxed_Value operator>>(const Boxed_POD_Value &r) const - { - if (!m_isfloat && !r.m_isfloat) + Boxed_Value operator^(const Boxed_POD_Value &r) const { - return smart_size(i >> r.i); + if (!isfloat && !r.isfloat) + { + return Boxed_Value(i ^ r.i); + } + + throw exception::bad_boxed_cast("^ only valid for integer types"); } - throw exception::bad_boxed_cast(">> only valid for integer types"); - } - - Boxed_Value smart_size(boost::int64_t t_i) const - { - if (t_i < boost::integer_traits::const_min - || t_i > boost::integer_traits::const_max) + Boxed_Value operator|(const Boxed_POD_Value &r) const { - return Boxed_Value(t_i); - } else { - return Boxed_Value(static_cast(t_i)); + if (!isfloat && !r.isfloat) + { + return Boxed_Value(i | r.i); + } + + throw exception::bad_boxed_cast("| only valid for integer types"); + } + + Boxed_Value operator/(const Boxed_POD_Value &r) const + { + if (!isfloat && !r.isfloat) + { + return smart_size(i / r.i); + } + + return Boxed_Value(((isfloat)?d:i) / ((r.isfloat)?r.d:r.i)); + } + + Boxed_Value operator<<(const Boxed_POD_Value &r) const + { + if (!isfloat && !r.isfloat) + { + return smart_size(i << r.i); + } + + throw exception::bad_boxed_cast("<< only valid for integer types"); } - } + Boxed_Value operator*(const Boxed_POD_Value &r) const + { + if (!isfloat && !r.isfloat) + { + return smart_size(i * r.i); + } - double d; - boost::int64_t i; + return Boxed_Value(((isfloat)?d:i) * ((r.isfloat)?r.d:r.i)); + } - bool m_isfloat; + + Boxed_Value operator%(const Boxed_POD_Value &r) const + { + if (!isfloat && !r.isfloat) + { + return smart_size(i % r.i); + } + + throw exception::bad_boxed_cast("% only valid for integer types"); + } + + Boxed_Value operator>>(const Boxed_POD_Value &r) const + { + if (!isfloat && !r.isfloat) + { + return smart_size(i >> r.i); + } + + throw exception::bad_boxed_cast(">> only valid for integer types"); + } + + Boxed_Value smart_size(boost::int64_t t_i) const + { + if (t_i < boost::integer_traits::const_min + || t_i > boost::integer_traits::const_max) + { + return Boxed_Value(t_i); + } else { + return Boxed_Value(static_cast(t_i)); + } + } + + + double d; + boost::int64_t i; + + bool isfloat; }; namespace detail diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 9467b58..591238a 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -111,151 +111,153 @@ namespace chaiscript typedef boost::shared_ptr ModulePtr; - /** - * A Proxy_Function implementation that is able to take - * a vector of Proxy_Functions and perform a dispatch on them. It is - * used specifically in the case of dealing with Function object variables - */ - class Dispatch_Function : public Proxy_Function_Base + namespace detail { - public: - Dispatch_Function(const std::vector &t_funcs) - : Proxy_Function_Base(build_type_infos(t_funcs)), + /** + * A Proxy_Function implementation that is able to take + * a vector of Proxy_Functions and perform a dispatch on them. It is + * used specifically in the case of dealing with Function object variables + */ + class Dispatch_Function : public dispatch::Proxy_Function_Base + { + public: + Dispatch_Function(const std::vector &t_funcs) + : Proxy_Function_Base(build_type_infos(t_funcs)), m_funcs(t_funcs) { } - virtual bool operator==(const Proxy_Function_Base &rhs) const - { - try { - const Dispatch_Function &dispatchfun = dynamic_cast(rhs); - return m_funcs == dispatchfun.m_funcs; - } catch (const std::bad_cast &) { + virtual bool operator==(const dispatch::Proxy_Function_Base &rhs) const + { + try { + const Dispatch_Function &dispatchfun = dynamic_cast(rhs); + return m_funcs == dispatchfun.m_funcs; + } catch (const std::bad_cast &) { + return false; + } + } + + virtual ~Dispatch_Function() {} + + virtual std::vector get_contained_functions() const + { + return std::vector(m_funcs.begin(), m_funcs.end()); + } + + + virtual int get_arity() const + { + typedef std::vector function_vec; + + function_vec::const_iterator begin = m_funcs.begin(); + const function_vec::const_iterator end = m_funcs.end(); + + if (begin != end) + { + int arity = (*begin)->get_arity(); + + ++begin; + + while (begin != end) + { + if (arity != (*begin)->get_arity()) + { + // The arities in the list do not match, so it's unspecified + return -1; + } + + ++begin; + } + + return arity; + } + + return -1; // unknown arity + } + + virtual bool call_match(const std::vector &vals) const + { + typedef std::vector function_vec; + + function_vec::const_iterator begin = m_funcs.begin(); + function_vec::const_iterator end = m_funcs.end(); + + while (begin != end) + { + if ((*begin)->call_match(vals)) + { + return true; + } else { + ++begin; + } + } + return false; } - } - virtual ~Dispatch_Function() {} - - virtual std::vector get_contained_functions() const - { - return std::vector(m_funcs.begin(), m_funcs.end()); - } - - - virtual int get_arity() const - { - typedef std::vector function_vec; - - function_vec::const_iterator begin = m_funcs.begin(); - const function_vec::const_iterator end = m_funcs.end(); - - if (begin != end) + virtual std::string annotation() const { - int arity = (*begin)->get_arity(); - - ++begin; - - while (begin != end) - { - if (arity != (*begin)->get_arity()) - { - // The arities in the list do not match, so it's unspecified - return -1; - } - - ++begin; - } - - return arity; + return "Multiple method dispatch function wrapper."; } - return -1; // unknown arity - } - - virtual bool call_match(const std::vector &vals) const - { - typedef std::vector function_vec; - - function_vec::const_iterator begin = m_funcs.begin(); - function_vec::const_iterator end = m_funcs.end(); - - while (begin != end) + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const { - if ((*begin)->call_match(vals)) - { - return true; - } else { - ++begin; - } + return dispatch::dispatch(m_funcs.begin(), m_funcs.end(), params); } - return false; - } + private: + std::vector m_funcs; - virtual std::string annotation() const - { - return "Multiple method dispatch function wrapper."; - } - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - return detail::dispatch(m_funcs.begin(), m_funcs.end(), params); - } - - private: - std::vector m_funcs; - - static std::vector build_type_infos(const std::vector &t_funcs) - { - typedef std::vector function_vec; - - function_vec::const_iterator begin = t_funcs.begin(); - const function_vec::const_iterator end = t_funcs.end(); - - if (begin != end) + static std::vector build_type_infos(const std::vector &t_funcs) { - std::vector type_infos = (*begin)->get_param_types(); + typedef std::vector function_vec; - ++begin; + function_vec::const_iterator begin = t_funcs.begin(); + const function_vec::const_iterator end = t_funcs.end(); - bool sizemismatch = false; - - while (begin != end) + if (begin != end) { - std::vector param_types = (*begin)->get_param_types(); + std::vector type_infos = (*begin)->get_param_types(); - if (param_types.size() != type_infos.size()) - { - sizemismatch = true; - } + ++begin; - for (size_t i = 0; i < type_infos.size() && i < param_types.size(); ++i) + bool sizemismatch = false; + + while (begin != end) { - if (!(type_infos[i] == param_types[i])) + std::vector param_types = (*begin)->get_param_types(); + + if (param_types.size() != type_infos.size()) { - type_infos[i] = detail::Get_Type_Info::get(); + sizemismatch = true; } + + for (size_t i = 0; i < type_infos.size() && i < param_types.size(); ++i) + { + if (!(type_infos[i] == param_types[i])) + { + type_infos[i] = detail::Get_Type_Info::get(); + } + } + + ++begin; } - ++begin; + assert(type_infos.size() > 0 && " type_info vector size is < 0, this is only possible if something else is broken"); + + if (sizemismatch) + { + type_infos.resize(1); + } + + return type_infos; } - assert(type_infos.size() > 0 && " type_info vector size is < 0, this is only possible if something else is broken"); - - if (sizemismatch) - { - type_infos.resize(1); - } - - return type_infos; + return std::vector(); } - - return std::vector(); - } - }; - + }; + } namespace exception { @@ -300,396 +302,398 @@ namespace chaiscript }; } - /** - * Main class for the dispatchkit. Handles management - * of the object stack, functions and registered types. - */ - class Dispatch_Engine + namespace detail { - public: - typedef std::map Type_Name_Map; - typedef std::map Scope; - typedef std::deque StackData; - typedef boost::shared_ptr Stack; + /** + * Main class for the dispatchkit. Handles management + * of the object stack, functions and registered types. + */ + class Dispatch_Engine + { + public: + typedef std::map Type_Name_Map; + typedef std::map Scope; + typedef std::deque StackData; + typedef boost::shared_ptr Stack; - struct State - { - std::map > m_functions; - std::map m_global_objects; - Type_Name_Map m_types; - std::set m_reserved_words; - }; - - Dispatch_Engine() - : m_place_holder(boost::shared_ptr(new Placeholder_Object())) - { - } - - ~Dispatch_Engine() - { - detail::Dynamic_Conversions::get().cleanup(m_conversions.begin(), m_conversions.end()); - } - - /** - * Add a new conversion for upcasting to a base class - */ - void add(const Dynamic_Cast_Conversion &d) - { - m_conversions.push_back(d); - return detail::Dynamic_Conversions::get().add_conversion(d); - } - - /** - * Add a new named Proxy_Function to the system - */ - bool add(const Proxy_Function &f, const std::string &name) - { - validate_object_name(name); - return add_function(f, name); - } - - /** - * Set the value of an object, by name. If the object - * is not available in the current scope it is created - */ - void add(const Boxed_Value &obj, const std::string &name) - { - validate_object_name(name); - StackData &stack = get_stack_data(); - - for (int i = static_cast(stack.size())-1; i >= 0; --i) + struct State { - std::map::const_iterator itr = stack[i].find(name); - if (itr != stack[i].end()) + std::map > m_functions; + std::map m_global_objects; + Type_Name_Map m_types; + std::set m_reserved_words; + }; + + Dispatch_Engine() + : m_place_holder(boost::shared_ptr(new dispatch::Placeholder_Object())) + { + } + + ~Dispatch_Engine() + { + detail::Dynamic_Conversions::get().cleanup(m_conversions.begin(), m_conversions.end()); + } + + /** + * Add a new conversion for upcasting to a base class + */ + void add(const Dynamic_Cast_Conversion &d) + { + m_conversions.push_back(d); + return detail::Dynamic_Conversions::get().add_conversion(d); + } + + /** + * Add a new named Proxy_Function to the system + */ + bool add(const Proxy_Function &f, const std::string &name) + { + validate_object_name(name); + return add_function(f, name); + } + + /** + * Set the value of an object, by name. If the object + * is not available in the current scope it is created + */ + void add(const Boxed_Value &obj, const std::string &name) + { + validate_object_name(name); + StackData &stack = get_stack_data(); + + for (int i = static_cast(stack.size())-1; i >= 0; --i) { - stack[i][name] = obj; - return; + std::map::const_iterator itr = stack[i].find(name); + if (itr != stack[i].end()) + { + stack[i][name] = obj; + return; + } + } + + add_object(name, obj); + } + + /** + * Adds a named object to the current scope + */ + void add_object(const std::string &name, const Boxed_Value &obj) + { + StackData &stack = get_stack_data(); + validate_object_name(name); + stack.back()[name] = obj; + } + + /** + * Adds a new global shared object, between all the threads + */ + void add_global_const(const Boxed_Value &obj, const std::string &name) + { + validate_object_name(name); + if (!obj.is_const()) + { + throw exception::global_non_const(); + } + +#ifndef CHAISCRIPT_NO_THREADS + boost::unique_lock l(m_global_object_mutex); +#endif + + m_state.m_global_objects[name] = obj; + } + + /** + * Adds a new scope to the stack + */ + void new_scope() + { + StackData &stack = get_stack_data(); + stack.push_back(Scope()); + } + + /** + * Pops the current scope from the stack + */ + void pop_scope() + { + StackData &stack = get_stack_data(); + if (stack.size() > 1) + { + stack.pop_back(); + } else { + throw std::range_error("Unable to pop global stack"); } } - add_object(name, obj); - } - - /** - * Adds a named object to the current scope - */ - void add_object(const std::string &name, const Boxed_Value &obj) - { - StackData &stack = get_stack_data(); - validate_object_name(name); - stack.back()[name] = obj; - } - - /** - * Adds a new global shared object, between all the threads - */ - void add_global_const(const Boxed_Value &obj, const std::string &name) - { - validate_object_name(name); - if (!obj.is_const()) + /** + * Swaps out the stack with a new stack + * \returns the old stack + * \param[in] s The new stack + */ + Stack set_stack(const Stack &s) { - throw exception::global_non_const(); + Stack old = m_stack_holder->stack; + m_stack_holder->stack = s; + return old; } + Stack new_stack() const + { + Stack s(new Stack::element_type()); + s->push_back(Scope()); + return s; + } + + Stack get_stack() const + { + return m_stack_holder->stack; + } + + /** + * Searches the current stack for an object of the given name + * includes a special overload for the _ place holder object to + * ensure that it is always in scope. + */ + Boxed_Value get_object(const std::string &name) const + { + // Is it a placeholder object? + if (name == "_") + { + return m_place_holder; + } + + StackData &stack = get_stack_data(); + + // Is it in the stack? + for (int i = static_cast(stack.size())-1; i >= 0; --i) + { + std::map::const_iterator stackitr = stack[i].find(name); + if (stackitr != stack[i].end()) + { + return stackitr->second; + } + } + + // Is the value we are looking for a global? + { #ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_global_object_mutex); + boost::shared_lock l(m_global_object_mutex); #endif - m_state.m_global_objects[name] = obj; - } + std::map::const_iterator itr = m_state.m_global_objects.find(name); + if (itr != m_state.m_global_objects.end()) + { + return itr->second; + } + } - /** - * Adds a new scope to the stack - */ - void new_scope() - { - StackData &stack = get_stack_data(); - stack.push_back(Scope()); - } + // If all that failed, then check to see if it's a function + std::vector funcs = get_function(name); - /** - * Pops the current scope from the stack - */ - void pop_scope() - { - StackData &stack = get_stack_data(); - if (stack.size() > 1) - { - stack.pop_back(); - } else { - throw std::range_error("Unable to pop global stack"); - } - } - - /** - * Swaps out the stack with a new stack - * \returns the old stack - * \param[in] s The new stack - */ - Stack set_stack(const Stack &s) - { - Stack old = m_stack_holder->stack; - m_stack_holder->stack = s; - return old; - } - - Stack new_stack() const - { - Stack s(new Stack::element_type()); - s->push_back(Scope()); - return s; - } - - Stack get_stack() const - { - return m_stack_holder->stack; - } - - /** - * Searches the current stack for an object of the given name - * includes a special overload for the _ place holder object to - * ensure that it is always in scope. - */ - Boxed_Value get_object(const std::string &name) const - { - // Is it a placeholder object? - if (name == "_") - { - return m_place_holder; - } - - StackData &stack = get_stack_data(); - - // Is it in the stack? - for (int i = static_cast(stack.size())-1; i >= 0; --i) - { - std::map::const_iterator stackitr = stack[i].find(name); - if (stackitr != stack[i].end()) + if (funcs.empty()) { - return stackitr->second; + throw std::range_error("Object not known: " + name); + } else { + if (funcs.size() == 1) + { + // Return the first item if there is only one, + // no reason to take the cast of the extra level of dispatch + return const_var(*funcs.begin()); + } else { + return Boxed_Value(Const_Proxy_Function(new Dispatch_Function(funcs))); + } } } - // Is the value we are looking for a global? + /** + * Registers a new named type + */ + void add(const Type_Info &ti, const std::string &name) { + add_global_const(const_var(ti), name + "_type"); + #ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_global_object_mutex); + boost::unique_lock l(m_mutex); #endif - std::map::const_iterator itr = m_state.m_global_objects.find(name); - if (itr != m_state.m_global_objects.end()) + m_state.m_types.insert(std::make_pair(name, ti)); + } + + /** + * Returns the type info for a named type + */ + Type_Info get_type(const std::string &name) const + { +#ifndef CHAISCRIPT_NO_THREADS + boost::shared_lock l(m_mutex); +#endif + + Type_Name_Map::const_iterator itr = m_state.m_types.find(name); + + if (itr != m_state.m_types.end()) { return itr->second; } + + throw std::range_error("Type Not Known"); } - // If all that failed, then check to see if it's a function - std::vector funcs = get_function(name); - - if (funcs.empty()) + /** + * Returns the registered name of a known type_info object + * compares the "bare_type_info" for the broadest possible + * match + */ + std::string get_type_name(const Type_Info &ti) const { - throw std::range_error("Object not known: " + name); - } else { - if (funcs.size() == 1) +#ifndef CHAISCRIPT_NO_THREADS + boost::shared_lock l(m_mutex); +#endif + + for (Type_Name_Map::const_iterator itr = m_state.m_types.begin(); + itr != m_state.m_types.end(); + ++itr) { - // Return the first item if there is only one, - // no reason to take the cast of the extra level of dispatch - return const_var(*funcs.begin()); - } else { - return Boxed_Value(Const_Proxy_Function(new Dispatch_Function(funcs))); + if (itr->second.bare_equal(ti)) + { + return itr->first; + } } - } - } - /** - * Registers a new named type - */ - void add(const Type_Info &ti, const std::string &name) - { - add_global_const(const_var(ti), name + "_type"); - -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); -#endif - - m_state.m_types.insert(std::make_pair(name, ti)); - } - - /** - * Returns the type info for a named type - */ - Type_Info get_type(const std::string &name) const - { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif - - Type_Name_Map::const_iterator itr = m_state.m_types.find(name); - - if (itr != m_state.m_types.end()) - { - return itr->second; + return ti.bare_name(); } - throw std::range_error("Type Not Known"); - } - - /** - * Returns the registered name of a known type_info object - * compares the "bare_type_info" for the broadest possible - * match - */ - std::string get_type_name(const Type_Info &ti) const - { + /** + * Return all registered types + */ + std::vector > get_types() const + { #ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); + boost::shared_lock l(m_mutex); #endif - for (Type_Name_Map::const_iterator itr = m_state.m_types.begin(); - itr != m_state.m_types.end(); - ++itr) - { - if (itr->second.bare_equal(ti)) + return std::vector >(m_state.m_types.begin(), m_state.m_types.end()); + } + + /** + * Return a function by name + */ + std::vector< Proxy_Function > + get_function(const std::string &t_name) const { - return itr->first; +#ifndef CHAISCRIPT_NO_THREADS + boost::shared_lock l(m_mutex); +#endif + + const std::map > &funs = get_functions_int(); + + std::map >::const_iterator itr + = funs.find(t_name); + + if (itr != funs.end()) + { + return itr->second; + } else { + return std::vector(); + } + } + + /** + * Return true if a function exists + */ + bool function_exists(const std::string &name) const + { +#ifndef CHAISCRIPT_NO_THREADS + boost::shared_lock l(m_mutex); +#endif + + const std::map > &functions = get_functions_int(); + return functions.find(name) != functions.end(); } - return ti.bare_name(); - } - - /** - * Return all registered types - */ - std::vector > get_types() const - { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif - - return std::vector >(m_state.m_types.begin(), m_state.m_types.end()); - } - - /** - * Return a function by name - */ - std::vector< Proxy_Function > - get_function(const std::string &t_name) const - { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif - - const std::map > &funs = get_functions_int(); - - std::map >::const_iterator itr - = funs.find(t_name); - - if (itr != funs.end()) + /** + * Get a vector of all registered functions + */ + std::vector > get_functions() const { - return itr->second; - } else { - return std::vector(); - } - - } - - /** - * Return true if a function exists - */ - bool function_exists(const std::string &name) const - { #ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); + boost::shared_lock l(m_mutex); #endif + std::vector > rets; - const std::map > &functions = get_functions_int(); - return functions.find(name) != functions.end(); - } + const std::map > &functions = get_functions_int(); - /** - * Get a vector of all registered functions - */ - std::vector > get_functions() const - { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif - std::vector > rets; - - const std::map > &functions = get_functions_int(); - - for (std::map >::const_iterator itr = functions.begin(); - itr != functions.end(); - ++itr) - { - for (std::vector::const_iterator itr2 = itr->second.begin(); - itr2 != itr->second.end(); - ++itr2) + for (std::map >::const_iterator itr = functions.begin(); + itr != functions.end(); + ++itr) { - rets.push_back(std::make_pair(itr->first, *itr2)); + for (std::vector::const_iterator itr2 = itr->second.begin(); + itr2 != itr->second.end(); + ++itr2) + { + rets.push_back(std::make_pair(itr->first, *itr2)); + } } + + return rets; } - return rets; - } - - void add_reserved_word(const std::string &name) - { + void add_reserved_word(const std::string &name) + { #ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); + boost::unique_lock l(m_mutex); #endif - m_state.m_reserved_words.insert(name); - } + m_state.m_reserved_words.insert(name); + } - Boxed_Value call_function(const std::string &t_name, const std::vector ¶ms) const - { - std::vector functions = get_function(t_name); + Boxed_Value call_function(const std::string &t_name, const std::vector ¶ms) const + { + std::vector functions = get_function(t_name); - return detail::dispatch(functions.begin(), functions.end(), params); - } + return dispatch::dispatch(functions.begin(), functions.end(), params); + } - Boxed_Value call_function(const std::string &t_name) const - { - return call_function(t_name, std::vector()); - } + Boxed_Value call_function(const std::string &t_name) const + { + return call_function(t_name, std::vector()); + } - Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1) const - { - std::vector params; - params.push_back(p1); - return call_function(t_name, params); - } + Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1) const + { + std::vector params; + params.push_back(p1); + return call_function(t_name, params); + } - Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1, const Boxed_Value &p2) const - { - std::vector params; - params.push_back(p1); - params.push_back(p2); - return call_function(t_name, params); - } + Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1, const Boxed_Value &p2) const + { + std::vector params; + params.push_back(p1); + params.push_back(p2); + return call_function(t_name, params); + } - /** - * Dump object info to stdout - */ + /** + * Dump object info to stdout + */ void dump_object(Boxed_Value o) const { Type_Info ti = o.get_type_info(); std::cout << (ti.is_const()?"const ":"") << get_type_name(ti) << std::endl; } - /** - * Dump type info to stdout - */ + /** + * Dump type info to stdout + */ void dump_type(const Type_Info &type) const { std::cout << (type.is_const()?"const ":"") << get_type_name(type); } - /** - * Dump function to stdout - */ + /** + * Dump function to stdout + */ void dump_function(const std::pair &f) const { std::vector params = f.second->get_param_types(); @@ -717,9 +721,9 @@ namespace chaiscript std::cout << ") " << std::endl; } - /** - * Dump all system info to stdout - */ + /** + * Dump all system info to stdout + */ void dump_system() const { std::cout << "Registered Types: " << std::endl; @@ -746,249 +750,249 @@ namespace chaiscript std::cout << std::endl; } - /** - * return true if the Boxed_Value matches the registered type by name - */ - bool is_type(Boxed_Value r, const std::string &user_typename) const - { - try { - if (get_type(user_typename).bare_equal(r.get_type_info())) - { - return true; - } - } catch (const std::range_error &) { - } - - try { - const Dynamic_Object &d = boxed_cast(r); - return d.get_type_name() == user_typename; - } catch (const std::bad_cast &) { - } - - return false; - } - - std::string type_name(Boxed_Value obj) const - { - return get_type_name(obj.get_type_info()); - } - - State get_state() - { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); - boost::unique_lock l2(m_global_object_mutex); -#endif - - return m_state; - } - - void set_state(const State &t_state) - { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); - boost::unique_lock l2(m_global_object_mutex); -#endif - - m_state = t_state; - } - - - private: - /** - * Returns the current stack - * make const/non const versions - */ - StackData &get_stack_data() const - { - return *(m_stack_holder->stack); - } - - const std::map > &get_functions_int() const - { - return m_state.m_functions; - } - - std::map > &get_functions_int() - { - return m_state.m_functions; - } - - static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) - { - const std::vector lhsparamtypes = lhs->get_param_types(); - const std::vector rhsparamtypes = rhs->get_param_types(); - - const int lhssize = lhsparamtypes.size(); - const int rhssize = rhsparamtypes.size(); - - const Type_Info boxed_type = user_type(); - const Type_Info boxed_pod_type = user_type(); - - boost::shared_ptr dynamic_lhs(boost::dynamic_pointer_cast(lhs)); - boost::shared_ptr dynamic_rhs(boost::dynamic_pointer_cast(rhs)); - - if (dynamic_lhs && dynamic_rhs) + /** + * return true if the Boxed_Value matches the registered type by name + */ + bool is_type(Boxed_Value r, const std::string &user_typename) const { - if (dynamic_lhs->get_guard()) - { - if (dynamic_rhs->get_guard()) + try { + if (get_type(user_typename).bare_equal(r.get_type_info())) { - return false; - } else { return true; } - } else { - return false; + } catch (const std::range_error &) { + } + + try { + const dispatch::Dynamic_Object &d = boxed_cast(r); + return d.get_type_name() == user_typename; + } catch (const std::bad_cast &) { } - } - if (dynamic_lhs && !dynamic_rhs) - { return false; } - if (!dynamic_lhs && dynamic_rhs) + std::string type_name(Boxed_Value obj) const { - return true; + return get_type_name(obj.get_type_info()); } - - - for (int i = 1; i < lhssize && i < rhssize; ++i) + State get_state() { - const Type_Info lt = lhsparamtypes[i]; - const Type_Info rt = rhsparamtypes[i]; - - if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) - { - continue; // The first two types are essentially the same, next iteration - } - - // const is after non-const for the same type - if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) - { - return false; - } - - if (lt.bare_equal(rt) && !lt.is_const()) - { - return true; - } - - // boxed_values are sorted last - if (lt.bare_equal(boxed_type)) - { - return false; - } - - if (rt.bare_equal(boxed_type)) - { - if (lt.bare_equal(boxed_pod_type)) - { - return true; - } - return true; - } - - if (lt.bare_equal(boxed_pod_type)) - { - return false; - } - - if (rt.bare_equal(boxed_pod_type)) - { - return true; - } - - // otherwise, we want to sort by typeid - return lt < rt; - } - - return false; - } - - - /** - * Throw a reserved_word exception if the name is not allowed - */ - void validate_object_name(const std::string &name) const - { #ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); + boost::unique_lock l(m_mutex); + boost::unique_lock l2(m_global_object_mutex); #endif - if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end()) - { - throw exception::reserved_word_error(name); + return m_state; } - } - /** - * Implementation detail for adding a function. Returns - * true if the function was added, false if a function with the - * same signature and name already exists. - */ - bool add_function(const Proxy_Function &t_f, const std::string &t_name) - { + void set_state(const State &t_state) + { #ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); + boost::unique_lock l(m_mutex); + boost::unique_lock l2(m_global_object_mutex); #endif - std::map > &funcs = get_functions_int(); - - std::map >::iterator itr - = funcs.find(t_name); + m_state = t_state; + } - if (itr != funcs.end()) + + private: + /** + * Returns the current stack + * make const/non const versions + */ + StackData &get_stack_data() const { - std::vector &vec = itr->second; - for (std::vector::const_iterator itr2 = vec.begin(); - itr2 != vec.end(); - ++itr2) + return *(m_stack_holder->stack); + } + + const std::map > &get_functions_int() const + { + return m_state.m_functions; + } + + std::map > &get_functions_int() + { + return m_state.m_functions; + } + + static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) + { + const std::vector lhsparamtypes = lhs->get_param_types(); + const std::vector rhsparamtypes = rhs->get_param_types(); + + const int lhssize = lhsparamtypes.size(); + const int rhssize = rhsparamtypes.size(); + + const Type_Info boxed_type = user_type(); + const Type_Info boxed_pod_type = user_type(); + + boost::shared_ptr dynamic_lhs(boost::dynamic_pointer_cast(lhs)); + boost::shared_ptr dynamic_rhs(boost::dynamic_pointer_cast(rhs)); + + if (dynamic_lhs && dynamic_rhs) { - if ((*t_f) == *(*itr2)) + if (dynamic_lhs->get_guard()) { + if (dynamic_rhs->get_guard()) + { + return false; + } else { + return true; + } + } else { return false; } } - vec.push_back(t_f); - std::stable_sort(vec.begin(), vec.end(), &function_less_than); - } else { - std::vector vec; - vec.push_back(t_f); - funcs.insert(std::make_pair(t_name, vec)); + if (dynamic_lhs && !dynamic_rhs) + { + return false; + } + + if (!dynamic_lhs && dynamic_rhs) + { + return true; + } + + + + for (int i = 1; i < lhssize && i < rhssize; ++i) + { + const Type_Info lt = lhsparamtypes[i]; + const Type_Info rt = rhsparamtypes[i]; + + if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) + { + continue; // The first two types are essentially the same, next iteration + } + + // const is after non-const for the same type + if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) + { + return false; + } + + if (lt.bare_equal(rt) && !lt.is_const()) + { + return true; + } + + // boxed_values are sorted last + if (lt.bare_equal(boxed_type)) + { + return false; + } + + if (rt.bare_equal(boxed_type)) + { + if (lt.bare_equal(boxed_pod_type)) + { + return true; + } + return true; + } + + if (lt.bare_equal(boxed_pod_type)) + { + return false; + } + + if (rt.bare_equal(boxed_pod_type)) + { + return true; + } + + // otherwise, we want to sort by typeid + return lt < rt; + } + + return false; } - return true; - } + /** + * Throw a reserved_word exception if the name is not allowed + */ + void validate_object_name(const std::string &name) const + { #ifndef CHAISCRIPT_NO_THREADS - mutable boost::shared_mutex m_mutex; - mutable boost::shared_mutex m_global_object_mutex; + boost::shared_lock l(m_mutex); #endif - struct Stack_Holder - { - Stack_Holder() - : stack(new StackData()) - { - stack->push_back(Scope()); + if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end()) + { + throw exception::reserved_word_error(name); + } } - Stack stack; - }; + /** + * Implementation detail for adding a function. Returns + * true if the function was added, false if a function with the + * same signature and name already exists. + */ + bool add_function(const Proxy_Function &t_f, const std::string &t_name) + { +#ifndef CHAISCRIPT_NO_THREADS + boost::unique_lock l(m_mutex); +#endif - std::vector m_conversions; - chaiscript::detail::threading::Thread_Storage m_stack_holder; + std::map > &funcs = get_functions_int(); + + std::map >::iterator itr + = funcs.find(t_name); + + if (itr != funcs.end()) + { + std::vector &vec = itr->second; + for (std::vector::const_iterator itr2 = vec.begin(); + itr2 != vec.end(); + ++itr2) + { + if ((*t_f) == *(*itr2)) + { + return false; + } + } + + vec.push_back(t_f); + std::stable_sort(vec.begin(), vec.end(), &function_less_than); + } else { + std::vector vec; + vec.push_back(t_f); + funcs.insert(std::make_pair(t_name, vec)); + } + + return true; + } + +#ifndef CHAISCRIPT_NO_THREADS + mutable boost::shared_mutex m_mutex; + mutable boost::shared_mutex m_global_object_mutex; +#endif + + struct Stack_Holder + { + Stack_Holder() + : stack(new StackData()) + { + stack->push_back(Scope()); + } + + Stack stack; + }; + + std::vector m_conversions; + chaiscript::detail::threading::Thread_Storage m_stack_holder; - State m_state; - - Boxed_Value m_place_holder; - }; + State m_state; + Boxed_Value m_place_holder; + }; + } } #endif diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 732bd8a..0269088 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -11,270 +11,273 @@ namespace chaiscript { - class Dynamic_Object + namespace dispatch { - public: - Dynamic_Object(const std::string &t_type_name) - : m_type_name(t_type_name) - { - } - - std::string get_type_name() const - { - return m_type_name; - } - - Boxed_Value get_attr(const std::string &t_attr_name) - { - return m_attrs[t_attr_name]; - } - - std::map get_attrs() - { - return m_attrs; - } - - private: - std::string m_type_name; - - std::map m_attrs; - }; - - namespace detail - { - struct Dynamic_Object_Attribute - { - static Boxed_Value func(const std::string &t_type_name, const std::string &t_attr_name, - Dynamic_Object &t_do) - { - if (t_do.get_type_name() != t_type_name) - { - throw exception::bad_boxed_cast("Dynamic object type mismatch"); - } - - return t_do.get_attr(t_attr_name); - } - }; - - /** - * A Proxy_Function implementation designed for calling a function - * that is automatically guarded based on the first param based on the - * param's type name - */ - class Dynamic_Object_Function : public Proxy_Function_Base + class Dynamic_Object { public: - Dynamic_Object_Function( - const std::string &t_type_name, - const Proxy_Function &t_func, - const boost::optional &t_ti = boost::optional()) - : Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)), - m_type_name(t_type_name), m_func(t_func), m_ti(t_ti) + Dynamic_Object(const std::string &t_type_name) + : m_type_name(t_type_name) + { + } + + std::string get_type_name() const + { + return m_type_name; + } + + Boxed_Value get_attr(const std::string &t_attr_name) + { + return m_attrs[t_attr_name]; + } + + std::map get_attrs() + { + return m_attrs; + } + + private: + std::string m_type_name; + + std::map m_attrs; + }; + + namespace detail + { + struct Dynamic_Object_Attribute + { + static Boxed_Value func(const std::string &t_type_name, const std::string &t_attr_name, + Dynamic_Object &t_do) + { + if (t_do.get_type_name() != t_type_name) + { + throw exception::bad_boxed_cast("Dynamic object type mismatch"); + } + + return t_do.get_attr(t_attr_name); + } + }; + + /** + * A Proxy_Function implementation designed for calling a function + * that is automatically guarded based on the first param based on the + * param's type name + */ + class Dynamic_Object_Function : public Proxy_Function_Base + { + public: + Dynamic_Object_Function( + const std::string &t_type_name, + const Proxy_Function &t_func, + const boost::optional &t_ti = boost::optional()) + : Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)), + m_type_name(t_type_name), m_func(t_func), m_ti(t_ti) { assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); } - virtual ~Dynamic_Object_Function() {} + virtual ~Dynamic_Object_Function() {} - virtual bool operator==(const Proxy_Function_Base &f) const - { - const Dynamic_Object_Function *df = dynamic_cast(&f); - if (df) + virtual bool operator==(const Proxy_Function_Base &f) const { - return df->m_type_name == m_type_name && (*df->m_func) == (*m_func); - } else { - return false; - } - } - - virtual bool call_match(const std::vector &vals) const - { - if (dynamic_object_typename_match(vals, m_type_name, m_ti)) - { - return m_func->call_match(vals); - } else { - return false; - } - } - - virtual std::vector get_contained_functions() const - { - std::vector fs; - fs.push_back(m_func); - return fs; - } - - - virtual int get_arity() const - { - return m_func->get_arity(); - } - - virtual std::string annotation() const - { - return m_func->annotation(); - } - - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - if (dynamic_object_typename_match(params, m_type_name, m_ti)) - { - return (*m_func)(params); - } else { - throw exception::guard_error(); - } - } - - virtual bool compare_first_type(const Boxed_Value &bv) const - { - return dynamic_object_typename_match(bv, m_type_name, m_ti); - } - - private: - static std::vector build_param_types( - const std::vector &t_inner_types, boost::optional t_objectti) - { - if (t_objectti) - { - std::vector types(t_inner_types); - - assert(types.size() > 1); - assert(types[1].bare_equal(user_type())); - types[1] = *t_objectti; - return types; - } else { - return t_inner_types; - } - } - - static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, - const boost::optional &ti) - { - static Type_Info doti = user_type(); - if (bv.get_type_info().bare_equal(doti)) - { - try { - const Dynamic_Object &d = boxed_cast(bv); - return name == "Dynamic_Object" || d.get_type_name() == name; - } catch (const std::bad_cast &) { - return false; - } - } else { - if (ti) + const Dynamic_Object_Function *df = dynamic_cast(&f); + if (df) { - return bv.get_type_info().bare_equal(*ti); + return df->m_type_name == m_type_name && (*df->m_func) == (*m_func); } else { return false; } } - } - - static bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, - const boost::optional &ti) - { - if (bvs.size() > 0) + virtual bool call_match(const std::vector &vals) const { - return dynamic_object_typename_match(bvs[0], name, ti); - } else { - return false; + if (dynamic_object_typename_match(vals, m_type_name, m_ti)) + { + return m_func->call_match(vals); + } else { + return false; + } + } + + virtual std::vector get_contained_functions() const + { + std::vector fs; + fs.push_back(m_func); + return fs; } - } - - std::string m_type_name; - Proxy_Function m_func; - boost::optional m_ti; - - }; - /** - * A Proxy_Function implementation designed for creating a new - * Dynamic_Object - * that is automatically guarded based on the first param based on the - * param's type name - */ - class Dynamic_Object_Constructor : public Proxy_Function_Base - { - public: - Dynamic_Object_Constructor( - const std::string &t_type_name, - const Proxy_Function &t_func) - : Proxy_Function_Base(build_type_list(t_func->get_param_types())), - m_type_name(t_type_name), m_func(t_func) + virtual int get_arity() const + { + return m_func->get_arity(); + } + + virtual std::string annotation() const + { + return m_func->annotation(); + } + + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + if (dynamic_object_typename_match(params, m_type_name, m_ti)) + { + return (*m_func)(params); + } else { + throw exception::guard_error(); + } + } + + virtual bool compare_first_type(const Boxed_Value &bv) const + { + return dynamic_object_typename_match(bv, m_type_name, m_ti); + } + + private: + static std::vector build_param_types( + const std::vector &t_inner_types, boost::optional t_objectti) + { + if (t_objectti) + { + std::vector types(t_inner_types); + + assert(types.size() > 1); + assert(types[1].bare_equal(user_type())); + types[1] = *t_objectti; + return types; + } else { + return t_inner_types; + } + } + + static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, + const boost::optional &ti) + { + static Type_Info doti = user_type(); + if (bv.get_type_info().bare_equal(doti)) + { + try { + const Dynamic_Object &d = boxed_cast(bv); + return name == "Dynamic_Object" || d.get_type_name() == name; + } catch (const std::bad_cast &) { + return false; + } + } else { + if (ti) + { + return bv.get_type_info().bare_equal(*ti); + } else { + return false; + } + } + + } + + static bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, + const boost::optional &ti) + { + if (bvs.size() > 0) + { + return dynamic_object_typename_match(bvs[0], name, ti); + } else { + return false; + } + } + + std::string m_type_name; + Proxy_Function m_func; + boost::optional m_ti; + + }; + + + /** + * A Proxy_Function implementation designed for creating a new + * Dynamic_Object + * that is automatically guarded based on the first param based on the + * param's type name + */ + class Dynamic_Object_Constructor : public Proxy_Function_Base + { + public: + Dynamic_Object_Constructor( + const std::string &t_type_name, + const Proxy_Function &t_func) + : Proxy_Function_Base(build_type_list(t_func->get_param_types())), + m_type_name(t_type_name), m_func(t_func) { assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); } - static std::vector build_type_list(const std::vector &tl) - { - std::vector::const_iterator begin = tl.begin(); - std::vector::const_iterator end = tl.end(); - - if (begin != end) + static std::vector build_type_list(const std::vector &tl) { - ++begin; + std::vector::const_iterator begin = tl.begin(); + std::vector::const_iterator end = tl.end(); + + if (begin != end) + { + ++begin; + } + + return std::vector(begin, end); } - return std::vector(begin, end); - } + virtual ~Dynamic_Object_Constructor() {} - virtual ~Dynamic_Object_Constructor() {} - - virtual bool operator==(const Proxy_Function_Base &f) const - { - const Dynamic_Object_Constructor *dc = dynamic_cast(&f); - if (dc) + virtual bool operator==(const Proxy_Function_Base &f) const { - return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); - } else { - return false; + const Dynamic_Object_Constructor *dc = dynamic_cast(&f); + if (dc) + { + return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); + } else { + return false; + } } - } - virtual bool call_match(const std::vector &vals) const - { - std::vector new_vals; - new_vals.push_back(Boxed_Value(Dynamic_Object(m_type_name))); - new_vals.insert(new_vals.end(), vals.begin(), vals.end()); + virtual bool call_match(const std::vector &vals) const + { + std::vector new_vals; + new_vals.push_back(Boxed_Value(Dynamic_Object(m_type_name))); + new_vals.insert(new_vals.end(), vals.begin(), vals.end()); - return m_func->call_match(new_vals); - } + return m_func->call_match(new_vals); + } - virtual int get_arity() const - { - // "this" is not considered part of the arity - return m_func->get_arity() - 1; - } + virtual int get_arity() const + { + // "this" is not considered part of the arity + return m_func->get_arity() - 1; + } - virtual std::string annotation() const - { - return m_func->annotation(); - } + virtual std::string annotation() const + { + return m_func->annotation(); + } - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - std::vector new_params; - chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name)); - new_params.push_back(bv); - new_params.insert(new_params.end(), params.begin(), params.end()); + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + std::vector new_params; + chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name)); + new_params.push_back(bv); + new_params.insert(new_params.end(), params.begin(), params.end()); - (*m_func)(new_params); + (*m_func)(new_params); - return bv; - } + return bv; + } - private: - std::string m_type_name; - Proxy_Function m_func; + private: + std::string m_type_name; + Proxy_Function m_func; - }; + }; + } } } #endif diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 51899d1..434d3db 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -20,37 +20,39 @@ namespace chaiscript { - /** - * Build a function caller that knows how to dispatch on a set of functions - * example: - * boost::function f = - * build_function_caller(dispatchkit.get_function("print")); - * \returns A boost::function object for dispatching - * \param[in] funcs the set of functions to dispatch on. - */ - template - boost::function + namespace dispatch + { + /** + * Build a function caller that knows how to dispatch on a set of functions + * example: + * boost::function f = + * build_function_caller(dispatchkit.get_function("print")); + * \returns A boost::function object for dispatching + * \param[in] funcs the set of functions to dispatch on. + */ + template + boost::function functor(const std::vector &funcs) { FunctionType *p=0; return detail::build_function_caller_helper(p, funcs); } - /** - * Build a function caller for a particular Proxy_Function object - * useful in the case that a function is being pass out from scripting back - * into code - * example: - * void my_function(Proxy_Function f) - * { - * boost::function local_f = - * build_function_caller(f); - * } - * \returns A boost::function object for dispatching - * \param[in] func A function to execute. - */ - template - boost::function + /** + * Build a function caller for a particular Proxy_Function object + * useful in the case that a function is being pass out from scripting back + * into code + * example: + * void my_function(Proxy_Function f) + * { + * boost::function local_f = + * build_function_caller(f); + * } + * \returns A boost::function object for dispatching + * \param[in] func A function to execute. + */ + template + boost::function functor(Const_Proxy_Function func) { std::vector funcs; @@ -58,76 +60,76 @@ namespace chaiscript return functor(funcs); } - /** - * Helper for automatically unboxing a Boxed_Value that contains a function object - * and creating a typesafe C++ function caller from it. - */ - template - boost::function + /** + * Helper for automatically unboxing a Boxed_Value that contains a function object + * and creating a typesafe C++ function caller from it. + */ + template + boost::function functor(const Boxed_Value &bv) { return functor(boxed_cast(bv)); } + } namespace detail{ /** - * Cast helper to handle automatic casting to const boost::function & - */ + * Cast helper to handle automatic casting to const boost::function & + */ template struct Cast_Helper &> { typedef boost::function Result_Type; - + static Result_Type cast(const Boxed_Value &ob) { if (ob.get_type_info().bare_equal(user_type())) { - return functor(ob); + return dispatch::functor(ob); } else { return Cast_Helper_Inner &>::cast(ob); } } }; - + /** - * Cast helper to handle automatic casting to boost::function - */ + * Cast helper to handle automatic casting to boost::function + */ template struct Cast_Helper > { typedef boost::function Result_Type; - + static Result_Type cast(const Boxed_Value &ob) { if (ob.get_type_info().bare_equal(user_type())) { - return functor(ob); + return dispatch::functor(ob); } else { return Cast_Helper_Inner >::cast(ob); } } }; - + /** - * Cast helper to handle automatic casting to const boost::function - */ + * Cast helper to handle automatic casting to const boost::function + */ template struct Cast_Helper > { typedef boost::function Result_Type; - + static Result_Type cast(const Boxed_Value &ob) { if (ob.get_type_info().bare_equal(user_type())) { - return functor(ob); + return dispatch::functor(ob); } else { return Cast_Helper_Inner >::cast(ob); } } }; } - } #endif diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index d6798c8..49a877a 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -23,35 +23,38 @@ namespace chaiscript { - namespace detail + namespace dispatch { + namespace detail + { - /** - * Internal helper class for handling the return - * value of a build_function_caller - */ - template - struct Function_Caller_Ret - { - static Ret call(const std::vector &t_funcs, - const std::vector ¶ms) + /** + * Internal helper class for handling the return + * value of a build_function_caller + */ + template + struct Function_Caller_Ret { - return boxed_cast(dispatch(t_funcs, params)); - } - }; + static Ret call(const std::vector &t_funcs, + const std::vector ¶ms) + { + return boxed_cast(dispatch::dispatch(t_funcs, params)); + } + }; - /** - * Specialization for void return types - */ - template<> - struct Function_Caller_Ret - { - static void call(const std::vector &t_funcs, - const std::vector ¶ms) + /** + * Specialization for void return types + */ + template<> + struct Function_Caller_Ret { - dispatch(t_funcs, params); - } - }; + static void call(const std::vector &t_funcs, + const std::vector ¶ms) + { + dispatch::dispatch(t_funcs, params); + } + }; + } } } @@ -65,47 +68,49 @@ namespace chaiscript namespace chaiscript { - namespace detail + namespace dispatch { - /** - * used internally for unwrapping a function call's types - */ - template - Ret function_caller(const std::vector &funcs - BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) - { - std::vector params; - - BOOST_PP_REPEAT(n, addparam, ~) - - return Function_Caller_Ret::call(funcs, params); - } - - /** - * used internally for unwrapping a function call's types - */ - template - boost::function - build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector &funcs) - { - if (funcs.size() == 1) + namespace detail + { + /** + * used internally for unwrapping a function call's types + */ + template + Ret function_caller(const std::vector &funcs + BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) { - boost::shared_ptr > pfi = - boost::dynamic_pointer_cast > - (funcs[0]); + std::vector params; - if (pfi) - { - return pfi->internal_function(); - } - // 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 + BOOST_PP_REPEAT(n, addparam, ~) + + return Function_Caller_Ret::call(funcs, params); } - return boost::bind(&function_caller, funcs - BOOST_PP_ENUM_TRAILING(n, curry, ~)); - } + /** + * used internally for unwrapping a function call's types + */ + template + boost::function + build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector &funcs) + { + if (funcs.size() == 1) + { + boost::shared_ptr > pfi = + boost::dynamic_pointer_cast > + (funcs[0]); + if (pfi) + { + return pfi->internal_function(); + } + // 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 boost::bind(&function_caller, funcs + BOOST_PP_ENUM_TRAILING(n, curry, ~)); + } + } } } #undef n diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index ed3a7c9..73e0afe 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -26,7 +26,7 @@ namespace chaiscript Proxy_Function constructor() { T *f = 0; - return (detail::build_constructor_(f)); + return (dispatch::detail::build_constructor_(f)); } } @@ -35,30 +35,33 @@ namespace chaiscript namespace chaiscript { - namespace detail + namespace dispatch { - /** - * A constructor function, used for creating a new object - * of a given type with a given set of params - */ - template - boost::shared_ptr constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) - { - return boost::shared_ptr(new Class( BOOST_PP_ENUM_PARAMS(n, p) )); - } + namespace detail + { + /** + * A constructor function, used for creating a new object + * of a given type with a given set of params + */ + template + boost::shared_ptr constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) + { + return boost::shared_ptr(new Class( BOOST_PP_ENUM_PARAMS(n, p) )); + } - /** - * Helper function for build a constructor function - * example: - * dispatchengine.register_function(build_constructor, "MyClass"); - * \todo See if it is possible to make this not be a variadic function - */ - template - Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param))) - { - typedef boost::shared_ptr (sig)(BOOST_PP_ENUM_PARAMS(n, Param)); - return Proxy_Function(new Proxy_Function_Impl(boost::function(&(constructor_)))); - } + /** + * Helper function for build a constructor function + * example: + * dispatchengine.register_function(build_constructor, "MyClass"); + * \todo See if it is possible to make this not be a variadic function + */ + template + Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param))) + { + typedef boost::shared_ptr (sig)(BOOST_PP_ENUM_PARAMS(n, Param)); + return Proxy_Function(new Proxy_Function_Impl(boost::function(&(constructor_)))); + } + } } } #undef n diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 4ec0bc9..97ef808 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -26,154 +26,157 @@ namespace chaiscript typedef boost::shared_ptr AST_NodePtr; - /** - * Helper for building a list of parameters for calling a Proxy_Function - * it does automatic conversion to Boxed_Value types via operator<< - * - * example usage: - * Boxed_Value retval = dispatch(dispatchengine.get_function("+"), - * chaiscript::Param_List_Builder() << 5 << 6); - */ - struct Param_List_Builder + namespace dispatch { - Param_List_Builder &operator<<(const Boxed_Value &so) + /** + * Helper for building a list of parameters for calling a Proxy_Function + * it does automatic conversion to Boxed_Value types via operator<< + * + * example usage: + * Boxed_Value retval = dispatch(dispatchengine.get_function("+"), + * chaiscript::Param_List_Builder() << 5 << 6); + */ + struct Param_List_Builder { - objects.push_back(so); - return *this; - } - - template - Param_List_Builder &operator<<(T t) + Param_List_Builder &operator<<(const Boxed_Value &so) { - objects.push_back(Boxed_Value(t)); + objects.push_back(so); return *this; } - operator const std::vector &() const - { - return objects; - } - - std::vector objects; - }; - - /** - * Pure virtual base class for all Proxy_Function implementations - * Proxy_Functions are a type erasure of type safe C++ - * function calls. At runtime parameter types are expected to be - * tested against passed in types. - * Dispatch_Engine only knows how to work with Proxy_Function, no other - * function classes. - */ - class Proxy_Function_Base - { - public: - virtual ~Proxy_Function_Base() {} - Boxed_Value operator()(const std::vector ¶ms) const - { - Boxed_Value bv = do_call(params); - bv.add_dependencies(params.begin(), params.end()); - return bv; - } - - /// Returns a vector containing all of the types of the parameters the function returns/takes - /// if the function is variadic or takes no arguments (arity of 0 or -1), the returned - /// value containes exactly 1 Type_Info object: the return type - /// \returns the types of all parameters. - 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 = 0; - - virtual std::vector > get_contained_functions() const - { - return std::vector >(); - } - - - //! Return true if the function is a possible match - //! to the passed in values - bool filter(const std::vector &vals) const - { - int arity = get_arity(); - - if (arity < 0) + template + Param_List_Builder &operator<<(T t) { - return true; - } else if (size_t(arity) == vals.size()) { - if (arity == 0) + objects.push_back(Boxed_Value(t)); + return *this; + } + + operator const std::vector &() const + { + return objects; + } + + std::vector objects; + }; + + /** + * Pure virtual base class for all Proxy_Function implementations + * Proxy_Functions are a type erasure of type safe C++ + * function calls. At runtime parameter types are expected to be + * tested against passed in types. + * Dispatch_Engine only knows how to work with Proxy_Function, no other + * function classes. + */ + class Proxy_Function_Base + { + public: + virtual ~Proxy_Function_Base() {} + Boxed_Value operator()(const std::vector ¶ms) const + { + Boxed_Value bv = do_call(params); + bv.add_dependencies(params.begin(), params.end()); + return bv; + } + + /// Returns a vector containing all of the types of the parameters the function returns/takes + /// if the function is variadic or takes no arguments (arity of 0 or -1), the returned + /// value containes exactly 1 Type_Info object: the return type + /// \returns the types of all parameters. + 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 = 0; + + virtual std::vector > get_contained_functions() const + { + return std::vector >(); + } + + + //! Return true if the function is a possible match + //! to the passed in values + bool filter(const std::vector &vals) const + { + int arity = get_arity(); + + if (arity < 0) + { + return true; + } else if (size_t(arity) == vals.size()) { + if (arity == 0) + { + return true; + } else { + return compare_first_type(vals[0]); + } + } else { + return false; + } + } + + /// \returns the number of arguments the function takes or -1 if it is variadic + virtual int get_arity() const = 0; + + virtual std::string annotation() const = 0; + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const = 0; + + Proxy_Function_Base(const std::vector &t_types) + : m_types(t_types) + { + } + + virtual bool compare_first_type(const Boxed_Value &bv) const + { + const std::vector &types = get_param_types(); + + if (types.size() < 2) + { + return true; + } + const Type_Info &ti = types[1]; + if (ti.is_undef() + || ti.bare_equal(user_type()) + || (!bv.get_type_info().is_undef() + && (ti.bare_equal(user_type()) + || ti.bare_equal(bv.get_type_info()) + || detail::dynamic_cast_converts(ti, bv.get_type_info()) + || bv.get_type_info().bare_equal(user_type >()) + ) + ) + ) { return true; } else { - return compare_first_type(vals[0]); + return false; } - } else { - return false; } - } - /// \returns the number of arguments the function takes or -1 if it is variadic - virtual int get_arity() const = 0; - - virtual std::string annotation() const = 0; - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const = 0; - - Proxy_Function_Base(const std::vector &t_types) - : m_types(t_types) - { - } - - virtual bool compare_first_type(const Boxed_Value &bv) const - { - const std::vector &types = get_param_types(); - - if (types.size() < 2) + bool compare_types(const std::vector &tis, const std::vector &bvs) const { - return true; - } - const Type_Info &ti = types[1]; - if (ti.is_undef() - || ti.bare_equal(user_type()) - || (!bv.get_type_info().is_undef() - && (ti.bare_equal(user_type()) - || ti.bare_equal(bv.get_type_info()) - || detail::dynamic_cast_converts(ti, bv.get_type_info()) - || bv.get_type_info().bare_equal(user_type >()) - ) - ) - ) - { - return true; - } else { - return false; - } - } - - bool compare_types(const std::vector &tis, const std::vector &bvs) const - { - if (tis.size() - 1 != bvs.size()) - { - return false; - } else { - size_t size = bvs.size(); - for (size_t i = 0; i < size; ++i) + if (tis.size() - 1 != bvs.size()) { - if (!(tis[i+1].bare_equal(bvs[i].get_type_info()) && tis[i+1].is_const() >= bvs[i].get_type_info().is_const() )) + return false; + } else { + size_t size = bvs.size(); + for (size_t i = 0; i < size; ++i) { - return false; + if (!(tis[i+1].bare_equal(bvs[i].get_type_info()) && tis[i+1].is_const() >= bvs[i].get_type_info().is_const() )) + { + return false; + } } } + return true; } - return true; - } - std::vector m_types; - }; + std::vector m_types; + }; + } - typedef boost::shared_ptr Proxy_Function; - typedef boost::shared_ptr Const_Proxy_Function; + typedef boost::shared_ptr Proxy_Function; + typedef boost::shared_ptr Const_Proxy_Function; namespace exception { @@ -192,382 +195,385 @@ namespace chaiscript }; } - /** - * A Proxy_Function implementation that is not type safe, the called function - * is expecting a vector that it works with how it chooses. - */ - class Dynamic_Proxy_Function : public Proxy_Function_Base + namespace dispatch { - public: - Dynamic_Proxy_Function( - const boost::function &)> &t_f, - int t_arity=-1, - const AST_NodePtr &t_parsenode = AST_NodePtr(), - const std::string &t_description = "", - const Proxy_Function &t_guard = Proxy_Function()) - : Proxy_Function_Base(build_param_type_list(t_arity)), + /** + * A Proxy_Function implementation that is not type safe, the called function + * is expecting a vector that it works with how it chooses. + */ + class Dynamic_Proxy_Function : public Proxy_Function_Base + { + public: + Dynamic_Proxy_Function( + const boost::function &)> &t_f, + int t_arity=-1, + const AST_NodePtr &t_parsenode = AST_NodePtr(), + const std::string &t_description = "", + const Proxy_Function &t_guard = Proxy_Function()) + : Proxy_Function_Base(build_param_type_list(t_arity)), m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard), m_parsenode(t_parsenode) { } - virtual bool operator==(const Proxy_Function_Base &rhs) const - { - return this == &rhs; - } + virtual bool operator==(const Proxy_Function_Base &rhs) const + { + return this == &rhs; + } - virtual bool call_match(const std::vector &vals) const - { + virtual bool call_match(const std::vector &vals) const + { return (m_arity < 0 || vals.size() == size_t(m_arity)) && test_guard(vals); - } + } - virtual ~Dynamic_Proxy_Function() {} + virtual ~Dynamic_Proxy_Function() {} - virtual int get_arity() const - { - return m_arity; - } - - Proxy_Function get_guard() const - { - return m_guard; - } - - AST_NodePtr get_parse_tree() const - { - return m_parsenode; - } - - virtual std::string annotation() const - { - return m_description; - } - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - if (m_arity < 0 || params.size() == size_t(m_arity)) + virtual int get_arity() const { + return m_arity; + } - if (test_guard(params)) + Proxy_Function get_guard() const + { + return m_guard; + } + + AST_NodePtr get_parse_tree() const + { + return m_parsenode; + } + + virtual std::string annotation() const + { + return m_description; + } + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + if (m_arity < 0 || params.size() == size_t(m_arity)) { - return m_f(params); + + if (test_guard(params)) + { + return m_f(params); + } else { + throw exception::guard_error(); + } + } else { - throw exception::guard_error(); - } - - } else { - throw exception::arity_error(static_cast(params.size()), m_arity); - } - } - - private: - bool test_guard(const std::vector ¶ms) const - { - if (m_guard) - { - try { - return boxed_cast((*m_guard)(params)); - } catch (const exception::arity_error &) { - return false; - } catch (const exception::bad_boxed_cast &) { - return false; - } - } else { - return true; - } - } - - static std::vector build_param_type_list(int arity) - { - std::vector types; - - // For the return type - types.push_back(detail::Get_Type_Info::get()); - - if (arity >= 0) - { - for (int i = 0; i < arity; ++i) - { - types.push_back(detail::Get_Type_Info::get()); - } - } - - return types; - } - - boost::function &)> m_f; - int m_arity; - std::string m_description; - Proxy_Function m_guard; - AST_NodePtr m_parsenode; - }; - - /** - * An object used by Bound_Function to represent "_" parameters - * of a binding. This allows for unbound parameters during bind. - */ - struct Placeholder_Object - { - }; - - /** - * An implementation of Proxy_Function that takes a Proxy_Function - * and substitutes bound parameters into the parameter list - * at runtime, when call() is executed. - * it is used for bind(function, param1, _, param2) style calls - */ - class Bound_Function : public Proxy_Function_Base - { - public: - Bound_Function(const Const_Proxy_Function &t_f, - const std::vector &t_args) - : Proxy_Function_Base(build_param_type_info(t_f, t_args)), - m_f(t_f), m_args(t_args), m_arity(t_f->get_arity()<0?-1:static_cast(get_param_types().size())-1) - { - assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast(m_args.size())); - } - - virtual bool operator==(const Proxy_Function_Base &t_f) const - { - return &t_f == this; - } - - virtual ~Bound_Function() {} - - virtual bool call_match(const std::vector &vals) const - { - return m_f->call_match(build_param_list(vals)); - } - - virtual Boxed_Value operator()(const std::vector ¶ms) const - { - return (*m_f)(build_param_list(params)); - } - - virtual std::vector get_contained_functions() const - { - std::vector fs; - fs.push_back(m_f); - return fs; - } - - - std::vector build_param_list(const std::vector ¶ms) const - { - typedef std::vector::const_iterator pitr; - - pitr parg = params.begin(); - pitr barg = m_args.begin(); - - std::vector args; - - while (!(parg == params.end() && barg == m_args.end())) - { - while (barg != m_args.end() - && !(barg->get_type_info() == detail::Get_Type_Info::get())) - { - args.push_back(*barg); - ++barg; - } - - if (parg != params.end()) - { - args.push_back(*parg); - ++parg; - } - - if (barg != m_args.end() - && barg->get_type_info() == detail::Get_Type_Info::get()) - { - ++barg; + throw exception::arity_error(static_cast(params.size()), m_arity); } } - return args; - } - virtual int get_arity() const - { - return m_arity; - } - - virtual std::string annotation() const - { - return "Bound: " + m_f->annotation(); - } - - protected: - static std::vector build_param_type_info(const Const_Proxy_Function &t_f, - const std::vector &t_args) - { - assert(t_f->get_arity() < 0 || t_f->get_arity() == static_cast(t_args.size())); - if (t_f->get_arity() < 0) { return std::vector(); } - - std::vector types = t_f->get_param_types(); - assert(types.size() == t_args.size() + 1); - - std::vector retval; - retval.push_back(types[0]); - for (size_t i = 0; i < types.size()-1; ++i) + private: + bool test_guard(const std::vector ¶ms) const { - if (t_args[i].get_type_info() == detail::Get_Type_Info::get()) + if (m_guard) { - retval.push_back(types[i+1]); + try { + return boxed_cast((*m_guard)(params)); + } catch (const exception::arity_error &) { + return false; + } catch (const exception::bad_boxed_cast &) { + return false; + } + } else { + return true; } } - return retval; - } + static std::vector build_param_type_list(int arity) + { + std::vector types; - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - return (*m_f)(build_param_list(params)); - } + // For the return type + types.push_back(detail::Get_Type_Info::get()); - private: - Const_Proxy_Function m_f; - std::vector m_args; - int m_arity; - }; + if (arity >= 0) + { + for (int i = 0; i < arity; ++i) + { + types.push_back(detail::Get_Type_Info::get()); + } + } - /** - * The standard typesafe function call implementation of Proxy_Function - * It takes a boost::function<> object and performs runtime - * type checking of Boxed_Value parameters, in a type safe manner - */ - template - class Proxy_Function_Impl : public Proxy_Function_Base - { - public: - Proxy_Function_Impl(const boost::function &f) - : Proxy_Function_Base(detail::build_param_type_list(static_cast(0))), + return types; + } + + boost::function &)> m_f; + int m_arity; + std::string m_description; + Proxy_Function m_guard; + AST_NodePtr m_parsenode; + }; + + /** + * An object used by Bound_Function to represent "_" parameters + * of a binding. This allows for unbound parameters during bind. + */ + struct Placeholder_Object + { + }; + + /** + * An implementation of Proxy_Function that takes a Proxy_Function + * and substitutes bound parameters into the parameter list + * at runtime, when call() is executed. + * it is used for bind(function, param1, _, param2) style calls + */ + class Bound_Function : public Proxy_Function_Base + { + public: + Bound_Function(const Const_Proxy_Function &t_f, + const std::vector &t_args) + : Proxy_Function_Base(build_param_type_info(t_f, t_args)), + m_f(t_f), m_args(t_args), m_arity(t_f->get_arity()<0?-1:static_cast(get_param_types().size())-1) + { + assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast(m_args.size())); + } + + virtual bool operator==(const Proxy_Function_Base &t_f) const + { + return &t_f == this; + } + + virtual ~Bound_Function() {} + + virtual bool call_match(const std::vector &vals) const + { + return m_f->call_match(build_param_list(vals)); + } + + virtual Boxed_Value operator()(const std::vector ¶ms) const + { + return (*m_f)(build_param_list(params)); + } + + virtual std::vector get_contained_functions() const + { + std::vector fs; + fs.push_back(m_f); + return fs; + } + + + std::vector build_param_list(const std::vector ¶ms) const + { + typedef std::vector::const_iterator pitr; + + pitr parg = params.begin(); + pitr barg = m_args.begin(); + + std::vector args; + + while (!(parg == params.end() && barg == m_args.end())) + { + while (barg != m_args.end() + && !(barg->get_type_info() == detail::Get_Type_Info::get())) + { + args.push_back(*barg); + ++barg; + } + + if (parg != params.end()) + { + args.push_back(*parg); + ++parg; + } + + if (barg != m_args.end() + && barg->get_type_info() == detail::Get_Type_Info::get()) + { + ++barg; + } + } + return args; + } + + virtual int get_arity() const + { + return m_arity; + } + + virtual std::string annotation() const + { + return "Bound: " + m_f->annotation(); + } + + protected: + static std::vector build_param_type_info(const Const_Proxy_Function &t_f, + const std::vector &t_args) + { + assert(t_f->get_arity() < 0 || t_f->get_arity() == static_cast(t_args.size())); + if (t_f->get_arity() < 0) { return std::vector(); } + + std::vector types = t_f->get_param_types(); + assert(types.size() == t_args.size() + 1); + + std::vector retval; + retval.push_back(types[0]); + for (size_t i = 0; i < types.size()-1; ++i) + { + if (t_args[i].get_type_info() == detail::Get_Type_Info::get()) + { + retval.push_back(types[i+1]); + } + } + + return retval; + } + + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + return (*m_f)(build_param_list(params)); + } + + private: + Const_Proxy_Function m_f; + std::vector m_args; + int m_arity; + }; + + /** + * The standard typesafe function call implementation of Proxy_Function + * It takes a boost::function<> object and performs runtime + * type checking of Boxed_Value parameters, in a type safe manner + */ + template + class Proxy_Function_Impl : public Proxy_Function_Base + { + public: + Proxy_Function_Impl(const boost::function &f) + : Proxy_Function_Base(detail::build_param_type_list(static_cast(0))), m_f(f), m_dummy_func(0) { } - virtual ~Proxy_Function_Impl() {} + virtual ~Proxy_Function_Impl() {} - virtual bool operator==(const Proxy_Function_Base &t_func) const - { - const Proxy_Function_Impl *pimpl = dynamic_cast *>(&t_func); - return pimpl != 0; - } - - - virtual int get_arity() const - { - return static_cast(m_types.size()) - 1; - } - - - virtual bool call_match(const std::vector &vals) const - { - if (int(vals.size()) != get_arity()) + virtual bool operator==(const Proxy_Function_Base &t_func) const { - return false; + const Proxy_Function_Impl *pimpl = dynamic_cast *>(&t_func); + return pimpl != 0; } - return compare_types(m_types, vals) || detail::compare_types_cast(m_dummy_func, vals); - } - virtual std::string annotation() const - { - return ""; - } + virtual int get_arity() const + { + return static_cast(m_types.size()) - 1; + } - boost::function internal_function() const - { - return m_f; - } - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - return detail::Do_Call::result_type>::go(m_f, params); - } + virtual bool call_match(const std::vector &vals) const + { + if (int(vals.size()) != get_arity()) + { + return false; + } - private: - boost::function m_f; - Func *m_dummy_func; - }; + return compare_types(m_types, vals) || detail::compare_types_cast(m_dummy_func, vals); + } - /** - * Attribute getter Proxy_Function implementation - */ - template - class Attribute_Access : public Proxy_Function_Base - { - public: - Attribute_Access(T Class::* t_attr) - : Proxy_Function_Base(param_types()), + virtual std::string annotation() const + { + return ""; + } + + boost::function internal_function() const + { + return m_f; + } + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + return detail::Do_Call::result_type>::go(m_f, params); + } + + private: + boost::function m_f; + Func *m_dummy_func; + }; + + /** + * Attribute getter Proxy_Function implementation + */ + template + class Attribute_Access : public Proxy_Function_Base + { + public: + Attribute_Access(T Class::* t_attr) + : Proxy_Function_Base(param_types()), m_attr(t_attr) { } - virtual ~Attribute_Access() {} + virtual ~Attribute_Access() {} - virtual bool operator==(const Proxy_Function_Base &t_func) const - { - const Attribute_Access * aa - = dynamic_cast *>(&t_func); - if (aa) { - return m_attr == aa->m_attr; - } else { - return false; - } - } - - - virtual int get_arity() const - { - return 1; - } - - virtual bool call_match(const std::vector &vals) const - { - if (vals.size() != 1) + virtual bool operator==(const Proxy_Function_Base &t_func) const { - return false; - } - - return vals[0].get_type_info().bare_equal(user_type()); - } - - virtual std::string annotation() const - { - return ""; - } - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - if (params.size() == 1) - { - const Boxed_Value &bv = params[0]; - if (bv.is_const()) - { - const Class *o = boxed_cast(bv); - return detail::Handle_Return::type>::handle(o->*m_attr); + const Attribute_Access * aa + = dynamic_cast *>(&t_func); + if (aa) { + return m_attr == aa->m_attr; } else { - Class *o = boxed_cast(bv); - return detail::Handle_Return::type>::handle(o->*m_attr); + return false; } - } else { - throw exception::arity_error(static_cast(params.size()), 1); - } - } + } - private: - static std::vector param_types() - { - std::vector v; - v.push_back(user_type()); - v.push_back(user_type()); - return v; - } - T Class::* m_attr; - }; + + virtual int get_arity() const + { + return 1; + } + + virtual bool call_match(const std::vector &vals) const + { + if (vals.size() != 1) + { + return false; + } + + return vals[0].get_type_info().bare_equal(user_type()); + } + + virtual std::string annotation() const + { + return ""; + } + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + if (params.size() == 1) + { + const Boxed_Value &bv = params[0]; + if (bv.is_const()) + { + const Class *o = boxed_cast(bv); + return detail::Handle_Return::type>::handle(o->*m_attr); + } else { + Class *o = boxed_cast(bv); + return detail::Handle_Return::type>::handle(o->*m_attr); + } + } else { + throw exception::arity_error(static_cast(params.size()), 1); + } + } + + private: + static std::vector param_types() + { + std::vector v; + v.push_back(user_type()); + v.push_back(user_type()); + return v; + } + T Class::* m_attr; + }; + } namespace exception { @@ -587,15 +593,16 @@ namespace chaiscript dispatch_error(bool is_const) throw() : std::runtime_error(std::string("No matching function to dispatch to") + (is_const?", parameter is const":"")) - { - } + { + } virtual ~dispatch_error() throw() {} }; - } + } - namespace detail + namespace dispatch { + /** * Take a vector of functions and a vector of parameters. Attempt to execute * each function against the set of parameters, in order, until a matching @@ -635,7 +642,7 @@ namespace chaiscript Boxed_Value dispatch(const Funcs &funcs, const std::vector &plist) { - return dispatch(funcs.begin(), funcs.end(), plist); + return dispatch::dispatch(funcs.begin(), funcs.end(), plist); } } } diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index fbd4fc2..8db8113 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -18,61 +18,63 @@ namespace chaiscript { - namespace detail + namespace dispatch { - template - struct Fun_Helper - { - template - static Proxy_Function go(T t) + namespace detail + { + template + struct Fun_Helper { - return Proxy_Function( - new Proxy_Function_Impl< + template + static Proxy_Function go(T t) + { + return Proxy_Function( + new Proxy_Function_Impl< typename boost::function_types::function_type >::type> ( boost::function< - typename boost::function_types::function_type >::type - >(t))); - } - }; + typename boost::function_types::function_type >::type + >(t))); + } + }; - template<> - struct Fun_Helper - { - template - static Proxy_Function go(T t) + template<> + struct Fun_Helper { - return Proxy_Function( - new Proxy_Function_Impl< + template + static Proxy_Function go(T t) + { + return Proxy_Function( + new Proxy_Function_Impl< typename boost::function_types::function_type >::type> ( boost::function< - typename boost::function_types::function_type >::type + typename boost::function_types::function_type >::type >(boost::mem_fn(t)))); - } - }; + } + }; - template<> - struct Fun_Helper - { - template - static Proxy_Function go(T Class::* m) - { - return Proxy_Function(new Attribute_Access(m)); - } - }; - + template<> + struct Fun_Helper + { + template + static Proxy_Function go(T Class::* m) + { + return Proxy_Function(new Attribute_Access(m)); + } + }; + } } template Proxy_Function fun(const boost::function &f) { - return Proxy_Function(new Proxy_Function_Impl(f)); + return Proxy_Function(new dispatch::Proxy_Function_Impl(f)); } template Proxy_Function fun(T t) { - return detail::Fun_Helper::value, boost::function_types::is_member_function_pointer::value>::go(t); + return dispatch::detail::Fun_Helper::value, boost::function_types::is_member_function_pointer::value>::go(t); } template diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index f2730e3..7196ef1 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -99,7 +99,7 @@ namespace chaiscript return to_string(); } - virtual Boxed_Value eval(Dispatch_Engine &) { + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &) { Boxed_Value bv; throw std::runtime_error("Undispatched ast_node (internal error)"); } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index af7ca14..b495048 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -235,7 +235,7 @@ namespace chaiscript std::vector m_modulepaths; std::vector m_usepaths; - Dispatch_Engine m_engine; + chaiscript::detail::Dispatch_Engine m_engine; /** @@ -307,7 +307,7 @@ namespace chaiscript /** * Returns the current evaluation m_engine */ - Dispatch_Engine &get_eval_engine() { + chaiscript::detail::Dispatch_Engine &get_eval_engine() { return m_engine; } @@ -335,13 +335,13 @@ namespace chaiscript add(Bootstrap::bootstrap()); - m_engine.add(fun(&Dispatch_Engine::dump_system, boost::ref(m_engine)), "dump_system"); - m_engine.add(fun(&Dispatch_Engine::dump_object, boost::ref(m_engine)), "dump_object"); - m_engine.add(fun(&Dispatch_Engine::is_type, boost::ref(m_engine)), "is_type"); - m_engine.add(fun(&Dispatch_Engine::type_name, boost::ref(m_engine)), "type_name"); - m_engine.add(fun(&Dispatch_Engine::function_exists, boost::ref(m_engine)), "function_exists"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, boost::ref(m_engine)), "dump_system"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, boost::ref(m_engine)), "dump_object"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, boost::ref(m_engine)), "is_type"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, boost::ref(m_engine)), "type_name"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, boost::ref(m_engine)), "function_exists"); - m_engine.add(fun(&Dispatch_Engine::get_type_name, boost::ref(m_engine)), "name"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, boost::ref(m_engine)), "name"); typedef void (ChaiScript::*load_mod_1)(const std::string&); @@ -392,7 +392,7 @@ namespace chaiscript struct State { std::set used_files; - Dispatch_Engine::State engine_state; + chaiscript::detail::Dispatch_Engine::State engine_state; std::set active_loaded_modules; }; @@ -532,7 +532,7 @@ namespace chaiscript template boost::function functor(const std::string &t_script) { - return chaiscript::functor(eval(t_script)); + return chaiscript::dispatch::functor(eval(t_script)); } /** diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 2718c23..23fa43b 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -49,7 +49,7 @@ namespace chaiscript Binary_Operator_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Binary_Operator_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; try { @@ -91,7 +91,7 @@ namespace chaiscript Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Int_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){ return const_var(int(atoi(this->text.c_str()))); } @@ -102,7 +102,7 @@ namespace chaiscript Float_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Float, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Float_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){ return const_var(double(atof(this->text.c_str()))); } @@ -113,7 +113,7 @@ namespace chaiscript Id_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Id, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Id_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ if (this->text == "true") { return const_var(true); } @@ -163,8 +163,8 @@ namespace chaiscript Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Fun_Call, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Fun_Call_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ - Param_List_Builder plb; + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ + dispatch::Param_List_Builder plb; if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { for (size_t i = 0; i < this->children[1]->children.size(); ++i) { @@ -178,8 +178,8 @@ namespace chaiscript } } - Dispatch_Engine::Stack prev_stack = t_ss.get_stack(); - Dispatch_Engine::Stack new_stack = t_ss.new_stack(); + chaiscript::detail::Dispatch_Engine::Stack prev_stack = t_ss.get_stack(); + chaiscript::detail::Dispatch_Engine::Stack new_stack = t_ss.new_stack(); try { Boxed_Value fn = this->children[0]->eval(t_ss); @@ -218,8 +218,8 @@ namespace chaiscript Inplace_Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inplace_Fun_Call, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inplace_Fun_Call_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ - Param_List_Builder plb; + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ + dispatch::Param_List_Builder plb; if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { for (size_t i = 0; i < this->children[1]->children.size(); ++i) { @@ -277,7 +277,7 @@ namespace chaiscript Equation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equation, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Equation_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; try { retval = this->children.back()->eval(t_ss); @@ -353,7 +353,7 @@ namespace chaiscript Var_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Var_Decl, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Var_Decl_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ try { t_ss.add_object(this->children[0]->text, Boxed_Value()); } @@ -391,7 +391,7 @@ namespace chaiscript Array_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Array_Call, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Array_Call_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; try { @@ -427,7 +427,7 @@ namespace chaiscript Dot_Access_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Dot_Access, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Dot_Access_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; try { retval = this->children[0]->eval(t_ss); @@ -439,7 +439,7 @@ namespace chaiscript if (this->children.size() > 1) { for (size_t i = 2; i < this->children.size(); i+=2) { - Param_List_Builder plb; + dispatch::Param_List_Builder plb; plb << retval; if (this->children[i]->children.size() > 1) { @@ -462,8 +462,8 @@ namespace chaiscript fun_name = this->children[i]->text; } - Dispatch_Engine::Stack prev_stack = t_ss.get_stack(); - Dispatch_Engine::Stack new_stack = t_ss.new_stack(); + chaiscript::detail::Dispatch_Engine::Stack prev_stack = t_ss.get_stack(); + chaiscript::detail::Dispatch_Engine::Stack new_stack = t_ss.new_stack(); try { t_ss.set_stack(new_stack); @@ -512,7 +512,7 @@ namespace chaiscript Quoted_String_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Quoted_String, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Quoted_String_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){ return const_var(this->text); } @@ -523,7 +523,7 @@ namespace chaiscript Single_Quoted_String_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Single_Quoted_String, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Single_Quoted_String_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){ return const_var(char(this->text[0])); } @@ -534,7 +534,7 @@ namespace chaiscript Lambda_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Lambda, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Lambda_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ std::vector t_param_names; size_t numparams = 0; @@ -550,8 +550,8 @@ namespace chaiscript numparams = 0; } - return Boxed_Value(Proxy_Function(new Dynamic_Proxy_Function - (boost::bind(&eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), + return Boxed_Value(Proxy_Function(new dispatch::Dynamic_Proxy_Function + (boost::bind(&eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), static_cast(numparams), this->children.back()))); } @@ -562,7 +562,7 @@ namespace chaiscript Block_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Block, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Block_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ size_t num_children = this->children.size(); t_ss.new_scope(); @@ -602,7 +602,7 @@ namespace chaiscript Def_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Def, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Def_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ std::vector t_param_names; size_t numparams = 0; AST_NodePtr guardnode; @@ -626,10 +626,10 @@ namespace chaiscript } } - boost::shared_ptr guard; + boost::shared_ptr guard; if (guardnode) { - guard = boost::shared_ptr - (new Dynamic_Proxy_Function(boost::bind(&eval_function, + guard = boost::shared_ptr + (new dispatch::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(t_ss), guardnode, t_param_names, _1), static_cast(numparams), guardnode)); } @@ -638,7 +638,7 @@ namespace chaiscript const std::string & l_function_name = this->children[0]->text; const std::string & l_annotation = this->annotation?this->annotation->text:""; t_ss.add(Proxy_Function - (new Dynamic_Proxy_Function(boost::bind(&eval_function, + (new dispatch::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), static_cast(numparams), this->children.back(), l_annotation, guard)), l_function_name); @@ -656,7 +656,7 @@ namespace chaiscript While_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::While, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~While_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ bool cond; t_ss.new_scope(); @@ -711,7 +711,7 @@ namespace chaiscript If_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::If, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~If_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ bool cond; try { cond = boxed_cast(this->children[0]->eval(t_ss)); @@ -782,7 +782,7 @@ namespace chaiscript For_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::For, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~For_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ bool cond; t_ss.new_scope(); @@ -893,7 +893,7 @@ namespace chaiscript Inline_Array_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Array, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inline_Array_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ std::vector vec; if (this->children.size() > 0) { for (size_t i = 0; i < this->children[0]->children.size(); ++i) { @@ -917,7 +917,7 @@ namespace chaiscript Inline_Map_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Map, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inline_Map_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ try { std::map retval; for (size_t i = 0; i < this->children[0]->children.size(); ++i) { @@ -944,7 +944,7 @@ namespace chaiscript Return_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Return, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Return_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ if (this->children.size() > 0) { try { throw detail::Return_Value(this->children[0]->eval(t_ss)); @@ -966,7 +966,7 @@ namespace chaiscript File_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::File, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~File_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss) { + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss) { const size_t size = this->children.size(); for (size_t i = 0; i < size; ++i) { try { @@ -989,7 +989,7 @@ namespace chaiscript Prefix_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Prefix_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ try { return t_ss.call_function(this->children[0]->text, this->children[1]->eval(t_ss)); } @@ -1005,7 +1005,7 @@ namespace chaiscript Break_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Break, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Break_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){ throw detail::Break_Loop(); } }; @@ -1029,7 +1029,7 @@ namespace chaiscript Inline_Range_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Range, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inline_Range_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ try { return t_ss.call_function("generate_range", this->children[0]->children[0]->children[0]->eval(t_ss), @@ -1058,7 +1058,7 @@ namespace chaiscript Try_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Try, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Try_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; t_ss.new_scope(); @@ -1300,7 +1300,7 @@ namespace chaiscript Method_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Method, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Method_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ std::vector t_param_names; AST_NodePtr guardnode; @@ -1327,10 +1327,10 @@ namespace chaiscript size_t numparams = t_param_names.size(); - boost::shared_ptr guard; + boost::shared_ptr guard; if (guardnode) { - guard = boost::shared_ptr - (new Dynamic_Proxy_Function(boost::bind(&eval_function, + guard = boost::shared_ptr + (new dispatch::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(t_ss), guardnode, t_param_names, _1), static_cast(numparams), guardnode)); } @@ -1341,8 +1341,8 @@ namespace chaiscript const std::string & function_name = this->children[1]->text; if (function_name == class_name) { t_ss.add(Proxy_Function - (new detail::Dynamic_Object_Constructor(class_name, Proxy_Function - (new Dynamic_Proxy_Function(boost::bind(&eval_function, + (new dispatch::detail::Dynamic_Object_Constructor(class_name, Proxy_Function + (new dispatch::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), static_cast(numparams), this->children.back(), l_annotation, guard)))), function_name); @@ -1356,8 +1356,8 @@ namespace chaiscript // No biggie, the type name is just not known } t_ss.add(Proxy_Function - (new detail::Dynamic_Object_Function(class_name, Proxy_Function - (new Dynamic_Proxy_Function(boost::bind(&eval_function, + (new dispatch::detail::Dynamic_Object_Function(class_name, Proxy_Function + (new dispatch::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), static_cast(numparams), this->children.back(), l_annotation, guard)), ti)), function_name); @@ -1377,9 +1377,9 @@ namespace chaiscript Attr_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Attr_Decl, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Attr_Decl_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ try { - t_ss.add(fun(boost::function(boost::bind(&detail::Dynamic_Object_Attribute::func, this->children[0]->text, + t_ss.add(fun(boost::function(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, this->children[0]->text, this->children[1]->text, _1))), this->children[1]->text); } @@ -1431,7 +1431,7 @@ namespace chaiscript Logical_And_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_And, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Logical_And_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; try { retval = this->children[0]->eval(t_ss); @@ -1473,7 +1473,7 @@ namespace chaiscript Logical_Or_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_Or, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Logical_Or_AST_Node() {} - virtual Boxed_Value eval(Dispatch_Engine &t_ss){ + virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; try { diff --git a/samples/example.cpp b/samples/example.cpp index e802982..68aa6c6 100644 --- a/samples/example.cpp +++ b/samples/example.cpp @@ -45,7 +45,7 @@ struct System void add_callback(const std::string &t_name, const chaiscript::Proxy_Function &t_func) { - m_callbacks[t_name] = chaiscript::functor(t_func); + m_callbacks[t_name] = chaiscript::dispatch::functor(t_func); } @@ -163,9 +163,9 @@ int main(int /*argc*/, char * /*argv*/[]) { chai.add(fun(&bound_log, std::string("Msg")), "BoundFun"); //Dynamic objects test - chai.add(chaiscript::Proxy_Function(new detail::Dynamic_Object_Function("TestType", fun(&hello_world))), "hello_world"); - chai.add(chaiscript::Proxy_Function(new detail::Dynamic_Object_Constructor("TestType", fun(&hello_constructor))), "TestType"); - chai.add(fun(boost::function(boost::bind(&detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr"); + chai.add(chaiscript::Proxy_Function(new dispatch::detail::Dynamic_Object_Function("TestType", fun(&hello_world))), "hello_world"); + chai.add(chaiscript::Proxy_Function(new dispatch::detail::Dynamic_Object_Constructor("TestType", fun(&hello_constructor))), "TestType"); + chai.add(fun(boost::function(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr"); chai.eval("var x = TestType()"); // chai.eval("x.attr = \"hi\""); diff --git a/src/main.cpp b/src/main.cpp index 53ea64e..dff7cd9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,7 +55,7 @@ void version(int){ bool throws_exception(const chaiscript::Proxy_Function &f) { try { - chaiscript::functor(f)(); + chaiscript::dispatch::functor(f)(); } catch (...) { return true; } diff --git a/src/reflection.cpp b/src/reflection.cpp index f858863..aca21d9 100644 --- a/src/reflection.cpp +++ b/src/reflection.cpp @@ -14,7 +14,8 @@ bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) { - boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); + boost::shared_ptr pf + = boost::dynamic_pointer_cast(t_pf); if (pf) { return pf->get_parse_tree(); @@ -25,7 +26,8 @@ bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) chaiscript::AST_NodePtr get_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) { - boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); + boost::shared_ptr pf + = boost::dynamic_pointer_cast(t_pf); if (pf) { if (pf->get_parse_tree()) diff --git a/unittests/dynamic_object_test.cpp b/unittests/dynamic_object_test.cpp index 251716f..8383e03 100644 --- a/unittests/dynamic_object_test.cpp +++ b/unittests/dynamic_object_test.cpp @@ -19,7 +19,7 @@ int main() chai("attr bob::z; def bob::bob() { this.z = 10 }; var x = bob()"); - chaiscript::Dynamic_Object &mydo = chai.eval("x"); + chaiscript::dispatch::Dynamic_Object &mydo = chai.eval("x"); assert_equal(mydo.get_type_name(), "bob");