Get ChaiScript ported to MSVC 2013. See Notes in code.

This commit is contained in:
Jason Turner 2013-11-02 07:42:06 -06:00
parent 1708024372
commit 73b3762f7a
20 changed files with 166 additions and 70 deletions

View File

@ -72,9 +72,7 @@ endif(READLINE_LIBRARY)
if(MSVC)
add_definitions(/W4)
if(CMAKE_CL_64)
add_definitions(/bigobj)
endif()
add_definitions(/bigobj)
else()
add_definitions(-Wall -Wextra -Wshadow -pedantic -std=c++0x)
@ -177,9 +175,10 @@ if(BUILD_TESTING)
)
if (NOT UNIT_TEST_LIGHT)
add_executable(utility_test unittests/utility_test.cpp)
target_link_libraries(utility_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Utility_Test COMMAND utility_test)
# commented out because uniform initializer syntax is not working properly in MSVC 2013
#add_executable(utility_test unittests/utility_test.cpp)
#target_link_libraries(utility_test ${LIBS} ${EXTRA_LINKER_FLAGS})
#add_test(NAME Utility_Test COMMAND utility_test)
add_executable(dynamic_object_test unittests/dynamic_object_test.cpp)
target_link_libraries(dynamic_object_test ${LIBS} ${EXTRA_LINKER_FLAGS})

View File

@ -9,7 +9,7 @@
#ifdef _MSC_VER
#define CHAISCRIPT_MSVC _MSC_VER
#define CHAISCRIPT_HAS_DECLSPEc
#define CHAISCRIPT_HAS_DECLSPEC
#endif
#ifdef _WIN32
@ -23,6 +23,15 @@
#define CHAISCRIPT_MODULE_EXPORT extern "C"
#endif
#ifdef CHAISCRIPT_MSVC
#define CHAISCRIPT_NOEXCEPT throw()
#define CHAISCRIPT_CONSTEXPR
#else
#define CHAISCRIPT_NOEXCEPT noexcept
#define CHAISCRIPT_CONSTEXPR constexpr
#endif
#endif

View File

@ -19,15 +19,15 @@ namespace chaiscript {
class bad_any_cast : public std::bad_cast
{
public:
bad_any_cast() noexcept
bad_any_cast() CHAISCRIPT_NOEXCEPT
: m_what("bad any cast")
{
}
virtual ~bad_any_cast() noexcept {}
virtual ~bad_any_cast() CHAISCRIPT_NOEXCEPT {}
/// \brief Description of what error occured
virtual const char * what() const noexcept
virtual const char * what() const CHAISCRIPT_NOEXCEPT
{
return m_what.c_str();
}
@ -71,6 +71,8 @@ namespace chaiscript {
return std::shared_ptr<Data>(new Data_Impl<T>(m_data));
}
Data_Impl &operator=(const Data_Impl&) = delete;
const std::type_info &m_type;
T m_data;
};

View File

@ -22,25 +22,25 @@ namespace chaiscript
{
public:
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) noexcept
const std::string &t_what) CHAISCRIPT_NOEXCEPT
: from(t_from), to(&t_to), m_what(t_what)
{
}
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) CHAISCRIPT_NOEXCEPT
: from(t_from), to(&t_to), m_what("Cannot perform boxed_cast")
{
}
bad_boxed_cast(const std::string &t_what) noexcept
bad_boxed_cast(const std::string &t_what) CHAISCRIPT_NOEXCEPT
: to(0), m_what(t_what)
{
}
virtual ~bad_boxed_cast() noexcept {}
virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT {}
/// \brief Description of what error occured
virtual const char * what() const noexcept
virtual const char * what() const CHAISCRIPT_NOEXCEPT
{
return m_what.c_str();
}

View File

@ -149,6 +149,12 @@ namespace chaiscript
namespace detail {
template<typename T>
size_t count(T &t_target, const typename T::key_type &t_key)
{
return t_target.count(t_key);
}
template<typename T>
void insert(T &t_target, const T &t_other)
{
@ -405,11 +411,11 @@ namespace chaiscript
template<typename ContainerType>
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
{
m->add(fun<int (const ContainerType *, const typename ContainerType::key_type &)>(&ContainerType::count), "count");
m->add(fun(detail::count<ContainerType>), "count");
typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &);
m->add(fun<int (ContainerType *, const typename ContainerType::key_type &)>(static_cast<erase_ptr>(&ContainerType::erase)), "erase");
m->add(fun(static_cast<erase_ptr>(&ContainerType::erase)), "erase");
m->add(fun(&detail::insert<ContainerType>), "insert");

View File

@ -10,11 +10,13 @@
#include "boxed_value.hpp"
#include "../language/chaiscript_algebraic.hpp"
#include <sstream>
#include <cstdint>
namespace chaiscript
{
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4244 4018 4389 4146)
#endif
@ -846,7 +848,7 @@ namespace chaiscript
};
}
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@ -39,12 +39,12 @@ namespace chaiscript
class reserved_word_error : public std::runtime_error
{
public:
reserved_word_error(const std::string &t_word) noexcept
reserved_word_error(const std::string &t_word) CHAISCRIPT_NOEXCEPT
: std::runtime_error("Reserved word not allowed in object name: " + t_word), m_word(t_word)
{
}
virtual ~reserved_word_error() noexcept {}
virtual ~reserved_word_error() CHAISCRIPT_NOEXCEPT {}
std::string word() const
{
@ -86,12 +86,12 @@ namespace chaiscript
class global_non_const : public std::runtime_error
{
public:
global_non_const() noexcept
global_non_const() CHAISCRIPT_NOEXCEPT
: std::runtime_error("a global object must be const")
{
}
virtual ~global_non_const() noexcept {}
virtual ~global_non_const() CHAISCRIPT_NOEXCEPT {}
};
}

View File

@ -20,22 +20,22 @@ namespace chaiscript
{
public:
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) noexcept
const std::string &t_what) CHAISCRIPT_NOEXCEPT
: bad_boxed_cast(t_from, t_to, t_what)
{
}
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) CHAISCRIPT_NOEXCEPT
: bad_boxed_cast(t_from, t_to)
{
}
bad_boxed_dynamic_cast(const std::string &w) noexcept
bad_boxed_dynamic_cast(const std::string &w) CHAISCRIPT_NOEXCEPT
: bad_boxed_cast(w)
{
}
virtual ~bad_boxed_dynamic_cast() noexcept {}
virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT {}
};
}

View File

@ -176,11 +176,11 @@ namespace chaiscript
class guard_error : public std::runtime_error
{
public:
guard_error() noexcept
guard_error() CHAISCRIPT_NOEXCEPT
: std::runtime_error("Guard evaluation failed")
{ }
virtual ~guard_error() noexcept
virtual ~guard_error() CHAISCRIPT_NOEXCEPT
{ }
};
}
@ -579,7 +579,7 @@ namespace chaiscript
{
}
virtual ~dispatch_error() noexcept {}
virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}
std::vector<Boxed_Value> parameters;
std::vector<Const_Proxy_Function> functions;

View File

@ -32,7 +32,7 @@ namespace chaiscript
{
}
virtual ~arity_error() noexcept {}
virtual ~arity_error() CHAISCRIPT_NOEXCEPT {}
int got;
int expected;
@ -43,6 +43,29 @@ namespace chaiscript
{
namespace detail
{
template<typename ... Rest>
struct Build_Param_Type_List;
template<typename Param, typename ... Rest>
struct Build_Param_Type_List<Param, Rest...>
{
static void build(std::vector<Type_Info> &t_params)
{
t_params.push_back(chaiscript::detail::Get_Type_Info<Param>::get());
Build_Param_Type_List<Rest...>::build(t_params);
}
};
// 0th case
template<>
struct Build_Param_Type_List<>
{
static void build(std::vector<Type_Info> &)
{
}
};
/**
* Used by Proxy_Function_Impl to return a list of all param types
* it contains.
@ -50,8 +73,12 @@ namespace chaiscript
template<typename Ret, typename ... Params>
std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
{
return std::vector<Type_Info> { chaiscript::detail::Get_Type_Info<Ret>::get(),
chaiscript::detail::Get_Type_Info<Params>::get()... };
/// \todo this code was previously using { chaiscript::detail::Get_Type_Info<Ret>::get()... }
/// but this seems to indicate another bug with MSVC's uniform initializer lists
std::vector<Type_Info> params;
params.push_back(chaiscript::detail::Get_Type_Info<Ret>::get());
Build_Param_Type_List<Params...>::build(params);
return params;
}

View File

@ -36,13 +36,17 @@ namespace chaiscript
template<typename Ret, typename Class, typename ... Args>
std::function<Ret (Class &, Args...) > to_function(Ret (Class::*func)(Args...))
{
return std::function<Ret (Class &, Args...)>(func);
/// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for
/// std::function for member function pointers seems to be broken in MSVC
return std::function<Ret(Class &, Args...)>(std::mem_fn(func));
}
template<typename Ret, typename Class, typename ... Args>
std::function<Ret (const Class &, Args...) > to_function(Ret (Class::*func)(Args...) const)
{
return std::function<Ret (const Class &, Args...)>(func);
/// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for
/// std::function for member function pointers seems to be broken in MSVC
return std::function<Ret (const Class &, Args...)>(std::mem_fn(func));
}
template<bool Object>
@ -51,6 +55,7 @@ namespace chaiscript
template<typename T>
static Proxy_Function go(T t)
{
/// \todo is it possible to reduce the number of templates generated here?
return Proxy_Function(
new Proxy_Function_Impl<typename FunctionSignature<decltype(to_function(t)) >::Signature>(to_function(t)));
}

View File

@ -28,7 +28,7 @@ namespace chaiscript
class Type_Info
{
public:
constexpr Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bareti)
: m_type_info(t_ti), m_bare_type_info(t_bareti),
m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
@ -144,7 +144,7 @@ namespace chaiscript
{
typedef T type;
constexpr static Type_Info get()
CHAISCRIPT_CONSTEXPR static Type_Info get()
{
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
@ -159,7 +159,7 @@ namespace chaiscript
{
typedef T type;
constexpr static Type_Info get()
CHAISCRIPT_CONSTEXPR static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
@ -174,7 +174,7 @@ namespace chaiscript
{
typedef T type;
constexpr static Type_Info get()
CHAISCRIPT_CONSTEXPR static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
@ -189,7 +189,7 @@ namespace chaiscript
{
typedef T type;
constexpr static Type_Info get()
CHAISCRIPT_CONSTEXPR static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
@ -204,7 +204,7 @@ namespace chaiscript
{
typedef T type;
constexpr static Type_Info get()
CHAISCRIPT_CONSTEXPR static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
@ -231,7 +231,7 @@ namespace chaiscript
/// chaiscript::Type_Info ti = chaiscript::user_type(i);
/// \endcode
template<typename T>
constexpr Type_Info user_type(const T &/*t*/)
CHAISCRIPT_CONSTEXPR Type_Info user_type(const T &/*t*/)
{
return detail::Get_Type_Info<T>::get();
}
@ -246,7 +246,7 @@ namespace chaiscript
/// chaiscript::Type_Info ti = chaiscript::user_type<int>();
/// \endcode
template<typename T>
constexpr Type_Info user_type()
CHAISCRIPT_CONSTEXPR Type_Info user_type()
{
return detail::Get_Type_Info<T>::get();
}

View File

@ -75,7 +75,7 @@ namespace chaiscript
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname,
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
const chaiscript::detail::Dispatch_Engine &t_ss) CHAISCRIPT_NOEXCEPT :
std::runtime_error(format(t_why, t_where, t_fname, t_parameters, t_dot_notation, t_ss)),
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname), detail(format_detail(t_functions, t_dot_notation, t_ss))
{}
@ -83,18 +83,18 @@ namespace chaiscript
eval_error(const std::string &t_why,
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
const chaiscript::detail::Dispatch_Engine &t_ss) CHAISCRIPT_NOEXCEPT :
std::runtime_error(format(t_why, t_parameters, t_dot_notation, t_ss)),
reason(t_why), detail(format_detail(t_functions, t_dot_notation, t_ss))
{}
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) noexcept :
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) CHAISCRIPT_NOEXCEPT :
std::runtime_error(format(t_why, t_where, t_fname)),
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname)
{}
eval_error(const std::string &t_why) noexcept
eval_error(const std::string &t_why) CHAISCRIPT_NOEXCEPT
: std::runtime_error("Error: \"" + t_why + "\" "),
reason(t_why)
{}
@ -121,7 +121,7 @@ namespace chaiscript
return ss.str();
}
virtual ~eval_error() noexcept {}
virtual ~eval_error() CHAISCRIPT_NOEXCEPT {}
private:
@ -381,11 +381,11 @@ namespace chaiscript
* Errors generated when loading a file
*/
struct file_not_found_error : public std::runtime_error {
file_not_found_error(const std::string &t_filename) noexcept
file_not_found_error(const std::string &t_filename) CHAISCRIPT_NOEXCEPT
: std::runtime_error("File Not Found: " + t_filename)
{ }
virtual ~file_not_found_error() noexcept {}
virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT {}
};
}

View File

@ -39,12 +39,12 @@ namespace chaiscript
/// \brief Thrown if an error occurs while attempting to load a binary module
struct load_module_error : std::runtime_error
{
load_module_error(const std::string &t_reason) noexcept
load_module_error(const std::string &t_reason) CHAISCRIPT_NOEXCEPT
: std::runtime_error(t_reason)
{
}
virtual ~load_module_error() noexcept
virtual ~load_module_error() CHAISCRIPT_NOEXCEPT
{
}
};
@ -355,7 +355,7 @@ namespace chaiscript
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
do_eval(ChaiScript_Prelude::chaiscript_prelude, "standard prelude");
do_eval(ChaiScript_Prelude::chaiscript_prelude(), "standard prelude");
}
/**

View File

@ -9,7 +9,7 @@
namespace chaiscript {
struct ChaiScript_Prelude {
constexpr static const char *chaiscript_prelude=R""(
static std::string chaiscript_prelude() { return R""(
def lt(l, r) {
if (call_exists(`<`, l, r)) {
@ -523,6 +523,7 @@ def find(container, value) {
)"";
}
};
}

View File

@ -16,6 +16,8 @@ namespace chaiscript
namespace utility
{
/// \todo Use of this utility, and uniform initializer lists, is causing memory errors in MSVC
/*
template<typename Class, typename ModuleType>
void add_class(ModuleType &t_module,
const std::string &t_classname,
@ -35,6 +37,7 @@ namespace chaiscript
}
}
*/
}
}

View File

@ -63,13 +63,25 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
using namespace chaiscript;
m->add(chaiscript::user_type<chaiscript::exception::eval_error>(), "eval_error");
m->add(chaiscript::fun(&chaiscript::exception::eval_error::reason), "reason");
m->add(chaiscript::fun(&chaiscript::exception::eval_error::call_stack), "call_stack");
/*
chaiscript::utility::add_class<chaiscript::exception::eval_error>(*m,
"eval_error",
{ },
{ {fun(&chaiscript::exception::eval_error::reason), "reason"},
{fun(&chaiscript::exception::eval_error::call_stack), "call_stack"} }
);
*/
m->add(chaiscript::user_type<chaiscript::File_Position>(), "File_Position");
m->add(chaiscript::constructor<File_Position()>(), "File_Position");
m->add(chaiscript::constructor<File_Position(int, int)>(), "File_Position");
m->add(chaiscript::fun(&File_Position::line), "line");
m->add(chaiscript::fun(&File_Position::column), "column");
/*
chaiscript::utility::add_class<chaiscript::File_Position>(*m,
"File_Position",
{ constructor<File_Position()>(),
@ -77,28 +89,47 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
{ {fun(&File_Position::line), "line"},
{fun(&File_Position::column), "column"} }
);
*/
m->add(chaiscript::user_type<AST_Node>(), "AST_Node");
m->add(chaiscript::fun(&AST_Node::text), "text");
m->add(chaiscript::fun(&AST_Node::identifier), "identifier");
m->add(chaiscript::fun(&AST_Node::filename), "filename");
m->add(chaiscript::fun(&AST_Node::start), "start");
m->add(chaiscript::fun(&AST_Node::end), "end");
m->add(chaiscript::fun(&AST_Node::internal_to_string), "internal_to_string");
m->add(chaiscript::fun(&AST_Node::children), "children");
m->add(chaiscript::fun(&AST_Node::replace_child), "replace_child");
/*
chaiscript::utility::add_class<AST_Node>(*m,
"AST_Node",
{ },
{ {fun(&AST_Node::text), "text"},
{fun(&AST_Node::identifier), "identifier"},
{fun(&AST_Node::filename), "filename"},
{fun(&AST_Node::start), "start"},
{fun(&AST_Node::end), "end"},
{fun(&AST_Node::internal_to_string), "internal_to_string"},
{fun(&AST_Node::children), "children"},
{fun(&AST_Node::replace_child), "replace_child"}
}
);
"AST_Node",
{ },
{ {fun(&AST_Node::text), "text"},
{fun(&AST_Node::identifier), "identifier"},
{fun(&AST_Node::filename), "filename"},
{fun(&AST_Node::start), "start"},
{fun(&AST_Node::end), "end"},
{fun(&AST_Node::internal_to_string), "internal_to_string"},
{fun(&AST_Node::children), "children"},
{fun(&AST_Node::replace_child), "replace_child"}
}
);
*/
m->add(chaiscript::user_type<parser::ChaiScript_Parser>(), "ChaiScript_Parser");
m->add(chaiscript::constructor<parser::ChaiScript_Parser()>(), "ChaiScript_Parser");
m->add(chaiscript::fun(&parser::ChaiScript_Parser::parse), "parse");
m->add(chaiscript::fun(&parser::ChaiScript_Parser::ast), "ast");
/*
chaiscript::utility::add_class<parser::ChaiScript_Parser>(*m,
"ChaiScript_Parser",
{ constructor<parser::ChaiScript_Parser ()>() },
{ {fun(&parser::ChaiScript_Parser::parse), "parse"},
{fun(&parser::ChaiScript_Parser::ast), "ast"} }
);
*/
return m;

View File

@ -40,7 +40,10 @@ void do_work(chaiscript::ChaiScript &c, int id)
int main()
{
// Disable deprecation warning for getenv call.
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#ifdef max // Why microsoft? why?
#undef max
#endif
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
@ -48,7 +51,7 @@ int main()
const char *usepath = getenv("CHAI_USE_PATH");
const char *modulepath = getenv("CHAI_MODULE_PATH");
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@ -29,12 +29,19 @@ int main()
{
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
/*
chaiscript::utility::add_class<Test>(*m,
"Test",
{ chaiscript::constructor<Test ()>(),
chaiscript::constructor<Test (const Test &)>() },
{ {chaiscript::fun(&Test::count), "count"} }
);
*/
m->add(chaiscript::user_type<Test>(), "Test");
m->add(chaiscript::constructor<Test()>(), "Test");
m->add(chaiscript::constructor<Test(const Test &)>(), "Test");
m->add(chaiscript::fun(&Test::count), "count");
chaiscript::ChaiScript chai;
chai.add(m);

View File

@ -1,5 +1,6 @@
// Tests to make sure that the order in which function dispatches occur is correct
#include <chaiscript/chaiscript_defines.hpp>
#include <chaiscript/dispatchkit/type_info.hpp>
#include <cstdlib>