diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 274822d..86a4969 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -533,22 +533,39 @@ namespace chaiscript * function variables. */ template - boost::shared_ptr shared_ptr_clone(boost::shared_ptr f) + boost::shared_ptr shared_ptr_clone(const boost::shared_ptr &p) { - return f; + return p; } + /** + * Specific version of shared_ptr_clone just for Proxy_Functions + * probably not necessary, probably could just use the version above, + * but here we are. + */ + Proxy_Function proxy_function_clone(const Const_Proxy_Function &f) + { + return boost::const_pointer_cast(f); + } + + + /** * Assignment function for shared_ptr objects, does not perform a copy of the * object pointed to, instead maintains the shared_ptr concept. * Similar to shared_ptr_clone. Used for Proxy_Function. */ template - Boxed_Value ptr_assign(Boxed_Value lhs, boost::shared_ptr rhs) + Boxed_Value ptr_assign(Boxed_Value lhs, const boost::shared_ptr::type> &rhs) { - lhs.assign(Boxed_Value(rhs)); - - return lhs; + if (lhs.is_unknown() + || (!lhs.get_type_info().is_const() && lhs.get_type_info().bare_equal(chaiscript::detail::Get_Type_Info::get()))) + { + lhs.assign(Boxed_Value(rhs)); + return lhs; + } else { + throw bad_boxed_cast("type mismatch in pointer assignment"); + } } /** @@ -617,9 +634,9 @@ namespace chaiscript throw arity_error(params.size(), 2); } - Proxy_Function f = boxed_cast(params[0]); + Const_Proxy_Function f = boxed_cast(params[0]); - return Boxed_Value(Proxy_Function(new Bound_Function(f, + return Boxed_Value(Const_Proxy_Function(new Bound_Function(f, std::vector(params.begin() + 1, params.end())))); } @@ -634,7 +651,7 @@ namespace chaiscript throw arity_error(params.size(), 1); } - Proxy_Function f = boxed_cast(params[0]); + Const_Proxy_Function f = boxed_cast(params[0]); return Boxed_Value(f->call_match(std::vector(params.begin() + 1, params.end()))); } @@ -703,7 +720,7 @@ namespace chaiscript m->add(Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&bind_function, _1))), "bind"); - m->add(fun(&shared_ptr_clone), "clone"); + m->add(fun(&proxy_function_clone), "clone"); m->add(fun(&ptr_assign), "="); m->add(Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&call_exists, _1))), diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index e472063..363762d 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -135,6 +135,8 @@ namespace chaiscript template boost::shared_ptr get(const boost::shared_ptr &obj) { + bool b_const = boost::is_const::value; + boost::shared_ptr data(new Data( detail::Get_Type_Info::get(), boost::any(obj), @@ -142,14 +144,14 @@ namespace chaiscript boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) ); - std::map::iterator itr - = m_ptrs.find(obj.get()); + std::map, Data>::iterator itr + = m_ptrs.find(std::make_pair(obj.get(), b_const)); if (itr != m_ptrs.end()) { (*data) = (itr->second); } else { - m_ptrs.insert(std::make_pair(obj.get(), *data)); + m_ptrs.insert(std::make_pair(std::make_pair(obj.get(), b_const), *data)); } return data; @@ -164,14 +166,16 @@ namespace chaiscript template boost::shared_ptr get(boost::reference_wrapper obj) { + bool b_const = boost::is_const::value; + boost::shared_ptr data(new Data( detail::Get_Type_Info::get(), boost::any(obj), true) ); - std::map::iterator itr - = m_ptrs.find(obj.get_pointer()); + std::map, Data >::iterator itr + = m_ptrs.find(std::make_pair(obj.get_pointer(), b_const) ); // If the ptr is found in the cache and it is the correct type, // return it. It may be the incorrect type when two variables share the @@ -201,7 +205,7 @@ namespace chaiscript boost::shared_ptr *ptr = boost::any_cast >(&data->m_obj); - m_ptrs.insert(std::make_pair(ptr->get(), *data)); + m_ptrs.insert(std::make_pair(std::make_pair(ptr->get(), false), *data)); return data; } @@ -228,13 +232,13 @@ namespace chaiscript } - std::map::iterator itr = m_ptrs.begin(); + std::map, Data>::iterator itr = m_ptrs.begin(); while (itr != m_ptrs.end()) { if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1) { - std::map::iterator todel = itr; + std::map, Data >::iterator todel = itr; ++itr; m_ptrs.erase(todel); } else { @@ -243,7 +247,7 @@ namespace chaiscript } } - std::map m_ptrs; + std::map, Data > m_ptrs; int m_cullcount; }; diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 140a2dc..a5e9b01 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -87,7 +87,7 @@ namespace chaiscript virtual ~Dispatch_Function() {} - virtual Boxed_Value operator()(const std::vector ¶ms) + virtual Boxed_Value operator()(const std::vector ¶ms) const { return dispatch(m_funcs.begin(), m_funcs.end(), params); } @@ -360,7 +360,7 @@ namespace chaiscript { throw std::range_error("Object not known: " + name); } else { - Boxed_Value f(Proxy_Function(new Dispatch_Function(funcs))); + Boxed_Value f(Const_Proxy_Function(new Dispatch_Function(funcs))); cache[name] = f; return f; } diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index f0a9a72..b94e930 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -99,7 +99,7 @@ namespace chaiscript } } - virtual Boxed_Value operator()(const std::vector ¶ms) + virtual Boxed_Value operator()(const std::vector ¶ms) const { if (dynamic_object_typename_match(params, m_type_name)) { @@ -180,7 +180,7 @@ namespace chaiscript return m_func->call_match(new_vals); } - virtual Boxed_Value operator()(const std::vector ¶ms) + virtual Boxed_Value operator()(const std::vector ¶ms) const { std::vector new_params; chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name)); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 38d789a..521f851 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -62,7 +62,7 @@ namespace chaiscript { public: virtual ~Proxy_Function_Base() {} - virtual Boxed_Value operator()(const std::vector ¶ms) = 0; + virtual Boxed_Value operator()(const std::vector ¶ms) const = 0; std::vector get_param_types() const { return m_types; } @@ -139,6 +139,7 @@ namespace chaiscript }; typedef boost::shared_ptr Proxy_Function; + typedef boost::shared_ptr Const_Proxy_Function; /** * Exception thrown if a function's guard fails to execute @@ -184,7 +185,7 @@ namespace chaiscript virtual ~Dynamic_Proxy_Function() {} - virtual Boxed_Value operator()(const std::vector ¶ms) + virtual Boxed_Value operator()(const std::vector ¶ms) const { if (m_arity < 0 || params.size() == size_t(m_arity)) { @@ -270,7 +271,7 @@ namespace chaiscript class Bound_Function : public Proxy_Function_Base { public: - Bound_Function(const Proxy_Function &t_f, + Bound_Function(const Const_Proxy_Function &t_f, const std::vector &t_args) : Proxy_Function_Base(std::vector()), m_f(t_f), m_args(t_args), m_arity(m_f->get_arity()<0?-1:(m_f->get_arity() - m_args.size())) @@ -289,7 +290,7 @@ namespace chaiscript return m_f->call_match(build_param_list(vals)); } - virtual Boxed_Value operator()(const std::vector ¶ms) + virtual Boxed_Value operator()(const std::vector ¶ms) const { return (*m_f)(build_param_list(params)); } @@ -343,7 +344,7 @@ namespace chaiscript } private: - Proxy_Function m_f; + Const_Proxy_Function m_f; std::vector m_args; int m_arity; }; @@ -375,7 +376,7 @@ namespace chaiscript } } - virtual Boxed_Value operator()(const std::vector ¶ms) + virtual Boxed_Value operator()(const std::vector ¶ms) const { return Do_Call::result_type>::go(m_f, params); } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 0f1af38..2a4b445 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -470,7 +470,7 @@ namespace chaiscript try { ss.set_stack(new_stack); - Boxed_Value retval = (*boxed_cast(fn))(plb); + Boxed_Value retval = (*boxed_cast(fn))(plb); ss.set_stack(prev_stack); return retval; } @@ -512,7 +512,7 @@ namespace chaiscript Boxed_Value fn = eval_token(ss, node->children[0]); try { - Boxed_Value retval = (*boxed_cast(fn))(plb); + Boxed_Value retval = (*boxed_cast(fn))(plb); return retval; } catch(const dispatch_error &e){ @@ -575,7 +575,7 @@ namespace chaiscript //fn = ss.get_function(fun_name); ss.set_stack(new_stack); //retval = dispatch(fn, plb); - retval = (*boxed_cast(fn))(plb); + retval = (*boxed_cast(fn))(plb); ss.set_stack(prev_stack); } catch(const dispatch_error &e){ diff --git a/unittests/function_reassignment.chai b/unittests/function_reassignment.chai new file mode 100644 index 0000000..5373a96 --- /dev/null +++ b/unittests/function_reassignment.chai @@ -0,0 +1,3 @@ +var x = `+` +x = `-` +print(x(5,4)) diff --git a/unittests/function_reassignment.txt b/unittests/function_reassignment.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/unittests/function_reassignment.txt @@ -0,0 +1 @@ +1 diff --git a/unittests/invalid_function_assignment.chai b/unittests/invalid_function_assignment.chai new file mode 100644 index 0000000..2468248 --- /dev/null +++ b/unittests/invalid_function_assignment.chai @@ -0,0 +1 @@ +clone = `-` diff --git a/unittests/invalid_function_assignment.txt b/unittests/invalid_function_assignment.txt new file mode 100644 index 0000000..2970e6e --- /dev/null +++ b/unittests/invalid_function_assignment.txt @@ -0,0 +1 @@ +Error: "Mismatched types in equation" in 'unittests/invalid_function_assignment.chai' at (1, 7) diff --git a/unittests/invalid_function_reassignment.chai b/unittests/invalid_function_reassignment.chai new file mode 100644 index 0000000..69a5789 --- /dev/null +++ b/unittests/invalid_function_reassignment.chai @@ -0,0 +1,2 @@ +var x = 5 +x = `-` diff --git a/unittests/invalid_function_reassignment.txt b/unittests/invalid_function_reassignment.txt new file mode 100644 index 0000000..b1ad728 --- /dev/null +++ b/unittests/invalid_function_reassignment.txt @@ -0,0 +1 @@ +Error: "Mismatched types in equation" in 'unittests/invalid_function_reassignment.chai' at (2, 3)