Reduce exceptions on startup to minimum
This still has some exceptions thrown during the loading of modules since I have no way of knowing where the operating system `dlopen` and `LoadLibrary` functions will search for me to pre-check it. Closes #158
This commit is contained in:
parent
f953f9b297
commit
962bdf4b3c
@ -136,10 +136,14 @@ namespace chaiscript
|
||||
ModulePtr bootstrap_pod_type(const std::string &name, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(user_type<T>(), name);
|
||||
m->add(constructor<T ()>(), name);
|
||||
m->add(constructor<T()>(), name);
|
||||
construct_pod<T>(name, m);
|
||||
|
||||
m->add(fun(&to_string<T>), "to_string");
|
||||
auto to_s = fun(&to_string<T>);
|
||||
|
||||
if (!m->has_function(to_s, "to_string")) {
|
||||
m->add(to_s, "to_string");
|
||||
}
|
||||
m->add(fun(&parse_string<T>), "to_" + name);
|
||||
return m;
|
||||
}
|
||||
@ -471,7 +475,6 @@ namespace chaiscript
|
||||
m->add(chaiscript::fun(&has_parse_tree), "has_parse_tree");
|
||||
m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
|
||||
|
||||
m->add(chaiscript::user_type<chaiscript::exception::eval_error>(), "eval_error");
|
||||
m->add(chaiscript::base_class<std::runtime_error, chaiscript::exception::eval_error>());
|
||||
|
||||
m->add(chaiscript::user_type<chaiscript::exception::arithmetic_error>(), "arithmetic_error");
|
||||
|
@ -267,7 +267,7 @@ namespace chaiscript
|
||||
template<typename ContainerType>
|
||||
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
basic_constructors<ContainerType>(type, m);
|
||||
copy_constructor<ContainerType>(type, m);
|
||||
operators::assign<ContainerType>(m);
|
||||
return m;
|
||||
}
|
||||
@ -443,6 +443,7 @@ namespace chaiscript
|
||||
m->add(fun(static_cast<elemaccess>(&MapType::operator[])), "[]");
|
||||
|
||||
container_type<MapType>(type, m);
|
||||
default_constructible_type<MapType>(type, m);
|
||||
assignable_type<MapType>(type, m);
|
||||
unique_associative_container_type<MapType>(type, m);
|
||||
pair_associative_container_type<MapType>(type, m);
|
||||
|
@ -199,6 +199,14 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
bool has_function(const Proxy_Function &new_f, const std::string &name)
|
||||
{
|
||||
return std::any_of(m_funcs.begin(), m_funcs.end(), [&](const std::pair<Proxy_Function, std::string> &existing_f) {
|
||||
return existing_f.second == name && *(existing_f.first) == *(new_f);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::vector<std::pair<Type_Info, std::string> > m_typeinfos;
|
||||
std::vector<std::pair<Proxy_Function, std::string> > m_funcs;
|
||||
@ -580,7 +588,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
/// Returns the type info for a named type
|
||||
Type_Info get_type(const std::string &name) const
|
||||
Type_Info get_type(const std::string &name, bool t_throw = true) const
|
||||
{
|
||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||
|
||||
@ -591,7 +599,11 @@ namespace chaiscript
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
throw std::range_error("Type Not Known");
|
||||
if (t_throw) {
|
||||
throw std::range_error("Type Not Known");
|
||||
} else {
|
||||
return Type_Info();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the registered name of a known type_info object
|
||||
|
@ -57,7 +57,7 @@ namespace chaiscript
|
||||
const Proxy_Function &t_func,
|
||||
const Type_Info &t_ti)
|
||||
: Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti), t_func->get_arity()),
|
||||
m_type_name(std::move(t_type_name)), m_func(t_func), m_ti(new Type_Info(t_ti)), m_doti(user_type<Dynamic_Object>())
|
||||
m_type_name(std::move(t_type_name)), m_func(t_func), m_ti(t_ti.is_undef()?nullptr:new Type_Info(t_ti)), m_doti(user_type<Dynamic_Object>())
|
||||
{
|
||||
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
||||
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
||||
|
@ -353,7 +353,9 @@ namespace chaiscript
|
||||
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name");
|
||||
|
||||
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type, std::ref(m_engine)), "type");
|
||||
m_engine.add(fun<void (const Type_Info &, const Type_Info &, const std::function<Boxed_Value (const Boxed_Value &)> &)> (
|
||||
m_engine.add(fun<chaiscript::Type_Info (const std::string &)>([this](const std::string &t_type_name){ return this->m_engine.get_type(t_type_name, true); }), "type");
|
||||
|
||||
m_engine.add(fun<void(const Type_Info &, const Type_Info &, const std::function<Boxed_Value(const Boxed_Value &)> &)>(
|
||||
[=](const Type_Info &t_from, const Type_Info &t_to, const std::function<Boxed_Value (const Boxed_Value &)> &t_func) {
|
||||
m_engine.add(chaiscript::type_conversion(t_from, t_to, t_func));
|
||||
}
|
||||
|
@ -517,11 +517,7 @@ namespace chaiscript
|
||||
{
|
||||
return std::pair<std::string, Type_Info>();
|
||||
} else {
|
||||
try {
|
||||
return std::pair<std::string, Type_Info>(t_node->children[0]->text, t_ss.get_type(t_node->children[0]->text));
|
||||
} catch (const std::range_error &) {
|
||||
return std::pair<std::string, Type_Info>(t_node->children[0]->text, Type_Info());
|
||||
}
|
||||
return std::pair<std::string, Type_Info>(t_node->children[0]->text, t_ss.get_type(t_node->children[0]->text, false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1484,30 +1480,19 @@ namespace chaiscript
|
||||
static_cast<int>(numparams), this->children.back(), param_types, l_annotation, guard)),
|
||||
function_name);
|
||||
|
||||
}
|
||||
else {
|
||||
try {
|
||||
// Do know type name (if this line fails, the catch block is called and the
|
||||
// other version is called, with no Type_Info object known)
|
||||
auto type = t_ss.get_type(class_name);
|
||||
param_types.push_front(class_name, type);
|
||||
} else {
|
||||
|
||||
t_ss.add(
|
||||
std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
|
||||
std::make_shared<dispatch::Dynamic_Proxy_Function>(std::bind(chaiscript::eval::detail::eval_function,
|
||||
std::ref(t_ss), this->children.back(),
|
||||
t_param_names, std::placeholders::_1, std::map<std::string, Boxed_Value>()), static_cast<int>(numparams), this->children.back(),
|
||||
param_types, l_annotation, guard), type), function_name);
|
||||
} catch (const std::range_error &) {
|
||||
param_types.push_front(class_name, Type_Info());
|
||||
// Do not know type name
|
||||
t_ss.add(
|
||||
std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
|
||||
std::make_shared<dispatch::Dynamic_Proxy_Function>(std::bind(chaiscript::eval::detail::eval_function,
|
||||
std::ref(t_ss), this->children.back(),
|
||||
t_param_names, std::placeholders::_1, std::map<std::string, Boxed_Value>()), static_cast<int>(numparams), this->children.back(),
|
||||
param_types, l_annotation, guard)), function_name);
|
||||
}
|
||||
// if the type is unknown, then this generates a function that looks up the type
|
||||
// at runtime. Defining the type first before this is called is better
|
||||
auto type = t_ss.get_type(class_name, false);
|
||||
param_types.push_front(class_name, type);
|
||||
|
||||
t_ss.add(
|
||||
std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
|
||||
std::make_shared<dispatch::Dynamic_Proxy_Function>(std::bind(chaiscript::eval::detail::eval_function,
|
||||
std::ref(t_ss), this->children.back(),
|
||||
t_param_names, std::placeholders::_1, std::map<std::string, Boxed_Value>()), static_cast<int>(numparams), this->children.back(),
|
||||
param_types, l_annotation, guard), type), function_name);
|
||||
}
|
||||
}
|
||||
catch (const exception::reserved_word_error &e) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user