Merge remote-tracking branch 'origin/release-4.x'
Conflicts: .travis.yml CMakeLists.txt include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/language/chaiscript_common.hpp
This commit is contained in:
10
.travis.yml
10
.travis.yml
@@ -18,10 +18,14 @@ script:
|
|||||||
- find CMakeFiles/ -name "*.gc*" -exec mv {} gcov/ \;
|
- find CMakeFiles/ -name "*.gc*" -exec mv {} gcov/ \;
|
||||||
- $GCOV -d -o gcov gcov/*.gcda
|
- $GCOV -d -o gcov gcov/*.gcda
|
||||||
- coveralls -n -E ".*\.cpp"
|
- coveralls -n -E ".*\.cpp"
|
||||||
|
after_script:
|
||||||
|
- contrib/codeanalysis/runcppcheck.sh
|
||||||
notifications:
|
notifications:
|
||||||
recipients:
|
|
||||||
- jason@emptycrate.com
|
|
||||||
email:
|
email:
|
||||||
|
recipients:
|
||||||
|
- jason@emptycrate.com
|
||||||
on_success: always
|
on_success: always
|
||||||
on_failure: always
|
on_failure: always
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
secure: LCUAKUCRtFp2ak81nVLR+jx0C9+Drwx1OR4VzuvH+HNGWFdUZmAIV3R84euDqFC5cUhYYipaeMbiSOJUHE4MNlL58eQZryED6KSL7k7SgxOLpFSspMvuMjIYZLlBWpBneCR/EMDilu+zXEnASfVUMPuLmtY1GAyfSoZboqFProc=
|
||||||
|
@@ -18,6 +18,18 @@ endif()
|
|||||||
option(BUILD_MODULES "Build Extra Modules (stl, reflection)" TRUE)
|
option(BUILD_MODULES "Build Extra Modules (stl, reflection)" TRUE)
|
||||||
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
|
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
|
||||||
|
|
||||||
|
set(EXTRA_LINKER_FLAGS "")
|
||||||
|
|
||||||
|
if (CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
option(ENABLE_COVERAGE "Enable Coverage Reporting in GCC" FALSE)
|
||||||
|
|
||||||
|
if (ENABLE_COVERAGE)
|
||||||
|
add_definitions(--coverage -O0)
|
||||||
|
SET(EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} "--coverage")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR}")
|
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.svn")
|
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.svn")
|
||||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.git")
|
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.git")
|
||||||
@@ -30,7 +42,7 @@ set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt"
|
|||||||
|
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR 5)
|
set(CPACK_PACKAGE_VERSION_MAJOR 5)
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR 3)
|
set(CPACK_PACKAGE_VERSION_MINOR 3)
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH 0)
|
set(CPACK_PACKAGE_VERSION_PATCH 1)
|
||||||
|
|
||||||
set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval")
|
set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval")
|
||||||
set(CPACK_PACKAGE_VENDOR "ChaiScript.com")
|
set(CPACK_PACKAGE_VENDOR "ChaiScript.com")
|
||||||
|
16
contrib/codeanalysis/runcppcheck.sh
Executable file
16
contrib/codeanalysis/runcppcheck.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
pushd ..
|
||||||
|
wget http://sourceforge.net/projects/cppcheck/files/cppcheck/1.64/cppcheck-1.64.tar.bz2
|
||||||
|
tar -xvf cppcheck-1.64.tar.bz2
|
||||||
|
cd cppcheck-1.64
|
||||||
|
make -j2
|
||||||
|
popd
|
||||||
|
../cppcheck-1.64/cppcheck --enable=all --inconclusive -I include --inline-suppr --std=c++11 --platform=unix64 src/main.cpp src/chai*.cpp --template ' - __{severity}__: [{file}:{line}](../blob/TRAVIS_COMMIT/{file}#L{line}) {message} ({id})' 2>output
|
||||||
|
sed -i "s/TRAVIS_COMMIT/${TRAVIS_COMMIT}/g" output
|
||||||
|
echo -n '{ "body": " ' > output.json
|
||||||
|
echo -n `awk '{printf "%s\\\\n", $0;}' output` >> output.json
|
||||||
|
echo -n '"}' >> output.json
|
||||||
|
if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then curl -H "Authorization: token ${TOKEN}" --request POST --data @output.json https://api.github.com/repos/ChaiScript/ChaiScript/commits/${TRAVIS_COMMIT}/comments; else curl -H "Authorization: token ${TOKEN}" --request POST --data @output.json https://api.github.com/repos/ChaiScript/ChaiScript/issues/${TRAVIS_PULL_REQUEST}/comments; fi
|
||||||
|
|
||||||
|
|
@@ -304,14 +304,6 @@ namespace chaiscript
|
|||||||
static void throw_exception(const Boxed_Value &bv) {
|
static void throw_exception(const Boxed_Value &bv) {
|
||||||
throw bv;
|
throw bv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<chaiscript::detail::Dispatch_Engine> bootstrap2(
|
|
||||||
std::shared_ptr<chaiscript::detail::Dispatch_Engine> e
|
|
||||||
= std::shared_ptr<chaiscript::detail::Dispatch_Engine> (new chaiscript::detail::Dispatch_Engine()))
|
|
||||||
{
|
|
||||||
e->add(user_type<void>(), "void");
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string what(const std::exception &e)
|
static std::string what(const std::exception &e)
|
||||||
{
|
{
|
||||||
|
@@ -79,11 +79,18 @@ namespace chaiscript
|
|||||||
if (std::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value && t_conversions)
|
if (std::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value && t_conversions)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
// std::cout << "trying an up conversion " << typeid(Type).name() << std::endl;
|
||||||
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
|
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
|
||||||
// either way, we are not responsible if it doesn't work
|
// either way, we are not responsible if it doesn't work
|
||||||
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_dynamic_cast<Type>(bv), t_conversions);
|
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_dynamic_cast<Type>(bv), t_conversions);
|
||||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
} catch (...) {
|
||||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
try {
|
||||||
|
// std::cout << "trying a down conversion " << typeid(Type).name() << std::endl;
|
||||||
|
// try going the other way - down the inheritance graph
|
||||||
|
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_dynamic_down_cast<Type>(bv), t_conversions);
|
||||||
|
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||||
|
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If it's not polymorphic, just throw the error, don't waste the time on the
|
// If it's not polymorphic, just throw the error, don't waste the time on the
|
||||||
|
@@ -307,7 +307,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Source>
|
template<typename Source>
|
||||||
std::string to_string_aux(const Boxed_Value &v) const
|
static std::string to_string_aux(const Boxed_Value &v)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << *static_cast<const Source *>(v.get_const_ptr());
|
oss << *static_cast<const Source *>(v.get_const_ptr());
|
||||||
@@ -520,7 +520,7 @@ namespace chaiscript
|
|||||||
return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv);
|
return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate_boxed_number(const Boxed_Value &v)
|
static void validate_boxed_number(const Boxed_Value &v)
|
||||||
{
|
{
|
||||||
const Type_Info &inp_ = v.get_type_info();
|
const Type_Info &inp_ = v.get_type_info();
|
||||||
if (inp_ == typeid(bool))
|
if (inp_ == typeid(bool))
|
||||||
|
@@ -48,12 +48,13 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Boxed_Value convert(const Boxed_Value &derived) const = 0;
|
virtual Boxed_Value convert(const Boxed_Value &derived) const = 0;
|
||||||
|
virtual Boxed_Value convert_down(const Boxed_Value &base) const = 0;
|
||||||
|
|
||||||
const Type_Info &base()
|
const Type_Info &base() const
|
||||||
{
|
{
|
||||||
return m_base;
|
return m_base;
|
||||||
}
|
}
|
||||||
const Type_Info &derived()
|
const Type_Info &derived() const
|
||||||
{
|
{
|
||||||
return m_derived;
|
return m_derived;
|
||||||
}
|
}
|
||||||
@@ -72,6 +73,57 @@ namespace chaiscript
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename From, typename To>
|
||||||
|
class Dynamic_Caster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Boxed_Value cast(const Boxed_Value &t_from)
|
||||||
|
{
|
||||||
|
if (t_from.get_type_info().bare_equal(user_type<From>()))
|
||||||
|
{
|
||||||
|
if (t_from.is_pointer())
|
||||||
|
{
|
||||||
|
// Dynamic cast out the contained boxed value, which we know is the type we want
|
||||||
|
if (t_from.is_const())
|
||||||
|
{
|
||||||
|
std::shared_ptr<const To> data
|
||||||
|
= std::dynamic_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr));
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
throw std::bad_cast();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(data);
|
||||||
|
} else {
|
||||||
|
std::shared_ptr<To> data
|
||||||
|
= std::dynamic_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr));
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
throw std::bad_cast();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Pull the reference out of the contained boxed value, which we know is the type we want
|
||||||
|
if (t_from.is_const())
|
||||||
|
{
|
||||||
|
const From &d = detail::Cast_Helper<const From &>::cast(t_from, 0);
|
||||||
|
const To &data = dynamic_cast<const To &>(d);
|
||||||
|
return Boxed_Value(std::cref(data));
|
||||||
|
} else {
|
||||||
|
From &d = detail::Cast_Helper<From &>::cast(t_from, 0);
|
||||||
|
To &data = dynamic_cast<To &>(d);
|
||||||
|
return Boxed_Value(std::ref(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw chaiscript::exception::bad_boxed_dynamic_cast(t_from.get_type_info(), typeid(To), "Unknown dynamic_cast_conversion");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Base, typename Derived>
|
template<typename Base, typename Derived>
|
||||||
class Dynamic_Conversion_Impl : public Dynamic_Conversion
|
class Dynamic_Conversion_Impl : public Dynamic_Conversion
|
||||||
{
|
{
|
||||||
@@ -81,50 +133,14 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Boxed_Value convert_down(const Boxed_Value &t_base) const
|
||||||
|
{
|
||||||
|
return Dynamic_Caster<Base, Derived>::cast(t_base);
|
||||||
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert(const Boxed_Value &t_derived) const
|
virtual Boxed_Value convert(const Boxed_Value &t_derived) const
|
||||||
{
|
{
|
||||||
if (t_derived.get_type_info().bare_equal(user_type<Derived>()))
|
return Dynamic_Caster<Derived, Base>::cast(t_derived);
|
||||||
{
|
|
||||||
if (t_derived.is_pointer())
|
|
||||||
{
|
|
||||||
// Dynamic cast out the contained boxed value, which we know is the type we want
|
|
||||||
if (t_derived.is_const())
|
|
||||||
{
|
|
||||||
std::shared_ptr<const Base> data
|
|
||||||
= std::dynamic_pointer_cast<const Base>(detail::Cast_Helper<std::shared_ptr<const Derived> >::cast(t_derived, nullptr));
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
throw std::bad_cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Boxed_Value(data);
|
|
||||||
} else {
|
|
||||||
std::shared_ptr<Base> data
|
|
||||||
= std::dynamic_pointer_cast<Base>(detail::Cast_Helper<std::shared_ptr<Derived> >::cast(t_derived, nullptr));
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
throw std::bad_cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Boxed_Value(data);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Pull the reference out of the contained boxed value, which we know is the type we want
|
|
||||||
if (t_derived.is_const())
|
|
||||||
{
|
|
||||||
const Derived &d = detail::Cast_Helper<const Derived &>::cast(t_derived, 0);
|
|
||||||
const Base &data = dynamic_cast<const Base &>(d);
|
|
||||||
return Boxed_Value(std::cref(data));
|
|
||||||
} else {
|
|
||||||
Derived &d = detail::Cast_Helper<Derived &>::cast(t_derived, 0);
|
|
||||||
Base &data = dynamic_cast<Base &>(d);
|
|
||||||
return Boxed_Value(std::ref(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw chaiscript::exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -155,7 +171,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived) const
|
bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived) const
|
||||||
{
|
{
|
||||||
return has_conversion(base, derived);
|
return has_conversion(base, derived) || has_conversion(derived, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Base>
|
template<typename Base>
|
||||||
@@ -170,6 +186,19 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
Boxed_Value boxed_dynamic_down_cast(const Boxed_Value &base) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return get_conversion(base.get_type_info(), user_type<Derived>())->convert_down(base);
|
||||||
|
} catch (const std::out_of_range &) {
|
||||||
|
throw exception::bad_boxed_dynamic_cast(base.get_type_info(), typeid(Derived), "No known conversion");
|
||||||
|
} catch (const std::bad_cast &) {
|
||||||
|
throw exception::bad_boxed_dynamic_cast(base.get_type_info(), typeid(Derived), "Unable to perform dynamic_cast operation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool has_conversion(const Type_Info &base, const Type_Info &derived) const
|
bool has_conversion(const Type_Info &base, const Type_Info &derived) const
|
||||||
{
|
{
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
@@ -242,8 +271,6 @@ namespace chaiscript
|
|||||||
/// chai.add(chaiscript::base_class<Base, Derived>());
|
/// chai.add(chaiscript::base_class<Base, Derived>());
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \todo Move share static type registration code into a mechanism that allows it to be properly
|
|
||||||
/// shared by all modules
|
|
||||||
template<typename Base, typename Derived>
|
template<typename Base, typename Derived>
|
||||||
Dynamic_Cast_Conversion base_class()
|
Dynamic_Cast_Conversion base_class()
|
||||||
{
|
{
|
||||||
|
@@ -30,7 +30,7 @@ namespace chaiscript
|
|||||||
return m_attrs[t_attr_name];
|
return m_attrs[t_attr_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, Boxed_Value> get_attrs()
|
std::map<std::string, Boxed_Value> get_attrs() const
|
||||||
{
|
{
|
||||||
return m_attrs;
|
return m_attrs;
|
||||||
}
|
}
|
||||||
|
@@ -17,12 +17,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal helper class for handling the return
|
* Internal helper class for handling the return
|
||||||
* value of a build_function_caller
|
* value of a build_function_caller
|
||||||
*/
|
*/
|
||||||
template<typename Ret>
|
template<typename Ret, bool is_arithmetic>
|
||||||
struct Function_Caller_Ret
|
struct Function_Caller_Ret
|
||||||
{
|
{
|
||||||
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||||
@@ -32,11 +31,25 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialization for arithmetic return types
|
||||||
|
*/
|
||||||
|
template<typename Ret>
|
||||||
|
struct Function_Caller_Ret<Ret, true>
|
||||||
|
{
|
||||||
|
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||||
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
|
{
|
||||||
|
return Boxed_Number(dispatch::dispatch(t_funcs, params, t_conversions)).get_as<Ret>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialization for void return types
|
* Specialization for void return types
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Function_Caller_Ret<void>
|
struct Function_Caller_Ret<void, false>
|
||||||
{
|
{
|
||||||
static void call(const std::vector<Const_Proxy_Function> &t_funcs,
|
static void call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||||
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
@@ -59,11 +72,11 @@ namespace chaiscript
|
|||||||
|
|
||||||
Ret operator()(Param...param)
|
Ret operator()(Param...param)
|
||||||
{
|
{
|
||||||
return Function_Caller_Ret<Ret>::call(m_funcs, {
|
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value>::call(m_funcs, {
|
||||||
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
|
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
|
||||||
}, m_conversions
|
}, m_conversions
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@ namespace chaiscript
|
|||||||
class Boxed_Number;
|
class Boxed_Number;
|
||||||
struct AST_Node;
|
struct AST_Node;
|
||||||
|
|
||||||
typedef std::shared_ptr<struct AST_Node> AST_NodePtr;
|
typedef std::shared_ptr<AST_Node> AST_NodePtr;
|
||||||
|
|
||||||
namespace dispatch
|
namespace dispatch
|
||||||
{
|
{
|
||||||
|
@@ -54,7 +54,7 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree
|
/// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree
|
||||||
typedef std::shared_ptr<struct AST_Node> AST_NodePtr;
|
typedef std::shared_ptr<AST_Node> AST_NodePtr;
|
||||||
|
|
||||||
|
|
||||||
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
|
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
|
||||||
@@ -435,7 +435,7 @@ namespace chaiscript
|
|||||||
return eval_internal(t_e);
|
return eval_internal(t_e);
|
||||||
} catch (exception::eval_error &ee) {
|
} catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(shared_from_this());
|
ee.call_stack.push_back(shared_from_this());
|
||||||
throw ee;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -742,7 +742,7 @@ namespace chaiscript
|
|||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv, m_engine);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -768,7 +768,7 @@ namespace chaiscript
|
|||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv, m_engine);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,7 +798,7 @@ namespace chaiscript
|
|||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv, m_engine);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,7 +814,7 @@ namespace chaiscript
|
|||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv, m_engine);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -834,7 +834,7 @@ namespace chaiscript
|
|||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv, m_engine);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -56,7 +56,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ChaiScript_Parser()
|
ChaiScript_Parser()
|
||||||
: m_multiline_comment_begin("/*"),
|
: m_line(-1), m_col(-1),
|
||||||
|
m_multiline_comment_begin("/*"),
|
||||||
m_multiline_comment_end("*/"),
|
m_multiline_comment_end("*/"),
|
||||||
m_singleline_comment("//")
|
m_singleline_comment("//")
|
||||||
{
|
{
|
||||||
@@ -803,10 +804,9 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Quoted_String_() {
|
bool Quoted_String_() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
char prev_char = 0;
|
|
||||||
if (has_more_input() && (*m_input_pos == '\"')) {
|
if (has_more_input() && (*m_input_pos == '\"')) {
|
||||||
retval = true;
|
retval = true;
|
||||||
prev_char = *m_input_pos;
|
char prev_char = *m_input_pos;
|
||||||
++m_input_pos;
|
++m_input_pos;
|
||||||
++m_col;
|
++m_col;
|
||||||
|
|
||||||
@@ -980,10 +980,9 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Single_Quoted_String_() {
|
bool Single_Quoted_String_() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
char prev_char = 0;
|
|
||||||
if (has_more_input() && (*m_input_pos == '\'')) {
|
if (has_more_input() && (*m_input_pos == '\'')) {
|
||||||
retval = true;
|
retval = true;
|
||||||
prev_char = *m_input_pos;
|
char prev_char = *m_input_pos;
|
||||||
++m_input_pos;
|
++m_input_pos;
|
||||||
++m_col;
|
++m_col;
|
||||||
|
|
||||||
@@ -1356,7 +1355,6 @@ namespace chaiscript
|
|||||||
bool Def() {
|
bool Def() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
bool is_annotated = false;
|
bool is_annotated = false;
|
||||||
bool is_method = false;
|
|
||||||
AST_NodePtr annotation;
|
AST_NodePtr annotation;
|
||||||
|
|
||||||
if (Annotation()) {
|
if (Annotation()) {
|
||||||
@@ -1375,6 +1373,8 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Missing function name in definition", File_Position(m_line, m_col), *m_filename);
|
throw exception::eval_error("Missing function name in definition", File_Position(m_line, m_col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_method = false;
|
||||||
|
|
||||||
if (Symbol("::", false)) {
|
if (Symbol("::", false)) {
|
||||||
//We're now a method
|
//We're now a method
|
||||||
is_method = true;
|
is_method = true;
|
||||||
|
@@ -11,6 +11,8 @@ class TestBaseType
|
|||||||
virtual ~TestBaseType() {}
|
virtual ~TestBaseType() {}
|
||||||
virtual int func() { return 0; }
|
virtual int func() { return 0; }
|
||||||
|
|
||||||
|
int base_only_func() { return -9; }
|
||||||
|
|
||||||
const TestBaseType &constMe() const { return *this; }
|
const TestBaseType &constMe() const { return *this; }
|
||||||
|
|
||||||
int val;
|
int val;
|
||||||
@@ -35,11 +37,28 @@ class TestDerivedType : public TestBaseType
|
|||||||
public:
|
public:
|
||||||
virtual ~TestDerivedType() {}
|
virtual ~TestDerivedType() {}
|
||||||
virtual int func() { return 1; }
|
virtual int func() { return 1; }
|
||||||
|
int derived_only_func() { return 19; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TestDerivedType &operator=(const TestDerivedType &);
|
TestDerivedType &operator=(const TestDerivedType &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TestMoreDerivedType : public TestDerivedType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TestMoreDerivedType() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<TestBaseType> derived_type_factory()
|
||||||
|
{
|
||||||
|
return std::shared_ptr<TestBaseType>(new TestDerivedType());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<TestBaseType> more_derived_type_factory()
|
||||||
|
{
|
||||||
|
return std::shared_ptr<TestBaseType>(new TestMoreDerivedType());
|
||||||
|
}
|
||||||
|
|
||||||
std::string hello_world()
|
std::string hello_world()
|
||||||
{
|
{
|
||||||
return "Hello World";
|
return "Hello World";
|
||||||
@@ -70,6 +89,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
|
|||||||
|
|
||||||
m->add(chaiscript::user_type<TestBaseType>(), "TestBaseType");
|
m->add(chaiscript::user_type<TestBaseType>(), "TestBaseType");
|
||||||
m->add(chaiscript::user_type<TestDerivedType>(), "TestDerivedType");
|
m->add(chaiscript::user_type<TestDerivedType>(), "TestDerivedType");
|
||||||
|
m->add(chaiscript::user_type<TestMoreDerivedType>(), "TestMoreDerivedType");
|
||||||
|
|
||||||
m->add(chaiscript::constructor<TestBaseType ()>(), "TestBaseType");
|
m->add(chaiscript::constructor<TestBaseType ()>(), "TestBaseType");
|
||||||
// m->add(chaiscript::constructor<TestBaseType (int)>(), "TestBaseType");
|
// m->add(chaiscript::constructor<TestBaseType (int)>(), "TestBaseType");
|
||||||
@@ -79,11 +99,23 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
|
|||||||
m->add(chaiscript::constructor<TestDerivedType ()>(), "TestDerivedType");
|
m->add(chaiscript::constructor<TestDerivedType ()>(), "TestDerivedType");
|
||||||
m->add(chaiscript::constructor<TestDerivedType (const TestDerivedType &)>(), "TestDerivedType");
|
m->add(chaiscript::constructor<TestDerivedType (const TestDerivedType &)>(), "TestDerivedType");
|
||||||
|
|
||||||
|
m->add(chaiscript::constructor<TestMoreDerivedType ()>(), "TestMoreDerivedType");
|
||||||
|
m->add(chaiscript::constructor<TestMoreDerivedType (const TestMoreDerivedType &)>(), "TestMoreDerivedType");
|
||||||
|
|
||||||
|
/// \todo automatic chaining of base classes?
|
||||||
m->add(chaiscript::base_class<TestBaseType, TestDerivedType>());
|
m->add(chaiscript::base_class<TestBaseType, TestDerivedType>());
|
||||||
|
m->add(chaiscript::base_class<TestBaseType, TestMoreDerivedType>());
|
||||||
|
m->add(chaiscript::base_class<TestDerivedType, TestMoreDerivedType>());
|
||||||
|
|
||||||
|
m->add(chaiscript::fun(&TestDerivedType::derived_only_func), "derived_only_func");
|
||||||
|
|
||||||
|
m->add(chaiscript::fun(&derived_type_factory), "derived_type_factory");
|
||||||
|
m->add(chaiscript::fun(&more_derived_type_factory), "more_derived_type_factory");
|
||||||
|
|
||||||
m->add(chaiscript::fun(&TestBaseType::func), "func");
|
m->add(chaiscript::fun(&TestBaseType::func), "func");
|
||||||
m->add(chaiscript::fun(&TestBaseType::val), "val");
|
m->add(chaiscript::fun(&TestBaseType::val), "val");
|
||||||
m->add(chaiscript::fun(&TestBaseType::const_val), "const_val");
|
m->add(chaiscript::fun(&TestBaseType::const_val), "const_val");
|
||||||
|
m->add(chaiscript::fun(&TestBaseType::base_only_func), "base_only_func");
|
||||||
|
|
||||||
m->add(chaiscript::fun(&get_new_int), "get_new_int");
|
m->add(chaiscript::fun(&get_new_int), "get_new_int");
|
||||||
|
|
||||||
|
@@ -18,6 +18,11 @@ void f3(double)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void f_func_return(const std::function<unsigned int (unsigned long)> &f)
|
||||||
|
{
|
||||||
|
// test the ability to return an unsigned with auto conversion
|
||||||
|
f(4);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -29,6 +34,8 @@ int main()
|
|||||||
chai.add(chaiscript::fun(&f1), "f3");
|
chai.add(chaiscript::fun(&f1), "f3");
|
||||||
chai.add(chaiscript::fun(&f4), "f3");
|
chai.add(chaiscript::fun(&f4), "f3");
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&f_func_return), "func_return");
|
||||||
|
|
||||||
// no overloads
|
// no overloads
|
||||||
chai.eval("f1(0)");
|
chai.eval("f1(0)");
|
||||||
chai.eval("f1(0l)");
|
chai.eval("f1(0l)");
|
||||||
@@ -46,7 +53,12 @@ int main()
|
|||||||
// 1 non-arithmetic overload
|
// 1 non-arithmetic overload
|
||||||
chai.eval("f2(1.0)");
|
chai.eval("f2(1.0)");
|
||||||
|
|
||||||
// this is the one call we expect to fail
|
// various options for returning with conversions from chaiscript
|
||||||
|
chai.eval("func_return(fun(x) { return 5u; })");
|
||||||
|
chai.eval("func_return(fun(x) { return 5; })");
|
||||||
|
chai.eval("func_return(fun(x) { return 5.0f; })");
|
||||||
|
|
||||||
|
// this is the one call we expect to fail, ambiguous overloads
|
||||||
try {
|
try {
|
||||||
chai.eval("f2(1.0l)");
|
chai.eval("f2(1.0l)");
|
||||||
} catch (const std::exception &) {
|
} catch (const std::exception &) {
|
||||||
|
@@ -15,3 +15,21 @@ assert_equal(15, t.const_val);
|
|||||||
t.val = 23;
|
t.val = 23;
|
||||||
assert_equal(23, t.val)
|
assert_equal(23, t.val)
|
||||||
|
|
||||||
|
// test_derived_factory returns a TestDerivedType contained
|
||||||
|
// in a shared_ptr<TestBaseType>. This is testing our ability
|
||||||
|
// to detect that and do the down casting for the user automatically
|
||||||
|
// at runtime
|
||||||
|
|
||||||
|
assert_equal(t.derived_only_func(), 19);
|
||||||
|
|
||||||
|
var d := derived_type_factory();
|
||||||
|
assert_equal(d.derived_only_func(), 19);
|
||||||
|
|
||||||
|
var t2 = TestMoreDerivedType();
|
||||||
|
assert_equal(t2.derived_only_func(), 19);
|
||||||
|
assert_equal(t2.base_only_func(), -9);
|
||||||
|
|
||||||
|
var md := more_derived_type_factory();
|
||||||
|
assert_equal(md.derived_only_func(), 19);
|
||||||
|
assert_equal(md.base_only_func(), -9);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user