Add more specific exception types to the dynamic system and handle them properly
This commit is contained in:
parent
d8b5847ff6
commit
eb5dbe4975
@ -110,7 +110,7 @@ namespace chaiscript
|
||||
try {
|
||||
retval = dispatch(ss.get_function(node->children[i+1]->text), plb);
|
||||
}
|
||||
catch(std::exception &e){
|
||||
catch(const dispatchkit::dispatch_error &e){
|
||||
throw EvalError("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]);
|
||||
}
|
||||
}
|
||||
@ -136,7 +136,7 @@ namespace chaiscript
|
||||
try {
|
||||
retval = dispatch(ss.get_function(node->children[i]->text), plb);
|
||||
}
|
||||
catch(std::exception &e){
|
||||
catch(const dispatchkit::dispatch_error &e){
|
||||
throw EvalError("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]);
|
||||
}
|
||||
}
|
||||
@ -155,7 +155,7 @@ namespace chaiscript
|
||||
catch(std::out_of_range &oor) {
|
||||
throw EvalError("Out of bounds exception", node);
|
||||
}
|
||||
catch(std::exception &e){
|
||||
catch(const dispatchkit::dispatch_error &e){
|
||||
throw EvalError("Can not find appropriate array lookup '[]'", node->children[i]);
|
||||
}
|
||||
}
|
||||
@ -208,12 +208,12 @@ namespace chaiscript
|
||||
dispatchkit::Boxed_Value tmp = eval_token(ss, node->children[i]);
|
||||
dispatch(ss.get_function("push_back"), dispatchkit::Param_List_Builder() << retval << tmp);
|
||||
}
|
||||
catch (std::exception inner_e) {
|
||||
catch (const dispatchkit::dispatch_error &inner_e) {
|
||||
throw EvalError("Can not find appropriate 'push_back'", node->children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception e) {
|
||||
catch (const dispatchkit::dispatch_error &e) {
|
||||
throw EvalError("Can not find appropriate 'Vector()'", node);
|
||||
}
|
||||
}
|
||||
@ -227,12 +227,12 @@ namespace chaiscript
|
||||
dispatchkit::Boxed_Value slot = dispatch(ss.get_function("[]"), dispatchkit::Param_List_Builder() << retval << key);
|
||||
dispatch(ss.get_function("="), dispatchkit::Param_List_Builder() << slot << eval_token(ss, node->children[i]->children[1]));
|
||||
}
|
||||
catch (std::exception inner_e) {
|
||||
catch (const dispatchkit::dispatch_error &inner_e) {
|
||||
throw EvalError("Can not find appropriate '=' for map init", node->children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception e) {
|
||||
catch (const dispatchkit::dispatch_error &e) {
|
||||
throw EvalError("Can not find appropriate 'Vector()'", node);
|
||||
}
|
||||
}
|
||||
@ -259,7 +259,7 @@ namespace chaiscript
|
||||
ss.set_stack(prev_stack);
|
||||
throw EvalError(ee.reason, node->children[0]);
|
||||
}
|
||||
catch(std::exception &e){
|
||||
catch(const dispatchkit::dispatch_error &e){
|
||||
ss.set_stack(prev_stack);
|
||||
throw EvalError("Engine error: " + std::string(e.what()) + " on '" + node->children[0]->text + "'", node->children[0]);
|
||||
}
|
||||
@ -304,7 +304,7 @@ namespace chaiscript
|
||||
ss.set_stack(prev_stack);
|
||||
throw EvalError(ee.reason, node);
|
||||
}
|
||||
catch(std::exception &e){
|
||||
catch(const dispatchkit::dispatch_error &e){
|
||||
ss.set_stack(prev_stack);
|
||||
throw EvalError("Can not find appropriate '" + fun_name + "'", node);
|
||||
}
|
||||
|
@ -351,27 +351,6 @@ namespace dispatchkit
|
||||
|
||||
}
|
||||
|
||||
class bad_boxed_value_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
bad_boxed_value_cast(const std::string &val) throw()
|
||||
: m_val(val)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~bad_boxed_value_cast() throw()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char * what() const throw()
|
||||
{
|
||||
return m_val.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_val;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//Built in to_string operator
|
||||
@ -420,7 +399,7 @@ namespace dispatchkit
|
||||
{
|
||||
return (lhs.assign(rhs));
|
||||
} else {
|
||||
throw bad_boxed_value_cast("boxed_value has a set type alread");
|
||||
throw bad_boxed_cast("boxed_value has a set type already");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,10 +356,40 @@ namespace dispatchkit
|
||||
}
|
||||
};
|
||||
|
||||
class bad_boxed_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) throw()
|
||||
: from(t_from.m_type_info), to(&t_to), m_what("Cannot perform boxed_cast")
|
||||
{
|
||||
}
|
||||
|
||||
bad_boxed_cast(const std::string &w) throw()
|
||||
: m_what(w)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~bad_boxed_cast() throw() {}
|
||||
|
||||
virtual const char * what () throw()
|
||||
{
|
||||
return m_what.c_str();
|
||||
}
|
||||
const std::type_info *from;
|
||||
const std::type_info *to;
|
||||
|
||||
private:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
typename Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv)
|
||||
{
|
||||
return Cast_Helper<Type>::cast(bv);
|
||||
try {
|
||||
return Cast_Helper<Type>::cast(bv);
|
||||
} catch (const boost::bad_any_cast &) {
|
||||
throw bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||
}
|
||||
}
|
||||
|
||||
struct Boxed_POD_Value
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <string>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
@ -88,6 +90,20 @@ namespace dispatchkit
|
||||
|
||||
std::vector<Boxed_Value> objects;
|
||||
};
|
||||
|
||||
struct arity_error : std::range_error
|
||||
{
|
||||
arity_error(int t_got, int t_expected)
|
||||
: std::range_error("Function dispatch arity mismatch"),
|
||||
got(t_got), expected(t_expected)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~arity_error() throw() {}
|
||||
int got;
|
||||
int expected;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
||||
@ -96,6 +112,8 @@ namespace dispatchkit
|
||||
|
||||
namespace dispatchkit
|
||||
{
|
||||
|
||||
|
||||
class Proxy_Function
|
||||
{
|
||||
public:
|
||||
@ -126,7 +144,7 @@ namespace dispatchkit
|
||||
{
|
||||
return m_f(params);
|
||||
} else {
|
||||
throw std::range_error("Incorrect number of parameters");
|
||||
throw arity_error(params.size(), m_arity);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,6 +193,16 @@ namespace dispatchkit
|
||||
Func m_f;
|
||||
};
|
||||
|
||||
struct dispatch_error : std::runtime_error
|
||||
{
|
||||
dispatch_error() throw()
|
||||
: std::runtime_error("No matching function to dispatch to")
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~dispatch_error() throw() {}
|
||||
};
|
||||
|
||||
Boxed_Value dispatch(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs,
|
||||
const std::vector<Boxed_Value> &plist)
|
||||
{
|
||||
@ -184,14 +212,14 @@ namespace dispatchkit
|
||||
{
|
||||
try {
|
||||
return (*itr->second)(plist);
|
||||
} catch (const std::bad_cast &) {
|
||||
} catch (const bad_boxed_cast &) {
|
||||
//try again
|
||||
} catch (const std::range_error &) {
|
||||
} catch (const arity_error &) {
|
||||
//invalid num params, try again
|
||||
}
|
||||
}
|
||||
|
||||
throw std::runtime_error("No matching function to dispatch to");
|
||||
throw dispatch_error();
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +238,7 @@ namespace dispatchkit
|
||||
|
||||
BOOST_PP_REPEAT(n, gettypeinfo, ~)
|
||||
|
||||
return ti;
|
||||
return ti;
|
||||
}
|
||||
|
||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||
@ -219,7 +247,7 @@ namespace dispatchkit
|
||||
{
|
||||
if (params.size() != n)
|
||||
{
|
||||
throw std::range_error("Incorrect number of parameters");
|
||||
throw arity_error(params.size(), n);
|
||||
} else {
|
||||
return Handle_Return<Ret>()(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~)));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user