Add more specific exception types to the dynamic system and handle them properly

This commit is contained in:
Jason Turner 2009-06-25 00:03:23 +00:00
parent d8b5847ff6
commit eb5dbe4975
4 changed files with 75 additions and 38 deletions

View File

@ -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);
}

View File

@ -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");
}
}

View File

@ -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

View File

@ -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, ~)));
}