From b41c0f432b9a48288406a3b177caea3ee5023b81 Mon Sep 17 00:00:00 2001 From: Luis Finke Date: Fri, 24 Oct 2014 17:41:33 -0400 Subject: [PATCH 01/36] Added (optional) protection against divide by zero exceptions defining the preprocessor CHAISCRIPT_PROTECT_DIVIDEBYZERO adds checking of right side values before division arithmetic, allowing the user to safely catch a divide by zero error, rather than dealing with a SIGFPE and having the entire program exit without a choice --- .../chaiscript/dispatchkit/boxed_number.hpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index f3d2838..74de1e5 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -22,6 +22,22 @@ namespace chaiscript { class Dynamic_Cast_Conversions; } // namespace chaiscript +namespace chaiscript +{ + namespace exception + { + struct arithmetic_error : public std::runtime_error + { + std::string reason; + + arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + virtual ~arithmetic_error() {} + }; +#define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); + } +} + namespace chaiscript { @@ -89,6 +105,9 @@ namespace chaiscript t += u; break; case Operators::assign_quotient: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif t /= u; break; case Operators::assign_difference: @@ -122,6 +141,9 @@ namespace chaiscript t >>= u; break; case Operators::assign_remainder: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif t %= u; break; case Operators::assign_bitwise_xor: @@ -146,6 +168,9 @@ namespace chaiscript case Operators::shift_right: return const_var(t >> u); case Operators::remainder: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif return const_var(t % u); case Operators::bitwise_and: return const_var(t & u); @@ -171,6 +196,9 @@ namespace chaiscript case Operators::sum: return const_var(t + u); case Operators::quotient: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif return const_var(t / u); case Operators::product: return const_var(t * u); From e61612e4161a5a7e9aa0b2bd3b0c67b765d3f3be Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 6 Jan 2015 13:35:52 -0700 Subject: [PATCH 02/36] Fix Doxygen configuration --- Doxyfile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile.in b/Doxyfile.in index 7f3402e..5c06893 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -40,7 +40,7 @@ PROJECT_NUMBER = ${CHAI_VERSION} # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = ${CMAKE_BINARY_DIR}/docs +PROJECT_BRIEF = "An easy to use embedded scripting language for C++." # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not From 52d03a66b15358e8fd2caeb5b063044c8aa839d2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 6 Jan 2015 14:41:36 -0700 Subject: [PATCH 03/36] Add future support, and fix returning of r-values --- include/chaiscript/chaiscript_stdlib.hpp | 10 ++++++++++ .../chaiscript/dispatchkit/bootstrap_stl.hpp | 19 +++++++++++++++++++ .../chaiscript/dispatchkit/handle_return.hpp | 5 +++++ unittests/future.chai | 17 +++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 unittests/future.chai diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp index 8d4986a..92483fd 100644 --- a/include/chaiscript/chaiscript_stdlib.hpp +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -19,6 +19,11 @@ #include "dispatchkit/bootstrap_stl.hpp" #include "dispatchkit/boxed_value.hpp" +#ifndef CHAISCRIPT_NO_THREADS +#include +#endif + + /// @file /// /// This file generates the standard library that normal ChaiScript usage requires. @@ -40,6 +45,11 @@ namespace chaiscript lib->add(standard_library::map_type >("Map")); lib->add(standard_library::pair_type >("Pair")); +#ifndef CHAISCRIPT_NO_THREADS + lib->add(standard_library::future_type>("future")); + lib->add(chaiscript::fun (const std::function &)>([](const std::function &t_func){ return std::async(std::launch::async, t_func);}), "async"); +#endif + return lib; } diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index acb8344..b3be6fc 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -564,6 +564,25 @@ namespace chaiscript return m; } + + + + /// Add a MapType container + /// http://www.sgi.com/tech/stl/Map.html + template + ModulePtr future_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type); + + m->add(fun(&FutureType::valid), "valid"); + m->add(fun(&FutureType::get), "get"); + m->add(fun(&FutureType::wait), "wait"); + + return m; + } + + + } } } diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 8f2ebfe..cb1c977 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -37,6 +37,11 @@ namespace chaiscript { return const_var(r); } + + static Boxed_Value handle(Ret &&r) + { + return Boxed_Value(std::move(r)); + } }; template diff --git a/unittests/future.chai b/unittests/future.chai new file mode 100644 index 0000000..afb9afe --- /dev/null +++ b/unittests/future.chai @@ -0,0 +1,17 @@ +var func = fun(){ + var ret = 0; + for (var i = 0; i < 1000000; ++i) { + ret += i; + } + return ret; +} + + +var fut1 := async(func); +var fut2 := async(func); +var fut3 := async(func); +var fut4 := async(func); + +// simply executing without crashing is good enough for this test + +print(" ${fut1.get()} ${fut2.get()} ${fut3.get()} ${fut4.get()}") From d91294b989482583d07e1af9350c0edc274dd31f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 7 Jan 2015 13:56:48 -0700 Subject: [PATCH 04/36] Add warning for c-style casts to gcc --- CMakeLists.txt | 2 +- include/chaiscript/language/chaiscript_engine.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a692ee6..034fb5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ if(MSVC) # how to workaround or fix the error. So I'm disabling it globally. add_definitions(/wd4503) else() - add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic ${CPP11_FLAG}) + add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -pedantic ${CPP11_FLAG}) if(APPLE) add_definitions(-Wno-sign-compare) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 523f49f..71ac325 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -464,7 +464,7 @@ namespace chaiscript memset( &rInfo, 0, sizeof(rInfo) ); cast_union u; u.in_ptr = &ChaiScript::use; - if ( dladdr((void*)(u.out_ptr), &rInfo) && rInfo.dli_fname ) { + if ( dladdr(static_cast(u.out_ptr), &rInfo) && rInfo.dli_fname ) { std::string dllpath(rInfo.dli_fname); const size_t lastslash = dllpath.rfind('/'); if (lastslash != std::string::npos) From 2e02273673ffd60004f29517b212aec248668479 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 10:40:20 -0700 Subject: [PATCH 05/36] Add .bundle to module search extensions --- include/chaiscript/language/chaiscript_engine.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 71ac325..47e68fd 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -706,7 +706,7 @@ namespace chaiscript /// \param[in] t_module_name Name of the module to load /// /// The module is searched for in the registered module path folders (chaiscript::ChaiScript::ChaiScript) - /// and with standard prefixes and postfixes: ("lib"|"")\(".dll"|".so"|""). + /// and with standard prefixes and postfixes: ("lib"|"")\(".dll"|".so"|".bundle"|""). /// /// Once the file is located, the system looks for the symbol "create_chaiscript_module_\". /// If no file can be found matching the search criteria and containing the appropriate entry point @@ -725,7 +725,7 @@ namespace chaiscript std::vector prefixes{"lib", "cyg", ""}; - std::vector postfixes{".dll", ".so", ""}; + std::vector postfixes{".dll", ".so", ".bundle", ""}; for (auto & elem : m_modulepaths) { From 12533ce3e11342af0dee9fdc7709b4199e37b289 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 16:14:47 -0700 Subject: [PATCH 06/36] Add note about State tracking of Type_Conversions --- include/chaiscript/language/chaiscript_engine.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 47e68fd..7fa4dd6 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -581,6 +581,8 @@ namespace chaiscript } /// \brief Represents the current state of the ChaiScript system. State and be saved and restored + /// \warning State object does not contain the user defined type conversions of the engine. They + /// are left out due to performance considerations involved in tracking the state /// \sa ChaiScript::get_state /// \sa ChaiScript::set_state struct State From de0948935545195d177dc771a5d33b8d8dde36f4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:02:56 -0700 Subject: [PATCH 07/36] Fix formatting (tabs vs spaces) in divide/0 protection --- .../chaiscript/dispatchkit/boxed_number.hpp | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index ed74855..1eefcc9 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -24,18 +24,18 @@ class Type_Conversions; namespace chaiscript { - namespace exception - { - struct arithmetic_error : public std::runtime_error - { - std::string reason; + namespace exception + { + struct arithmetic_error : public std::runtime_error + { + std::string reason; - arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} - arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} - virtual ~arithmetic_error() {} - }; + arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + virtual ~arithmetic_error() {} + }; #define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); - } + } } namespace chaiscript @@ -105,10 +105,10 @@ namespace chaiscript t += u; break; case Operators::assign_quotient: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif - t /= u; +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif + t /= u; break; case Operators::assign_difference: t -= u; @@ -141,9 +141,9 @@ namespace chaiscript t >>= u; break; case Operators::assign_remainder: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif t %= u; break; case Operators::assign_bitwise_xor: @@ -168,10 +168,10 @@ namespace chaiscript case Operators::shift_right: return const_var(t >> u); case Operators::remainder: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif - return const_var(t % u); +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif + return const_var(t % u); case Operators::bitwise_and: return const_var(t & u); case Operators::bitwise_or: @@ -196,10 +196,10 @@ namespace chaiscript case Operators::sum: return const_var(t + u); case Operators::quotient: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif - return const_var(t / u); +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif + return const_var(t / u); case Operators::product: return const_var(t * u); case Operators::difference: From 1a4dec0df070de2ce9e6297a9f859da64fc5ba3d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:06:08 -0700 Subject: [PATCH 08/36] Remove redundant/unnecessary constructors and object copies. --- include/chaiscript/dispatchkit/boxed_number.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 1eefcc9..16022ca 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -28,10 +28,7 @@ namespace chaiscript { struct arithmetic_error : public std::runtime_error { - std::string reason; - - arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} - arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {} virtual ~arithmetic_error() {} }; #define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); From 0695eec3caf108756fc615596f48b9c8a6c73c33 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:30:28 -0700 Subject: [PATCH 09/36] Limit scope of #ifdefs, remove macros Macros do not fit within the ChaiScript coding standards because they do not respect namespaces and are more difficult to debug of something goes wrong. --- .../chaiscript/dispatchkit/boxed_number.hpp | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 16022ca..87d0cb3 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -31,7 +31,6 @@ namespace chaiscript arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {} virtual ~arithmetic_error() {} }; -#define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); } } @@ -50,6 +49,19 @@ namespace chaiscript class Boxed_Number { private: +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + template + static void check_divide_by_zero(T t) + { + if(std::is_arithmetic::value) if(t==0) throw chaiscript::exception::arithmetic_error("divide by zero"); + } +#else + template + static void check_divide_by_zero(T) + { + } +#endif + struct boolean { @@ -74,7 +86,7 @@ namespace chaiscript case Operators::not_equal: return const_var(t != u); default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -102,16 +114,14 @@ namespace chaiscript t += u; break; case Operators::assign_quotient: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif - t /= u; + check_divide_by_zero(u); + t /= u; break; case Operators::assign_difference: t -= u; break; default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } return t_lhs; @@ -138,16 +148,14 @@ namespace chaiscript t >>= u; break; case Operators::assign_remainder: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif + check_divide_by_zero(u); t %= u; break; case Operators::assign_bitwise_xor: t ^= u; break; default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } return t_lhs; } @@ -165,10 +173,8 @@ namespace chaiscript case Operators::shift_right: return const_var(t >> u); case Operators::remainder: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif - return const_var(t % u); + check_divide_by_zero(u); + return const_var(t % u); case Operators::bitwise_and: return const_var(t & u); case Operators::bitwise_or: @@ -178,7 +184,7 @@ namespace chaiscript case Operators::bitwise_complement: return const_var(~t); default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -193,10 +199,8 @@ namespace chaiscript case Operators::sum: return const_var(t + u); case Operators::quotient: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif - return const_var(t / u); + check_divide_by_zero(u); + return const_var(t / u); case Operators::product: return const_var(t * u); case Operators::difference: @@ -206,7 +210,7 @@ namespace chaiscript case Operators::unary_plus: return const_var(+t); default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -352,7 +356,6 @@ namespace chaiscript return oss.str(); } - public: Boxed_Number() : bv(Boxed_Value(0)) @@ -868,12 +871,12 @@ namespace chaiscript struct Cast_Helper : Cast_Helper { }; - + /// Cast_Helper for converting from Boxed_Value to Boxed_Number template<> struct Cast_Helper : Cast_Helper { - }; + }; } #ifdef CHAISCRIPT_MSVC From 8746a9eea52e805f47f48d3679ca72077d284e40 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:38:27 -0700 Subject: [PATCH 10/36] Make divide by zero protection the default --- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 87d0cb3..69cfefa 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -49,7 +49,7 @@ namespace chaiscript class Boxed_Number { private: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO +#ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO template static void check_divide_by_zero(T t) { From 25b15a3449c39589855eb10a134e664082600902 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:06:04 -0700 Subject: [PATCH 11/36] Only apply divide by zero protection to integers Also allow arithmetic error to bubble up to the caller. --- include/chaiscript/dispatchkit/bootstrap.hpp | 10 +++++++--- include/chaiscript/dispatchkit/boxed_number.hpp | 4 +++- include/chaiscript/language/chaiscript_eval.hpp | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 3e88daf..579b6ee 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -396,10 +396,9 @@ namespace chaiscript m->add(user_type(), "runtime_error"); m->add(chaiscript::base_class()); - m->add(constructor(), "runtime_error"); - m->add(fun(std::function(&what)), "what"); + m->add(fun(std::function(&what)), "what"); m->add(user_type(), "Dynamic_Object"); m->add(constructor(), "Dynamic_Object"); @@ -487,7 +486,12 @@ 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::base_class()); + m->add(chaiscript::user_type("eval_error")); + m->add(chaiscript::base_class()); + + m->add(chaiscript::user_type("arithmetic_error")); + m->add(chaiscript::base_class()); + // chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 69cfefa..150e76c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -53,7 +53,9 @@ namespace chaiscript template static void check_divide_by_zero(T t) { - if(std::is_arithmetic::value) if(t==0) throw chaiscript::exception::arithmetic_error("divide by zero"); + if(std::is_integral::value && std::is_arithmetic::value && t==0) { + throw chaiscript::exception::arithmetic_error("divide by zero"); + } } #else template diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index be9aabc..eafb84b 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -93,6 +93,8 @@ namespace chaiscript // If it's an arithmetic operation we want to short circuit dispatch try{ return Boxed_Number::do_oper(t_oper, t_lhs, t_rhs); + } catch (const chaiscript::exception::arithmetic_error &) { + throw; } catch (...) { throw exception::eval_error("Error with numeric operator calling: " + t_oper_string); } From 576816e3b11d6fb04f09fa810144a0c418454c62 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:17:20 -0700 Subject: [PATCH 12/36] Add unit test for divide by zero protection --- include/chaiscript/dispatchkit/bootstrap.hpp | 4 ++-- unittests/divide_by_zero_protection.chai | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 unittests/divide_by_zero_protection.chai diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 579b6ee..dd1f880 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -486,10 +486,10 @@ 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("eval_error")); + m->add(chaiscript::user_type(), "eval_error"); m->add(chaiscript::base_class()); - m->add(chaiscript::user_type("arithmetic_error")); + m->add(chaiscript::user_type(), "arithmetic_error"); m->add(chaiscript::base_class()); diff --git a/unittests/divide_by_zero_protection.chai b/unittests/divide_by_zero_protection.chai new file mode 100644 index 0000000..ba40a43 --- /dev/null +++ b/unittests/divide_by_zero_protection.chai @@ -0,0 +1,7 @@ +try { + 3/0 + assert_true(false); // should never get here +} catch (e) { + assert_equal("Arithmetic error: divide by zero", e.what()) +} + From 420ba68b94a23fb4b02a7aa8bd6e3d433e22ce54 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:20:38 -0700 Subject: [PATCH 13/36] Make sure floating point returns Infinity --- unittests/divide_by_zero_protection.chai | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unittests/divide_by_zero_protection.chai b/unittests/divide_by_zero_protection.chai index ba40a43..db648fc 100644 --- a/unittests/divide_by_zero_protection.chai +++ b/unittests/divide_by_zero_protection.chai @@ -5,3 +5,5 @@ try { assert_equal("Arithmetic error: divide by zero", e.what()) } +assert_equal(3/0.0, Infinity) + From 2f90b3ae6bec2b77f1f9d7bf98212c001230305c Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:31:40 -0700 Subject: [PATCH 14/36] Correct exception specifier for arithmetic_error --- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 150e76c..6000468 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -29,7 +29,7 @@ namespace chaiscript struct arithmetic_error : public std::runtime_error { arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {} - virtual ~arithmetic_error() {} + virtual ~arithmetic_error() CHAISCRIPT_NOEXCEPT {} }; } } From 9b3bb493e9df44c1abd4a6dc609899f502ace8ec Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 10 Jan 2015 07:18:10 -0700 Subject: [PATCH 15/36] Clean up some MSVC warnings --- include/chaiscript/dispatchkit/boxed_number.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 6000468..c00911c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -53,9 +53,21 @@ namespace chaiscript template static void check_divide_by_zero(T t) { + +#ifdef CHAISCRIPT_MSVC + // MSVC complains that this expression is both constant and the value t is unused + // in the cases of integral expressions. Seems a bit overzealous to me, the parameter + // is only unreferenced because they are eliminating the dead code. +#pragma warning(push) +#pragma warning(disable : 4100 4127) +#endif if(std::is_integral::value && std::is_arithmetic::value && t==0) { throw chaiscript::exception::arithmetic_error("divide by zero"); } +#ifdef CHAISCRIPT_MSVC +#pragma warning(pop) +#endif + } #else template From 31ef683cedd35fb0ff10094f7c7649b97832b86d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 12 Jan 2015 10:06:42 -0700 Subject: [PATCH 16/36] Use SFINAE to clean up divide by zero protection --- .../chaiscript/dispatchkit/boxed_number.hpp | 22 +++++-------------- unittests/future.chai | 6 ++--- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index c00911c..a0ad6aa 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -49,32 +49,20 @@ namespace chaiscript class Boxed_Number { private: -#ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO template - static void check_divide_by_zero(T t) + static void check_divide_by_zero(T t, typename std::enable_if::value>::type* = 0) { - -#ifdef CHAISCRIPT_MSVC - // MSVC complains that this expression is both constant and the value t is unused - // in the cases of integral expressions. Seems a bit overzealous to me, the parameter - // is only unreferenced because they are eliminating the dead code. -#pragma warning(push) -#pragma warning(disable : 4100 4127) -#endif - if(std::is_integral::value && std::is_arithmetic::value && t==0) { +#ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO + if (t == 0) { throw chaiscript::exception::arithmetic_error("divide by zero"); } -#ifdef CHAISCRIPT_MSVC -#pragma warning(pop) #endif - } -#else + template - static void check_divide_by_zero(T) + static void check_divide_by_zero(T, typename std::enable_if::value>::type* = 0) { } -#endif struct boolean { diff --git a/unittests/future.chai b/unittests/future.chai index afb9afe..750c27d 100644 --- a/unittests/future.chai +++ b/unittests/future.chai @@ -1,6 +1,6 @@ var func = fun(){ var ret = 0; - for (var i = 0; i < 1000000; ++i) { + for (var i = 0; i < 50000; ++i) { ret += i; } return ret; @@ -9,9 +9,7 @@ var func = fun(){ var fut1 := async(func); var fut2 := async(func); -var fut3 := async(func); -var fut4 := async(func); // simply executing without crashing is good enough for this test -print(" ${fut1.get()} ${fut2.get()} ${fut3.get()} ${fut4.get()}") +print(" ${fut1.get()} ${fut2.get()} ") From 4761a68d06320bfbb8ad5d5d9d017db45a2960eb Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 11:24:40 -0700 Subject: [PATCH 17/36] Enable optional typing of function params --- .../chaiscript/dispatchkit/dynamic_object.hpp | 212 ------------------ .../dispatchkit/proxy_constructors.hpp | 2 + .../dispatchkit/proxy_functions.hpp | 112 ++++++++- .../chaiscript/language/chaiscript_common.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 106 +++++++-- .../chaiscript/language/chaiscript_parser.hpp | 50 ++++- 6 files changed, 240 insertions(+), 246 deletions(-) diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 69c24d5..d90fe1b 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -19,7 +19,6 @@ #include "boxed_cast.hpp" #include "boxed_cast_helper.hpp" #include "boxed_value.hpp" -#include "proxy_functions.hpp" #include "type_info.hpp" namespace chaiscript { @@ -62,217 +61,6 @@ namespace chaiscript std::map m_attrs; }; - namespace detail - { - /// A Proxy_Function implementation designed for calling a function - /// that is automatically guarded based on the first param based on the - /// param's type name - class Dynamic_Object_Function : public Proxy_Function_Base - { - public: - Dynamic_Object_Function( - std::string t_type_name, - const Proxy_Function &t_func) - : Proxy_Function_Base(t_func->get_param_types(), t_func->get_arity()), - m_type_name(std::move(t_type_name)), m_func(t_func), m_doti(user_type()) - { - assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) - && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); - } - - Dynamic_Object_Function( - std::string t_type_name, - 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()) - { - assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) - && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); - } - - virtual ~Dynamic_Object_Function() {} - - Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete; - Dynamic_Object_Function(Dynamic_Object_Function &) = delete; - - virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE - { - if (const auto *df = dynamic_cast(&f)) - { - return df->m_type_name == m_type_name && (*df->m_func) == (*m_func); - } else { - return false; - } - } - - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE - { - if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions)) - { - return m_func->call_match(vals, t_conversions); - } else { - return false; - } - } - - virtual std::vector get_contained_functions() const CHAISCRIPT_OVERRIDE - { - return {m_func}; - } - - virtual std::string annotation() const CHAISCRIPT_OVERRIDE - { - return m_func->annotation(); - } - - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE - { - if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions)) - { - return (*m_func)(params, t_conversions); - } else { - throw exception::guard_error(); - } - } - - virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE - { - return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions); - } - - private: - static std::vector build_param_types( - const std::vector &t_inner_types, const Type_Info& t_objectti) - { - std::vector types(t_inner_types); - - assert(types.size() > 1); - assert(types[1].bare_equal(user_type())); - types[1] = t_objectti; - return types; - } - - bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, - const std::unique_ptr &ti, const Type_Conversions &t_conversions) const - { - if (bv.get_type_info().bare_equal(m_doti)) - { - try { - const Dynamic_Object &d = boxed_cast(bv, &t_conversions); - return name == "Dynamic_Object" || d.get_type_name() == name; - } catch (const std::bad_cast &) { - return false; - } - } else { - if (ti) - { - return bv.get_type_info().bare_equal(*ti); - } else { - return false; - } - } - - } - - bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, - const std::unique_ptr &ti, const Type_Conversions &t_conversions) const - { - if (bvs.size() > 0) - { - return dynamic_object_typename_match(bvs[0], name, ti, t_conversions); - } else { - return false; - } - } - - std::string m_type_name; - Proxy_Function m_func; - std::unique_ptr m_ti; - const Type_Info m_doti; - - - }; - - - /** - * A Proxy_Function implementation designed for creating a new - * Dynamic_Object - * that is automatically guarded based on the first param based on the - * param's type name - */ - class Dynamic_Object_Constructor : public Proxy_Function_Base - { - public: - Dynamic_Object_Constructor( - std::string t_type_name, - const Proxy_Function &t_func) - : Proxy_Function_Base(build_type_list(t_func->get_param_types()), t_func->get_arity() - 1), - m_type_name(std::move(t_type_name)), m_func(t_func) - { - assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) - && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); - } - - static std::vector build_type_list(const std::vector &tl) - { - auto begin = tl.begin(); - auto end = tl.end(); - - if (begin != end) - { - ++begin; - } - - return std::vector(begin, end); - } - - virtual ~Dynamic_Object_Constructor() {} - - virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE - { - const Dynamic_Object_Constructor *dc = dynamic_cast(&f); - if (dc) - { - return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); - } else { - return false; - } - } - - virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE - { - std::vector new_vals{Boxed_Value(Dynamic_Object(m_type_name))}; - new_vals.insert(new_vals.end(), vals.begin(), vals.end()); - - return m_func->call_match(new_vals, t_conversions); - } - - virtual std::string annotation() const CHAISCRIPT_OVERRIDE - { - return m_func->annotation(); - } - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE - { - auto bv = var(Dynamic_Object(m_type_name)); - std::vector new_params{bv}; - new_params.insert(new_params.end(), params.begin(), params.end()); - - (*m_func)(new_params, t_conversions); - - return bv; - } - - private: - std::string m_type_name; - Proxy_Function m_func; - - }; - } } } #endif diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index 64d2a93..291fa43 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -8,6 +8,8 @@ #ifndef CHAISCRIPT_PROXY_CONSTRUCTORS_HPP_ #define CHAISCRIPT_PROXY_CONSTRUCTORS_HPP_ +#include "proxy_functions.hpp" + namespace chaiscript { namespace dispatch diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index fba9b4f..1c7cea2 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -24,6 +24,7 @@ #include "boxed_value.hpp" #include "proxy_functions_detail.hpp" #include "type_info.hpp" +#include "dynamic_object.hpp" namespace chaiscript { class Type_Conversions; @@ -42,6 +43,91 @@ namespace chaiscript namespace dispatch { + class Param_Types + { + public: + Param_Types() + {} + + Param_Types(std::vector> t_types) + : m_types(std::move(t_types)) + { + update_has_types(); + } + + void push_front(std::string t_name, Type_Info t_ti) + { + m_types.emplace(m_types.begin(), std::move(t_name), std::move(t_ti)); + update_has_types(); + } + + bool operator==(const Param_Types &t_rhs) const + { + return m_types == t_rhs.m_types; + } + + bool match(const std::vector &vals, const Type_Conversions &t_conversions) const + { + if (!m_has_types) return true; + if (vals.size() != m_types.size()) return false; + + for (size_t i = 0; i < vals.size(); ++i) + { + const auto &name = m_types[i].first; + if (!name.empty()) { + const auto &bv = vals[i]; + + if (bv.get_type_info().bare_equal(m_doti)) + { + try { + const Dynamic_Object &d = boxed_cast(bv, &t_conversions); + return name == "Dynamic_Object" || d.get_type_name() == name; + } catch (const std::bad_cast &) { + return false; + } + } else { + const auto &ti = m_types[i].second; + if (!ti.is_undef()) + { + if (!bv.get_type_info().bare_equal(ti)) { + return false; + } + } else { + return false; + } + } + } + } + + return true; + } + + const std::vector> &types() const + { + return m_types; + } + + private: + void update_has_types() + { + for (const auto &type : m_types) + { + if (!type.first.empty()) + { + m_has_types = true; + return; + } + } + + m_has_types = false; + } + + std::vector> m_types; + bool m_has_types = false; + Type_Info m_doti = user_type(); + + }; + /** * Pure virtual base class for all Proxy_Function implementations * Proxy_Functions are a type erasure of type safe C++ @@ -215,10 +301,12 @@ namespace chaiscript std::function &)> t_f, int t_arity=-1, AST_NodePtr t_parsenode = AST_NodePtr(), + Param_Types t_param_types = Param_Types(), std::string t_description = "", Proxy_Function t_guard = Proxy_Function()) - : Proxy_Function_Base(build_param_type_list(t_arity), t_arity), - m_f(std::move(t_f)), m_arity(t_arity), m_description(std::move(t_description)), m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)) + : Proxy_Function_Base(build_param_type_list(t_param_types), t_arity), + m_f(std::move(t_f)), m_arity(t_arity), m_param_types(std::move(t_param_types)), + m_description(std::move(t_description)), m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)) { } @@ -231,14 +319,15 @@ namespace chaiscript return this == &rhs || (prhs && this->m_arity == prhs->m_arity - && !this->m_guard && !prhs->m_guard); + && !this->m_guard && !prhs->m_guard + && this->m_param_types == prhs->m_param_types); } virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - return (m_arity < 0 || vals.size() == size_t(m_arity)) + return (m_arity < 0 || (vals.size() == size_t(m_arity) && m_param_types.match(vals, t_conversions))) && test_guard(vals, t_conversions); - } + } Proxy_Function get_guard() const @@ -261,8 +350,7 @@ namespace chaiscript { if (m_arity < 0 || params.size() == size_t(m_arity)) { - - if (test_guard(params, t_conversions)) + if (call_match(params, t_conversions) && test_guard(params, t_conversions)) { return m_f(params); } else { @@ -291,18 +379,19 @@ namespace chaiscript } } - static std::vector build_param_type_list(int arity) + static std::vector build_param_type_list(const Param_Types &t_types) { std::vector types; // For the return type types.push_back(chaiscript::detail::Get_Type_Info::get()); - if (arity > 0) + for (const auto &t : t_types.types()) { - for (int i = 0; i < arity; ++i) - { + if (t.second.is_undef()) { types.push_back(chaiscript::detail::Get_Type_Info::get()); + } else { + types.push_back(t.second); } } @@ -311,6 +400,7 @@ namespace chaiscript std::function &)> m_f; int m_arity; + Param_Types m_param_types; std::string m_description; Proxy_Function m_guard; AST_NodePtr m_parsenode; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 288b0cc..c784505 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -37,7 +37,7 @@ namespace chaiscript Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, - Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary + Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg }; }; @@ -50,7 +50,7 @@ namespace chaiscript "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", - "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary"}; + "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg"}; return ast_node_types[ast_node_type]; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index be9aabc..6323a6e 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -25,6 +25,7 @@ #include "../dispatchkit/boxed_number.hpp" #include "../dispatchkit/boxed_value.hpp" #include "../dispatchkit/dispatchkit.hpp" +#include "../dispatchkit/dynamic_object_detail.hpp" #include "../dispatchkit/proxy_functions.hpp" #include "../dispatchkit/proxy_functions_detail.hpp" #include "../dispatchkit/register_function.hpp" @@ -349,6 +350,28 @@ namespace chaiscript }; + struct Arg_AST_Node : public AST_Node { + public: + Arg_AST_Node(std::string t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + AST_Node(std::move(t_ast_node_text), AST_Node_Type::Arg_List, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } + virtual ~Arg_AST_Node() {} + + virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE + { + std::ostringstream oss; + for (size_t j = 0; j < this->children.size(); ++j) { + if (j != 0) + { + oss << " "; + } + + oss << this->children[j]->pretty_print(); + } + + return oss.str(); + } + }; + struct Arg_List_AST_Node : public AST_Node { public: Arg_List_AST_Node(std::string t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : @@ -369,6 +392,46 @@ namespace chaiscript return oss.str(); } + + static std::vector get_arg_names(const AST_NodePtr &t_node) { + std::vector retval; + + for (const auto &child : t_node->children) + { + if (child->children.empty()) + { + retval.push_back(child->text); + } else if (child->children.size() == 1) { + retval.push_back(child->children[0]->text); + } else { + retval.push_back(child->children[1]->text); + } + } + + return retval; + } + + static dispatch::Param_Types get_arg_types(const AST_NodePtr &t_node, chaiscript::detail::Dispatch_Engine &t_ss) { + std::vector> retval; + + for (const auto &child : t_node->children) + { + if (child->children.empty()) + { + retval.emplace_back("", Type_Info()); + } else if (child->children.size() == 1) { + retval.emplace_back("", Type_Info()); + } else { + try { + retval.emplace_back(child->children[0]->text, t_ss.get_type(child->children[0]->text)); + } catch (const std::range_error &t_err) { + retval.emplace_back(child->children[0]->text, Type_Info()); + } + } + } + + return dispatch::Param_Types(std::move(retval)); + } }; struct Equation_AST_Node : public AST_Node { @@ -636,13 +699,12 @@ namespace chaiscript size_t numparams = 0; + dispatch::Param_Types param_types; + if (!this->children.empty() && (this->children[0]->identifier == AST_Node_Type::Arg_List)) { numparams = this->children[0]->children.size(); - - for (const auto &child : this->children[0]->children) - { - t_param_names.push_back(child->text); - } + t_param_names = Arg_List_AST_Node::get_arg_names(this->children[0]); + param_types = Arg_List_AST_Node::get_arg_types(this->children[0], t_ss); } const auto &lambda_node = this->children.back(); @@ -652,7 +714,7 @@ namespace chaiscript { return detail::eval_function(t_ss, lambda_node, t_param_names, t_params); }, - static_cast(numparams), lambda_node))); + static_cast(numparams), lambda_node, param_types))); } }; @@ -696,13 +758,12 @@ namespace chaiscript size_t numparams = 0; AST_NodePtr guardnode; + dispatch::Param_Types param_types; + if ((this->children.size() > 2) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { numparams = this->children[1]->children.size(); - - for (const auto &child : this->children[1]->children) - { - t_param_names.push_back(child->text); - } + t_param_names = Arg_List_AST_Node::get_arg_names(this->children[1]); + param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss); if (this->children.size() > 3) { guardnode = this->children[2]; @@ -735,7 +796,7 @@ namespace chaiscript { return detail::eval_function(t_ss, func_node, t_param_names, t_params); }, static_cast(numparams), this->children.back(), - l_annotation, guard)), l_function_name); + param_types, l_annotation, guard)), l_function_name); } catch (const exception::reserved_word_error &e) { throw exception::eval_error("Reserved word used as function name '" + e.word() + "'"); @@ -1341,11 +1402,12 @@ namespace chaiscript //The first param of a method is always the implied this ptr. std::vector t_param_names{"this"}; + dispatch::Param_Types param_types; if ((this->children.size() > static_cast(3 + class_offset)) && (this->children[(2 + class_offset)]->identifier == AST_Node_Type::Arg_List)) { - for (const auto &child : this->children[(2 + class_offset)]->children) { - t_param_names.push_back(child->text); - } + auto args = Arg_List_AST_Node::get_arg_names(this->children[(2 + class_offset)]); + t_param_names.insert(t_param_names.end(), args.begin(), args.end()); + param_types = Arg_List_AST_Node::get_arg_types(this->children[(2 + class_offset)], t_ss); if (this->children.size() > static_cast(4 + class_offset)) { guardnode = this->children[(3 + class_offset)]; @@ -1375,29 +1437,35 @@ namespace chaiscript const std::string & function_name = this->children[(1 + class_offset)]->text; if (function_name == class_name) { + param_types.push_front(class_name, Type_Info()); t_ss.add(std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), this->children.back(), t_param_names, std::placeholders::_1), - static_cast(numparams), this->children.back(), l_annotation, guard)), + static_cast(numparams), this->children.back(), param_types, l_annotation, guard)), function_name); } else { try { - // Do know type name + // 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); + t_ss.add( std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), this->children.back(), t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), - l_annotation, guard), t_ss.get_type(class_name)), function_name); + 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(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), this->children.back(), t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), - l_annotation, guard)), function_name); + param_types, l_annotation, guard)), function_name); } } } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index e9c40aa..de18959 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -699,6 +699,25 @@ namespace chaiscript } } + /// Reads an argument from input + bool Arg() { + const auto prev_stack_top = m_match_stack.size(); + SkipWS(); + + if (!Id(true)) { + return false; + } + + SkipWS(); + Id(true); + + build_match(std::make_shared(), prev_stack_top); + + return true; + } + + + /// Checks for a node annotation of the form "#" bool Annotation() { SkipWS(); @@ -1109,6 +1128,33 @@ namespace chaiscript } } + /// Reads a comma-separated list of values from input, for function declarations + bool Decl_Arg_List() { + SkipWS(true); + bool retval = false; + + const auto prev_stack_top = m_match_stack.size(); + + if (Arg()) { + retval = true; + while (Eol()) {} + if (Char(',')) { + do { + while (Eol()) {} + if (!Arg()) { + throw exception::eval_error("Unexpected value in parameter list", File_Position(m_line, m_col), *m_filename); + } + } while (Char(',')); + } + build_match(std::make_shared(), prev_stack_top); + } + + SkipWS(true); + + return retval; + } + + /// Reads a comma-separated list of values from input bool Arg_List() { SkipWS(true); @@ -1186,7 +1232,7 @@ namespace chaiscript retval = true; if (Char('(')) { - Arg_List(); + Decl_Arg_List(); if (!Char(')')) { throw exception::eval_error("Incomplete anonymous function", File_Position(m_line, m_col), *m_filename); } @@ -1236,7 +1282,7 @@ namespace chaiscript } if (Char('(')) { - Arg_List(); + Decl_Arg_List(); if (!Char(')')) { throw exception::eval_error("Incomplete function definition", File_Position(m_line, m_col), *m_filename); } From c1f47cbc1650f59d41f1e928e1f8d5b10f92386e Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 11:39:24 -0700 Subject: [PATCH 18/36] Update prelude to use new typed params --- .../chaiscript/language/chaiscript_prelude.chai | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/chaiscript/language/chaiscript_prelude.chai b/include/chaiscript/language/chaiscript_prelude.chai index b4c0bc4..1db8702 100644 --- a/include/chaiscript/language/chaiscript_prelude.chai +++ b/include/chaiscript/language/chaiscript_prelude.chai @@ -455,37 +455,37 @@ def zip(x, y) { # Returns the position of the second value string in the first value string -def string::find(substr) : is_type(substr, "string") { +def string::find(string substr) { find(this, substr, size_t(0)); } # Returns the position of last match of the second value string in the first value string -def string::rfind(substr) : is_type(substr, "string") { +def string::rfind(string substr) { rfind(this, substr, size_t(-1)); } # Returns the position of the first match of elements in the second value string in the first value string -def string::find_first_of(list) : is_type(list, "string") { +def string::find_first_of(string list) { find_first_of(this, list, size_t(0)); } # Returns the position of the last match of elements in the second value string in the first value string -def string::find_last_of(list) : is_type(list, "string") { +def string::find_last_of(string list) { find_last_of(this, list, size_t(-1)); } # Returns the position of the first non-matching element in the second value string in the first value string -def string::find_first_not_of(list) : is_type(list, "string") { +def string::find_first_not_of(string list) { find_first_not_of(this, list, size_t(0)); } # Returns the position of the last non-matching element in the second value string in the first value string -def string::find_last_not_of(list) : is_type(list, "string") { +def string::find_last_not_of(string list) { find_last_not_of(this, list, size_t(-1)); } @@ -505,7 +505,7 @@ def string::trim() { } -def find(container, value, compare_func) : call_exists(range, container) && is_type(compare_func, "Function") { +def find(container, value, Function compare_func) : call_exists(range, container) { auto range := range(container); while (!range.empty()) { if (compare_func(range.front(), value)) { From 3d1edbf38fa7fa85802abca4a6998144a12dedb8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 11:44:13 -0700 Subject: [PATCH 19/36] Add missing dynamic_object_detail --- .../dispatchkit/dynamic_object_detail.hpp | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 include/chaiscript/dispatchkit/dynamic_object_detail.hpp diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp new file mode 100644 index 0000000..5683404 --- /dev/null +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -0,0 +1,251 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_DYNAMIC_OBJECT_DETAIL_HPP_ +#define CHAISCRIPT_DYNAMIC_OBJECT_DETAIL_HPP_ + +#include +#include +#include +#include +#include +#include +#include + +#include "../chaiscript_defines.hpp" +#include "boxed_cast.hpp" +#include "boxed_cast_helper.hpp" +#include "boxed_value.hpp" +#include "proxy_functions.hpp" +#include "type_info.hpp" +#include "dynamic_object.hpp" + +namespace chaiscript { +class Type_Conversions; +namespace dispatch { +class Proxy_Function_Base; +} // namespace dispatch +} // namespace chaiscript + +namespace chaiscript +{ + namespace dispatch + { + namespace detail + { + /// A Proxy_Function implementation designed for calling a function + /// that is automatically guarded based on the first param based on the + /// param's type name + class Dynamic_Object_Function : public Proxy_Function_Base + { + public: + Dynamic_Object_Function( + std::string t_type_name, + const Proxy_Function &t_func) + : Proxy_Function_Base(t_func->get_param_types(), t_func->get_arity()), + m_type_name(std::move(t_type_name)), m_func(t_func), m_doti(user_type()) + { + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); + } + + Dynamic_Object_Function( + std::string t_type_name, + 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()) + { + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); + } + + virtual ~Dynamic_Object_Function() {} + + Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete; + Dynamic_Object_Function(Dynamic_Object_Function &) = delete; + + virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE + { + if (const auto *df = dynamic_cast(&f)) + { + return df->m_type_name == m_type_name && (*df->m_func) == (*m_func); + } else { + return false; + } + } + + virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + { + if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions)) + { + return m_func->call_match(vals, t_conversions); + } else { + return false; + } + } + + virtual std::vector get_contained_functions() const CHAISCRIPT_OVERRIDE + { + return {m_func}; + } + + virtual std::string annotation() const CHAISCRIPT_OVERRIDE + { + return m_func->annotation(); + } + + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + { + if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions)) + { + return (*m_func)(params, t_conversions); + } else { + throw exception::guard_error(); + } + } + + virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + { + return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions); + } + + private: + static std::vector build_param_types( + const std::vector &t_inner_types, const Type_Info& t_objectti) + { + std::vector types(t_inner_types); + + assert(types.size() > 1); + //assert(types[1].bare_equal(user_type())); + types[1] = t_objectti; + return types; + } + + bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, + const std::unique_ptr &ti, const Type_Conversions &t_conversions) const + { + if (bv.get_type_info().bare_equal(m_doti)) + { + try { + const Dynamic_Object &d = boxed_cast(bv, &t_conversions); + return name == "Dynamic_Object" || d.get_type_name() == name; + } catch (const std::bad_cast &) { + return false; + } + } else { + if (ti) + { + return bv.get_type_info().bare_equal(*ti); + } else { + return false; + } + } + + } + + bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, + const std::unique_ptr &ti, const Type_Conversions &t_conversions) const + { + if (bvs.size() > 0) + { + return dynamic_object_typename_match(bvs[0], name, ti, t_conversions); + } else { + return false; + } + } + + std::string m_type_name; + Proxy_Function m_func; + std::unique_ptr m_ti; + const Type_Info m_doti; + + + }; + + + /** + * A Proxy_Function implementation designed for creating a new + * Dynamic_Object + * that is automatically guarded based on the first param based on the + * param's type name + */ + class Dynamic_Object_Constructor : public Proxy_Function_Base + { + public: + Dynamic_Object_Constructor( + std::string t_type_name, + const Proxy_Function &t_func) + : Proxy_Function_Base(build_type_list(t_func->get_param_types()), t_func->get_arity() - 1), + m_type_name(std::move(t_type_name)), m_func(t_func) + { + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); + } + + static std::vector build_type_list(const std::vector &tl) + { + auto begin = tl.begin(); + auto end = tl.end(); + + if (begin != end) + { + ++begin; + } + + return std::vector(begin, end); + } + + virtual ~Dynamic_Object_Constructor() {} + + virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE + { + const Dynamic_Object_Constructor *dc = dynamic_cast(&f); + if (dc) + { + return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); + } else { + return false; + } + } + + virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + { + std::vector new_vals{Boxed_Value(Dynamic_Object(m_type_name))}; + new_vals.insert(new_vals.end(), vals.begin(), vals.end()); + + return m_func->call_match(new_vals, t_conversions); + } + + virtual std::string annotation() const CHAISCRIPT_OVERRIDE + { + return m_func->annotation(); + } + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE + { + auto bv = var(Dynamic_Object(m_type_name)); + std::vector new_params{bv}; + new_params.insert(new_params.end(), params.begin(), params.end()); + + (*m_func)(new_params, t_conversions); + + return bv; + } + + private: + std::string m_type_name; + Proxy_Function m_func; + + }; + } + } +} +#endif + From f66b4aafc175411b553363b151661c3d4306b745 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 11:58:23 -0700 Subject: [PATCH 20/36] Fix g++ 4.6 initializers --- include/chaiscript/dispatchkit/proxy_functions.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 1c7cea2..8556e13 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -47,10 +47,14 @@ namespace chaiscript { public: Param_Types() + : m_has_types(false), + m_doti(user_type()) {} Param_Types(std::vector> t_types) : m_types(std::move(t_types)) + : m_has_types(false), + m_doti(user_type()) { update_has_types(); } @@ -123,8 +127,8 @@ namespace chaiscript } std::vector> m_types; - bool m_has_types = false; - Type_Info m_doti = user_type(); + bool m_has_types; + Type_Info m_doti; }; From 3f23e57a3dd116420ad06517ce7fdaf891a29d23 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 12:07:08 -0700 Subject: [PATCH 21/36] Fix build error --- include/chaiscript/dispatchkit/proxy_functions.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 8556e13..6a0dc0e 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -52,8 +52,8 @@ namespace chaiscript {} Param_Types(std::vector> t_types) - : m_types(std::move(t_types)) - : m_has_types(false), + : m_types(std::move(t_types)), + m_has_types(false), m_doti(user_type()) { update_has_types(); From ef69e4a2f194374c693d51e21f144f96f79c6399 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 14:05:41 -0700 Subject: [PATCH 22/36] Allow typing of exception handlers --- .../chaiscript/language/chaiscript_eval.hpp | 206 ++++++++---------- .../chaiscript/language/chaiscript_parser.hpp | 2 +- 2 files changed, 96 insertions(+), 112 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 6323a6e..134a576 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -393,41 +393,48 @@ namespace chaiscript return oss.str(); } + static std::string get_arg_name(const AST_NodePtr &t_node) { + if (t_node->children.empty()) + { + return t_node->text; + } else if (t_node->children.size() == 1) { + return t_node->children[0]->text; + } else { + return t_node->children[1]->text; + } + } + static std::vector get_arg_names(const AST_NodePtr &t_node) { std::vector retval; - for (const auto &child : t_node->children) + for (const auto &node : t_node->children) { - if (child->children.empty()) - { - retval.push_back(child->text); - } else if (child->children.size() == 1) { - retval.push_back(child->children[0]->text); - } else { - retval.push_back(child->children[1]->text); - } + retval.push_back(get_arg_name(node)); } return retval; } + static std::pair get_arg_type(const AST_NodePtr &t_node, chaiscript::detail::Dispatch_Engine &t_ss) + { + if (t_node->children.size() < 2) + { + return std::pair(); + } else { + try { + return std::pair(t_node->children[0]->text, t_ss.get_type(t_node->children[0]->text)); + } catch (const std::range_error &t_err) { + return std::pair(t_node->children[0]->text, Type_Info()); + } + } + } + static dispatch::Param_Types get_arg_types(const AST_NodePtr &t_node, chaiscript::detail::Dispatch_Engine &t_ss) { std::vector> retval; for (const auto &child : t_node->children) { - if (child->children.empty()) - { - retval.emplace_back("", Type_Info()); - } else if (child->children.size() == 1) { - retval.emplace_back("", Type_Info()); - } else { - try { - retval.emplace_back(child->children[0]->text, t_ss.get_type(child->children[0]->text)); - } catch (const std::range_error &t_err) { - retval.emplace_back(child->children[0]->text, Type_Info()); - } - } + retval.push_back(get_arg_type(child, t_ss)); } return dispatch::Param_Types(std::move(retval)); @@ -1247,11 +1254,74 @@ namespace chaiscript Try_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Try, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Try_AST_Node() {} + + Boxed_Value handle_exception(chaiscript::detail::Dispatch_Engine &t_ss, const Boxed_Value &t_except) const + { + Boxed_Value retval; + + size_t end_point = this->children.size(); + if (this->children.back()->identifier == AST_Node_Type::Finally) { + assert(end_point > 0); + end_point = this->children.size() - 1; + } + for (size_t i = 1; i < end_point; ++i) { + chaiscript::eval::detail::Scope_Push_Pop catchscope(t_ss); + AST_NodePtr catch_block = this->children[i]; + + if (catch_block->children.size() == 1) { + //No variable capture, no guards + retval = catch_block->children[0]->eval(t_ss); + break; + } else if (catch_block->children.size() == 2 || catch_block->children.size() == 3) { + const auto name = Arg_List_AST_Node::get_arg_name(catch_block->children[0]); + + if (dispatch::Param_Types( + std::vector>{Arg_List_AST_Node::get_arg_type(catch_block->children[0], t_ss)} + ).match(std::vector{t_except}, t_ss.conversions())) + { + t_ss.add_object(name, t_except); + + if (catch_block->children.size() == 2) { + //Variable capture, no guards + retval = catch_block->children[1]->eval(t_ss); + break; + } + else if (catch_block->children.size() == 3) { + //Variable capture, guards + + bool guard = false; + try { + guard = boxed_cast(catch_block->children[1]->eval(t_ss)); + } catch (const exception::bad_boxed_cast &) { + if (this->children.back()->identifier == AST_Node_Type::Finally) { + this->children.back()->children[0]->eval(t_ss); + } + throw exception::eval_error("Guard condition not boolean"); + } + if (guard) { + retval = catch_block->children[2]->eval(t_ss); + break; + } + } + } + } + else { + if (this->children.back()->identifier == AST_Node_Type::Finally) { + this->children.back()->children[0]->eval(t_ss); + } + throw exception::eval_error("Internal error: catch block size unrecognized"); + } + } + + return retval; + } + virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{ Boxed_Value retval; chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); + try { retval = this->children[0]->eval(t_ss); } @@ -1262,98 +1332,11 @@ namespace chaiscript throw; } catch (const std::exception &e) { - Boxed_Value except(std::ref(e)); + retval = handle_exception(t_ss, Boxed_Value(std::ref(e))); - size_t end_point = this->children.size(); - if (this->children.back()->identifier == AST_Node_Type::Finally) { - assert(end_point > 0); - end_point = this->children.size() - 1; - } - for (size_t i = 1; i < end_point; ++i) { - chaiscript::eval::detail::Scope_Push_Pop catchscope(t_ss); - AST_NodePtr catch_block = this->children[i]; - - if (catch_block->children.size() == 1) { - //No variable capture, no guards - retval = catch_block->children[0]->eval(t_ss); - break; - } - else if (catch_block->children.size() == 2) { - //Variable capture, no guards - t_ss.add_object(catch_block->children[0]->text, except); - retval = catch_block->children[1]->eval(t_ss); - - break; - } - else if (catch_block->children.size() == 3) { - //Variable capture, no guards - t_ss.add_object(catch_block->children[0]->text, except); - - bool guard = false; - try { - guard = boxed_cast(catch_block->children[1]->eval(t_ss)); - } catch (const exception::bad_boxed_cast &) { - if (this->children.back()->identifier == AST_Node_Type::Finally) { - this->children.back()->children[0]->eval(t_ss); - } - throw exception::eval_error("Guard condition not boolean"); - } - if (guard) { - retval = catch_block->children[2]->eval(t_ss); - break; - } - } - else { - if (this->children.back()->identifier == AST_Node_Type::Finally) { - this->children.back()->children[0]->eval(t_ss); - } - throw exception::eval_error("Internal error: catch block size unrecognized"); - } - } } - catch (Boxed_Value &except) { - for (size_t i = 1; i < this->children.size(); ++i) { - chaiscript::eval::detail::Scope_Push_Pop catchscope(t_ss); - const auto &catch_block = this->children[i]; - - if (catch_block->children.size() == 1) { - //No variable capture, no guards - retval = catch_block->children[0]->eval(t_ss); - break; - } - else if (catch_block->children.size() == 2) { - //Variable capture, no guards - t_ss.add_object(catch_block->children[0]->text, except); - retval = catch_block->children[1]->eval(t_ss); - break; - } - else if (catch_block->children.size() == 3) { - //Variable capture, guards - t_ss.add_object(catch_block->children[0]->text, except); - - bool guard; - try { - guard = boxed_cast(catch_block->children[1]->eval(t_ss)); - } - catch (const exception::bad_boxed_cast &) { - if (this->children.back()->identifier == AST_Node_Type::Finally) { - this->children.back()->children[0]->eval(t_ss); - } - - throw exception::eval_error("Guard condition not boolean"); - } - if (guard) { - retval = catch_block->children[2]->eval(t_ss); - break; - } - } - else { - if (this->children.back()->identifier == AST_Node_Type::Finally) { - this->children.back()->children[0]->eval(t_ss); - } - throw exception::eval_error("Internal error: catch block size unrecognized"); - } - } + catch (Boxed_Value &e) { + retval = handle_exception(t_ss, e); } catch (...) { if (this->children.back()->identifier == AST_Node_Type::Finally) { @@ -1362,6 +1345,7 @@ namespace chaiscript throw; } + if (this->children.back()->identifier == AST_Node_Type::Finally) { retval = this->children.back()->children[0]->eval(t_ss); } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index de18959..06cd21e 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1337,7 +1337,7 @@ namespace chaiscript if (Keyword("catch", false)) { const auto catch_stack_top = m_match_stack.size(); if (Char('(')) { - if (!(Id(true) && Char(')'))) { + if (!(Arg() && Char(')'))) { throw exception::eval_error("Incomplete 'catch' expression", File_Position(m_line, m_col), *m_filename); } if (Char(':')) { From 497dd89046c26cb9afdb8416c4c4a94ea136ecbc Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 14:08:46 -0700 Subject: [PATCH 23/36] Add typed exception unit tests --- unittests/exception_typed.chai | 21 ++++++++++++++++++++ unittests/exception_typed_2.chai | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 unittests/exception_typed.chai create mode 100644 unittests/exception_typed_2.chai diff --git a/unittests/exception_typed.chai b/unittests/exception_typed.chai new file mode 100644 index 0000000..e7951c1 --- /dev/null +++ b/unittests/exception_typed.chai @@ -0,0 +1,21 @@ +auto x = 1 +try { + throw(x) + x = 2 +} +catch(int e) { + x = e + 3 +} +assert_equal(4, x); + +x = 1 +try { + throw(x) + x = 2 +} +catch(string e) { +} +catch(e) { + x = e + 4 +} +assert_equal(5, x); diff --git a/unittests/exception_typed_2.chai b/unittests/exception_typed_2.chai new file mode 100644 index 0000000..cb294c7 --- /dev/null +++ b/unittests/exception_typed_2.chai @@ -0,0 +1,34 @@ +auto results = []; + +for (auto i = 2; i < 6; ++i) { + try { + throw(i) + } + catch(int e) : e < 2 { + results.push_back("c1: " + e.to_string()); + } + catch(int e) : e < 4 { + results.push_back("c2: " + e.to_string()); + } + catch(e) { + results.push_back("c3: " + e.to_string()); + } + catch { + // Should never get called + assert_equal(false, true) + } +} + +try { + throw(3) +} +catch(int e) : e < 3 +{ + // Should never get called + assert_equal(false, true); +} +catch { + results.push_back("defaultcatch"); +} + +assert_equal(["c2: 2", "c2: 3", "c3: 4", "c3: 5", "defaultcatch"], results); From 7761ceb7360e15c9e0421aa9fdac2af1fd37a645 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 17:04:34 -0700 Subject: [PATCH 24/36] Clean up some numeric processing code --- include/chaiscript/language/chaiscript_parser.hpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index e9c40aa..f090ba6 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -431,21 +431,13 @@ namespace chaiscript } } - std::stringstream ss(t_val.substr(0, i)); - if (float_) { - float f; - ss >> f; - return const_var(f); + return const_var(std::stof(t_val.substr(0,i))); } else if (long_) { - long double f; - ss >> f; - return const_var(f); + return const_var(std::stold(t_val.substr(0,i))); } else { - double f; - ss >> f; - return const_var(f); + return const_var(std::stod(t_val.substr(0,i))); } } From 26bf531cabbe80fd41dd41349e3b2f3471c8ff45 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 13 Jan 2015 17:07:46 -0700 Subject: [PATCH 25/36] Remove unused parameter --- include/chaiscript/language/chaiscript_eval.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 134a576..ae6a704 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -423,7 +423,7 @@ namespace chaiscript } else { try { return std::pair(t_node->children[0]->text, t_ss.get_type(t_node->children[0]->text)); - } catch (const std::range_error &t_err) { + } catch (const std::range_error &) { return std::pair(t_node->children[0]->text, Type_Info()); } } From 1552d36d7a44355a0f0fe7491aefa84737f8cae6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 14 Jan 2015 20:01:32 -0700 Subject: [PATCH 26/36] Fix spelling of ANALYZE to analyze --- .decent_ci-Windows.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.decent_ci-Windows.yaml b/.decent_ci-Windows.yaml index 69fee14..f1d4865 100644 --- a/.decent_ci-Windows.yaml +++ b/.decent_ci-Windows.yaml @@ -2,21 +2,21 @@ compilers: - name: Visual Studio version: 14 cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA% - compiler_extra_flags: /ANALYZE + compiler_extra_flags: /analyze skip_packaging: true - name: Visual Studio version: 14 architecture: Win64 cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA% - compiler_extra_flags: /ANALYZE + compiler_extra_flags: /analyze skip_packaging: true - name: Visual Studio version: 12 cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA% - compiler_extra_flags: /ANALYZE + compiler_extra_flags: /analyze - name: Visual Studio version: 12 architecture: Win64 cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA% - compiler_extra_flags: /ANALYZE + compiler_extra_flags: /analyze From 5b6e6042f33b8804ea00b297833b4a77d86b9407 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 14 Jan 2015 20:41:41 -0700 Subject: [PATCH 27/36] Work around MSVC 2014 issue with future have to wrap std::future::valid in a lambda due to noexcept?! --- include/chaiscript/dispatchkit/bootstrap_stl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index b3be6fc..dc27fe1 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -574,7 +574,7 @@ namespace chaiscript { m->add(user_type(), type); - m->add(fun(&FutureType::valid), "valid"); + m->add(fun([](const FutureType &t) { return t.valid(); }), "valid"); m->add(fun(&FutureType::get), "get"); m->add(fun(&FutureType::wait), "wait"); From 41a45ce8b5085dc34b01741f045a5abafddc8319 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 14 Jan 2015 21:07:40 -0700 Subject: [PATCH 28/36] Enable warnings (and fix up some things) --- CMakeLists.txt | 8 +++++- include/chaiscript/dispatchkit/any.hpp | 4 ++- .../chaiscript/dispatchkit/boxed_number.hpp | 9 +++++- .../chaiscript/dispatchkit/dispatchkit.hpp | 9 ++++++ .../dispatchkit/proxy_functions.hpp | 4 ++- .../dispatchkit/proxy_functions_detail.hpp | 6 ++-- .../chaiscript/language/chaiscript_common.hpp | 2 ++ .../chaiscript/language/chaiscript_eval.hpp | 28 +++++++++---------- 8 files changed, 49 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 034fb5e..03494a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,13 @@ if(MSVC) # how to workaround or fix the error. So I'm disabling it globally. add_definitions(/wd4503) else() - add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -pedantic ${CPP11_FLAG}) + add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Woverloaded-virtual -pedantic ${CPP11_FLAG}) + + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + add_definitions(-Weverything -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables) + else() + add_definitions(-Wnoexcept) + endif() if(APPLE) add_definitions(-Wno-sign-compare) diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index 7c403b7..8a624b1 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -26,6 +26,8 @@ namespace chaiscript { { } + bad_any_cast(const bad_any_cast &) = default; + virtual ~bad_any_cast() CHAISCRIPT_NOEXCEPT {} /// \brief Description of what error occurred @@ -105,7 +107,7 @@ namespace chaiscript { } } -#if _MSC_VER != 1800 +#if !defined(_MSC_VER) || _MSC_VER != 1800 Any(Any &&) = default; Any &operator=(Any &&t_any) = default; #endif diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 557a20a..dafe181 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -327,7 +327,7 @@ namespace chaiscript return oss.str(); } - + public: Boxed_Number() : bv(Boxed_Value(0)) @@ -340,6 +340,13 @@ namespace chaiscript validate_boxed_number(bv); } + Boxed_Number(const Boxed_Number &) = default; + +#if !defined(_MSC_VER) || _MSC_VER != 1800 + Boxed_Number(Boxed_Number &&) = default; + Boxed_Number& operator=(Boxed_Number &&) = default; +#endif + template explicit Boxed_Number(T t) : bv(Boxed_Value(t)) { diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index dfa167d..99ade8c 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -62,6 +62,8 @@ namespace chaiscript { } + reserved_word_error(const reserved_word_error &) = default; + virtual ~reserved_word_error() CHAISCRIPT_NOEXCEPT {} std::string word() const @@ -82,6 +84,8 @@ namespace chaiscript { } + illegal_name_error(const illegal_name_error &) = default; + virtual ~illegal_name_error() CHAISCRIPT_NOEXCEPT {} std::string name() const @@ -103,6 +107,8 @@ namespace chaiscript { } + name_conflict_error(const name_conflict_error &) = default; + virtual ~name_conflict_error() CHAISCRIPT_NOEXCEPT {} std::string name() const @@ -125,6 +131,7 @@ namespace chaiscript { } + global_non_const(const global_non_const &) = default; virtual ~global_non_const() CHAISCRIPT_NOEXCEPT {} }; } @@ -389,6 +396,8 @@ namespace chaiscript std::set m_reserved_words; State &operator=(const State &) = default; + State() = default; + State(const State &) = default; }; Dispatch_Engine() diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index fba9b4f..350f65b 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -197,6 +197,8 @@ namespace chaiscript : std::runtime_error("Guard evaluation failed") { } + guard_error(const guard_error &) = default; + virtual ~guard_error() CHAISCRIPT_NOEXCEPT { } }; @@ -560,7 +562,7 @@ namespace chaiscript } } else { throw exception::arity_error(static_cast(params.size()), 1); - } + } } private: diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 744d40b..e5c6f3f 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -42,6 +42,8 @@ namespace chaiscript { } + arity_error(const arity_error &) = default; + virtual ~arity_error() CHAISCRIPT_NOEXCEPT {} int got; @@ -72,7 +74,7 @@ namespace chaiscript template struct Try_Cast { - static void do_try(const std::vector ¶ms, int generation, const Type_Conversions &t_conversions) + static void do_try(const std::vector ¶ms, size_t generation, const Type_Conversions &t_conversions) { boxed_cast(params[generation], &t_conversions); Try_Cast::do_try(params, generation+1, t_conversions); @@ -83,7 +85,7 @@ namespace chaiscript template<> struct Try_Cast<> { - static void do_try(const std::vector &, int, const Type_Conversions &) + static void do_try(const std::vector &, size_t, const Type_Conversions &) { } }; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 288b0cc..0cd25c2 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -112,6 +112,8 @@ namespace chaiscript reason(t_why) {} + eval_error(const eval_error &) = default; + std::string pretty_print() const { std::ostringstream ss; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index be9aabc..aec1e91 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1333,29 +1333,28 @@ namespace chaiscript AST_NodePtr guardnode; - auto d = t_ss.get_parent_locals(); - auto itr = d.find("_current_class_name"); - int class_offset = 0; - if (itr != d.end()) class_offset = -1; + const auto d = t_ss.get_parent_locals(); + const auto itr = d.find("_current_class_name"); + const auto class_offset = (itr != d.end())?-1:0; const std::string & class_name = (itr != d.end())?std::string(boxed_cast(itr->second)):this->children[0]->text; //The first param of a method is always the implied this ptr. std::vector t_param_names{"this"}; - if ((this->children.size() > static_cast(3 + class_offset)) && (this->children[(2 + class_offset)]->identifier == AST_Node_Type::Arg_List)) { - for (const auto &child : this->children[(2 + class_offset)]->children) { + if ((this->children.size() > static_cast(3 + class_offset)) && (this->children[static_cast(2 + class_offset)]->identifier == AST_Node_Type::Arg_List)) { + for (const auto &child : this->children[static_cast(2 + class_offset)]->children) { t_param_names.push_back(child->text); } if (this->children.size() > static_cast(4 + class_offset)) { - guardnode = this->children[(3 + class_offset)]; + guardnode = this->children[static_cast(3 + class_offset)]; } } else { //no parameters if (this->children.size() > static_cast(3 + class_offset)) { - guardnode = this->children[(2 + class_offset)]; + guardnode = this->children[static_cast(2 + class_offset)]; } } @@ -1372,7 +1371,7 @@ namespace chaiscript try { const std::string & l_annotation = this->annotation?this->annotation->text:""; - const std::string & function_name = this->children[(1 + class_offset)]->text; + const std::string & function_name = this->children[static_cast(1 + class_offset)]->text; if (function_name == class_name) { t_ss.add(std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, @@ -1420,24 +1419,23 @@ namespace chaiscript { const auto &d = t_ss.get_parent_locals(); const auto itr = d.find("_current_class_name"); - int class_offset = 0; - if (itr != d.end()) class_offset = -1; + const auto class_offset = (itr != d.end())?-1:0; std::string class_name = (itr != d.end())?std::string(boxed_cast(itr->second)):this->children[0]->text; try { t_ss.add( std::make_shared( - class_name, + std::move(class_name), fun(std::function(std::bind(&dispatch::Dynamic_Object::get_attr, std::placeholders::_1, - this->children[(1 + class_offset)]->text + this->children[static_cast(1 + class_offset)]->text )) ) - ), this->children[(1 + class_offset)]->text); + ), this->children[static_cast(1 + class_offset)]->text); } catch (const exception::reserved_word_error &) { - throw exception::eval_error("Reserved word used as attribute '" + this->children[(1 + class_offset)]->text + "'"); + throw exception::eval_error("Reserved word used as attribute '" + this->children[static_cast(1 + class_offset)]->text + "'"); } catch (const exception::name_conflict_error &e) { throw exception::eval_error("Attribute redefined '" + e.name() + "'"); } From f95ca75acaaeceaa505ddb48bba0f1ccec9feaac Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 15 Jan 2015 14:24:39 -0700 Subject: [PATCH 29/36] Clean up more warnings with stricter warning levels --- CMakeLists.txt | 2 +- .../chaiscript/dispatchkit/bad_boxed_cast.hpp | 3 +- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- .../chaiscript/dispatchkit/boxed_number.hpp | 20 +++++++++---- .../chaiscript/dispatchkit/boxed_value.hpp | 2 +- .../dispatchkit/proxy_functions.hpp | 16 +++++------ .../dispatchkit/type_conversions.hpp | 8 ++++-- .../chaiscript/language/chaiscript_common.hpp | 3 +- .../chaiscript/language/chaiscript_engine.hpp | 5 ++-- .../chaiscript/language/chaiscript_parser.hpp | 5 ++-- src/main.cpp | 28 ++++++++++--------- src/test_module.cpp | 5 ++++ unittests/functor_cast_test.cpp | 14 +++++----- unittests/object_lifetime_test2.cpp | 6 ++-- 14 files changed, 71 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 03494a1..90d6f84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,7 +155,7 @@ else() add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Woverloaded-virtual -pedantic ${CPP11_FLAG}) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - add_definitions(-Weverything -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables) + add_definitions(-Weverything -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded) else() add_definitions(-Wnoexcept) endif() diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index 648eb41..ca2071b 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -45,7 +45,8 @@ namespace chaiscript { } - virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT {} + bad_boxed_cast(const bad_boxed_cast &) = default; + virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT = default; /// \brief Description of what error occurred virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 3e88daf..c43820f 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -298,7 +298,7 @@ namespace chaiscript } } - static void throw_exception(const Boxed_Value &bv) { + static void throw_exception [[ noreturn ]] (const Boxed_Value &bv) { throw bv; } diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index dafe181..f4264cd 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -33,6 +33,15 @@ namespace chaiscript #pragma warning(disable : 4244 4018 4389 4146 4365) #endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + /// \brief Represents any numeric type, generically. Used internally for generic operations between POD values class Boxed_Number { @@ -40,9 +49,6 @@ namespace chaiscript struct boolean { -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wsign-compare" -#endif template static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { @@ -850,14 +856,18 @@ namespace chaiscript struct Cast_Helper : Cast_Helper { }; - + /// Cast_Helper for converting from Boxed_Value to Boxed_Number template<> struct Cast_Helper : Cast_Helper { - }; + }; } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index c73358c..65ed7a6 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -72,8 +72,8 @@ namespace chaiscript chaiscript::detail::Any m_obj; void *m_data_ptr; const void *m_const_data_ptr; - bool m_is_ref; std::unique_ptr> m_attrs; + bool m_is_ref; }; struct Object_Data diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 350f65b..61d9d47 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -129,7 +129,7 @@ namespace chaiscript virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const = 0; Proxy_Function_Base(std::vector t_types, int t_arity) - : m_types(std::move(t_types)), m_has_arithmetic_param(false), m_arity(t_arity) + : m_types(std::move(t_types)), m_arity(t_arity), m_has_arithmetic_param(false) { for (size_t i = 1; i < m_types.size(); ++i) { @@ -175,8 +175,8 @@ namespace chaiscript } std::vector m_types; - bool m_has_arithmetic_param; int m_arity; + bool m_has_arithmetic_param; }; } @@ -220,11 +220,11 @@ namespace chaiscript std::string t_description = "", Proxy_Function t_guard = Proxy_Function()) : Proxy_Function_Base(build_param_type_list(t_arity), t_arity), - m_f(std::move(t_f)), m_arity(t_arity), m_description(std::move(t_description)), m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)) + m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)), m_description(std::move(t_description)), m_f(std::move(t_f)) { } - virtual ~Dynamic_Proxy_Function() {} + virtual ~Dynamic_Proxy_Function() = default; virtual bool operator==(const Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE { @@ -311,11 +311,10 @@ namespace chaiscript return types; } - std::function &)> m_f; - int m_arity; - std::string m_description; Proxy_Function m_guard; AST_NodePtr m_parsenode; + std::string m_description; + std::function &)> m_f; }; /** @@ -591,7 +590,8 @@ namespace chaiscript { } - virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {} + dispatch_error(const dispatch_error &) = default; + virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT = default; std::vector parameters; std::vector functions; diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 59ad5e3..6fd9a17 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -44,7 +44,9 @@ namespace chaiscript { } - virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT {} + bad_boxed_dynamic_cast(const bad_boxed_dynamic_cast &) = default; + + virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT = default; }; class bad_boxed_type_cast : public bad_boxed_cast @@ -66,7 +68,9 @@ namespace chaiscript { } - virtual ~bad_boxed_type_cast() CHAISCRIPT_NOEXCEPT {} + bad_boxed_type_cast(const bad_boxed_type_cast &) = default; + + virtual ~bad_boxed_type_cast() CHAISCRIPT_NOEXCEPT = default; }; } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 0cd25c2..fb1d213 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -397,7 +397,8 @@ namespace chaiscript : std::runtime_error("File Not Found: " + t_filename) { } - virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT {} + file_not_found_error(const file_not_found_error &) = default; + virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT = default; }; } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 7fa4dd6..6478c59 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -61,9 +61,8 @@ namespace chaiscript { } - virtual ~load_module_error() CHAISCRIPT_NOEXCEPT - { - } + load_module_error(const load_module_error &) = default; + virtual ~load_module_error() CHAISCRIPT_NOEXCEPT = default; }; } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index f090ba6..8dda17c 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -223,8 +223,8 @@ namespace chaiscript t_t->end.column = pos_col_stop; if (is_deep) { - t_t->children.assign(m_match_stack.begin() + t_match_start, m_match_stack.end()); - m_match_stack.erase(m_match_stack.begin() + t_match_start, m_match_stack.end()); + t_t->children.assign(m_match_stack.begin() + static_cast(t_match_start), m_match_stack.end()); + m_match_stack.erase(m_match_stack.begin() + static_cast(t_match_start), m_match_stack.end()); } /// \todo fix the fact that a successful match that captured no ast_nodes doesn't have any real start position @@ -1910,6 +1910,7 @@ namespace chaiscript case(AST_Node_Type::Bitwise_Xor) : case(AST_Node_Type::Bitwise_Or) : case(AST_Node_Type::Comparison) : + assert(m_match_stack.size() > 1); m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, m_match_stack.begin() + m_match_stack.size() - 1); build_match(std::make_shared(oper->text), prev_stack_top); break; diff --git a/src/main.cpp b/src/main.cpp index dead221..5c3be99 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,10 @@ #include #include +#ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS +#endif + #include #ifdef READLINE_AVAILABLE @@ -18,7 +21,7 @@ char *mystrdup (const char *s) { size_t len = strlen(s); // Space for length plus nul - char *d = static_cast(malloc (len+1)); + char *d = static_cast(malloc (len+1)); if (d == nullptr) return nullptr; // No memory #ifdef CHAISCRIPT_MSVC strcpy_s(d, len, s); // Copy the characters @@ -152,10 +155,6 @@ void help(int n) { } } -void version(int){ - std::cout << "chai: compiled " << __TIME__ << " " << __DATE__ << '\n'; -} - bool throws_exception(const std::function &f) { try { @@ -214,11 +213,11 @@ std::string get_next_command() { // We have to wrap exit with our own because Clang has a hard time with // function pointers to functions with special attributes (system exit being marked NORETURN) -void myexit(int return_val) { +void myexit [[ noreturn ]] (int return_val) { exit(return_val); } -void interactive(chaiscript::ChaiScript& chai) +void interactive [[ noreturn ]] (chaiscript::ChaiScript& chai) { using_history(); @@ -287,7 +286,6 @@ int main(int argc, char *argv[]) chai.add(chaiscript::fun(&myexit), "exit"); chai.add(chaiscript::fun(&myexit), "quit"); chai.add(chaiscript::fun(&help), "help"); - chai.add(chaiscript::fun(&version), "version"); chai.add(chaiscript::fun(&throws_exception), "throws_exception"); chai.add(chaiscript::fun(&get_eval_error), "get_eval_error"); @@ -317,7 +315,7 @@ int main(int argc, char *argv[]) arg += line + '\n' ; } } else if ( arg == "-v" || arg == "--version" ) { - arg = "version(0)" ; + arg = "version()" ; } else if ( arg == "-h" || arg == "--help" ) { arg = "help(-1)"; } else if ( arg == "-i" || arg == "--interactive" ) { @@ -332,10 +330,14 @@ int main(int argc, char *argv[]) chaiscript::Boxed_Value val ; try { switch ( mode ) { - case eInteractive : interactive(chai); break; - case eCommand : val = chai.eval(arg); break; - case eFile : val = chai.eval_file(arg); break; - default : std::cout << "Unrecognized execution mode\n"; return EXIT_FAILURE; + case eInteractive: + // interactive never returns, no need for break; + interactive(chai); + case eCommand: + val = chai.eval(arg); + break; + case eFile: + val = chai.eval_file(arg); } } catch (const chaiscript::exception::eval_error &ee) { diff --git a/src/test_module.cpp b/src/test_module.cpp index cb95326..aeb1159 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -10,6 +10,7 @@ class TestBaseType TestBaseType() : val(10), const_val(15) { } TestBaseType(int) : val(10), const_val(15) {} TestBaseType(int *) : val(10), const_val(15) {} + TestBaseType(const TestBaseType &) = default; virtual ~TestBaseType() {} virtual int func() { return 0; } @@ -62,6 +63,8 @@ class TestDerivedType : public TestBaseType { public: virtual ~TestDerivedType() {} + TestDerivedType(const TestDerivedType &) = default; + TestDerivedType() = default; virtual int func() CHAISCRIPT_OVERRIDE { return 1; } int derived_only_func() { return 19; } @@ -72,6 +75,8 @@ class TestDerivedType : public TestBaseType class TestMoreDerivedType : public TestDerivedType { public: + TestMoreDerivedType(const TestMoreDerivedType &) = default; + TestMoreDerivedType() = default; virtual ~TestMoreDerivedType() {} }; diff --git a/unittests/functor_cast_test.cpp b/unittests/functor_cast_test.cpp index 7c76ca2..5fa388f 100644 --- a/unittests/functor_cast_test.cpp +++ b/unittests/functor_cast_test.cpp @@ -1,6 +1,6 @@ #include -double test_call(const std::function &f, int val) +int test_call(const std::function &f, int val) { return f(val); } @@ -9,15 +9,15 @@ int main() { chaiscript::ChaiScript chai; - + chai.add(chaiscript::fun(&test_call), "test_call"); - chai.eval("def func(i) { return i * 3.5; };"); - double d = chai.eval("test_call(func, 3)"); - - if (d == 3 * 3.5) + chai.eval("def func(i) { return i * 6; };"); + int d = chai.eval("test_call(func, 3)"); + + if (d == 3 * 6) { - return EXIT_SUCCESS; + return EXIT_SUCCESS; } else { return EXIT_FAILURE; } diff --git a/unittests/object_lifetime_test2.cpp b/unittests/object_lifetime_test2.cpp index c99b191..31c5858 100644 --- a/unittests/object_lifetime_test2.cpp +++ b/unittests/object_lifetime_test2.cpp @@ -4,9 +4,9 @@ template struct Vector2 { - Vector2() : x(0), y(0) {}; - Vector2(T px, T py) : x(px), y(py) {}; - Vector2(const Vector2& cp) : x(cp.x), y(cp.y) {}; + Vector2() : x(0), y(0) {} + Vector2(T px, T py) : x(px), y(py) {} + Vector2(const Vector2& cp) : x(cp.x), y(cp.y) {} Vector2& operator+=(const Vector2& vec_r) { From 759d6fc42f2e51a3804df949f6bd24359616f391 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 15 Jan 2015 15:15:02 -0700 Subject: [PATCH 30/36] Remove [[ noreturn ]], MSVC14 doesn't yet support attributes? --- CMakeLists.txt | 2 +- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- samples/fun_call_performance.cpp | 12 +++++------- samples/inheritance.cpp | 2 ++ src/main.cpp | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90d6f84..4811852 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,7 +155,7 @@ else() add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Woverloaded-virtual -pedantic ${CPP11_FLAG}) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - add_definitions(-Weverything -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded) + add_definitions(-Weverything -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn) else() add_definitions(-Wnoexcept) endif() diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index c43820f..3e88daf 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -298,7 +298,7 @@ namespace chaiscript } } - static void throw_exception [[ noreturn ]] (const Boxed_Value &bv) { + static void throw_exception(const Boxed_Value &bv) { throw bv; } diff --git a/samples/fun_call_performance.cpp b/samples/fun_call_performance.cpp index a689b5a..e16efaa 100644 --- a/samples/fun_call_performance.cpp +++ b/samples/fun_call_performance.cpp @@ -8,7 +8,10 @@ #include #include +#ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS +#endif + #include #include @@ -154,10 +157,6 @@ void help(int n) { } } -void version(int){ - std::cout << "chai: compiled " << __TIME__ << " " << __DATE__ << std::endl; -} - std::string helloWorld(const std::string &t_name) { return "Hello " + t_name + "!"; @@ -297,7 +296,6 @@ int main(int argc, char *argv[]) chai.add(chaiscript::fun(&myexit), "exit"); chai.add(chaiscript::fun(&myexit), "quit"); chai.add(chaiscript::fun(&help), "help"); - chai.add(chaiscript::fun(&version), "version"); chai.add(chaiscript::fun(&throws_exception), "throws_exception"); chai.add(chaiscript::fun(&get_eval_error), "get_eval_error"); @@ -356,7 +354,7 @@ int main(int argc, char *argv[]) } } else if (arg == "-v" || arg == "--version") { - arg = "version(0)"; + arg = "version()"; } else if (arg == "-h" || arg == "--help") { arg = "help(-1)"; @@ -388,7 +386,7 @@ int main(int argc, char *argv[]) printf("**ChaiScript::time= %.10f\n", elapsed_secs1); break; } - default: std::cout << "Unrecognized execution mode" << std::endl; return EXIT_FAILURE; + } } catch (const chaiscript::exception::eval_error &ee) { diff --git a/samples/inheritance.cpp b/samples/inheritance.cpp index 5bd8c86..e8ef192 100644 --- a/samples/inheritance.cpp +++ b/samples/inheritance.cpp @@ -8,6 +8,8 @@ class BaseClass { } + BaseClass(const BaseClass &) = default; + virtual ~BaseClass() {} virtual std::string doSomething(float, double) const = 0; diff --git a/src/main.cpp b/src/main.cpp index 5c3be99..59e96e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -213,11 +213,11 @@ std::string get_next_command() { // We have to wrap exit with our own because Clang has a hard time with // function pointers to functions with special attributes (system exit being marked NORETURN) -void myexit [[ noreturn ]] (int return_val) { +void myexit(int return_val) { exit(return_val); } -void interactive [[ noreturn ]] (chaiscript::ChaiScript& chai) +void interactive(chaiscript::ChaiScript& chai) { using_history(); @@ -331,8 +331,8 @@ int main(int argc, char *argv[]) try { switch ( mode ) { case eInteractive: - // interactive never returns, no need for break; interactive(chai); + break; case eCommand: val = chai.eval(arg); break; From 9449fca22f52e78fd2b9e18cb75ff200ae4bd66f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 15 Jan 2015 15:42:35 -0700 Subject: [PATCH 31/36] Memory leak error fixes. Various compiler fixes. --- include/chaiscript/dispatchkit/bad_boxed_cast.hpp | 2 +- include/chaiscript/dispatchkit/proxy_functions.hpp | 4 ++-- include/chaiscript/dispatchkit/type_conversions.hpp | 4 ++-- include/chaiscript/language/chaiscript_common.hpp | 2 +- include/chaiscript/language/chaiscript_engine.hpp | 2 +- src/test_module.cpp | 6 ++++-- unittests/boxed_cast_test.cpp | 5 +++++ 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index ca2071b..7afc6dc 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -46,7 +46,7 @@ namespace chaiscript } bad_boxed_cast(const bad_boxed_cast &) = default; - virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT = default; + virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT {} /// \brief Description of what error occurred virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 61d9d47..78b4dee 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -224,7 +224,7 @@ namespace chaiscript { } - virtual ~Dynamic_Proxy_Function() = default; + virtual ~Dynamic_Proxy_Function() {} virtual bool operator==(const Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE { @@ -591,7 +591,7 @@ namespace chaiscript } dispatch_error(const dispatch_error &) = default; - virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT = default; + virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {} std::vector parameters; std::vector functions; diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 6fd9a17..d4cf429 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -46,7 +46,7 @@ namespace chaiscript bad_boxed_dynamic_cast(const bad_boxed_dynamic_cast &) = default; - virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT = default; + virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT {} }; class bad_boxed_type_cast : public bad_boxed_cast @@ -70,7 +70,7 @@ namespace chaiscript bad_boxed_type_cast(const bad_boxed_type_cast &) = default; - virtual ~bad_boxed_type_cast() CHAISCRIPT_NOEXCEPT = default; + virtual ~bad_boxed_type_cast() CHAISCRIPT_NOEXCEPT {} }; } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index fb1d213..7a6d010 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -398,7 +398,7 @@ namespace chaiscript { } file_not_found_error(const file_not_found_error &) = default; - virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT = default; + virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT {} }; } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 6478c59..a4d354e 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -62,7 +62,7 @@ namespace chaiscript } load_module_error(const load_module_error &) = default; - virtual ~load_module_error() CHAISCRIPT_NOEXCEPT = default; + virtual ~load_module_error() CHAISCRIPT_NOEXCEPT {} }; } diff --git a/src/test_module.cpp b/src/test_module.cpp index aeb1159..2544d53 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -9,7 +9,7 @@ class TestBaseType public: TestBaseType() : val(10), const_val(15) { } TestBaseType(int) : val(10), const_val(15) {} - TestBaseType(int *) : val(10), const_val(15) {} + TestBaseType(int *i) : val(10), const_val(15) { } TestBaseType(const TestBaseType &) = default; virtual ~TestBaseType() {} virtual int func() { return 0; } @@ -100,9 +100,11 @@ std::string hello_world() return "Hello World"; } +int global_i = 1; + int *get_new_int() { - return new int(1); + return &global_i; } // MSVC doesn't like that we are using C++ return types from our C declared module diff --git a/unittests/boxed_cast_test.cpp b/unittests/boxed_cast_test.cpp index 4e94471..4635841 100644 --- a/unittests/boxed_cast_test.cpp +++ b/unittests/boxed_cast_test.cpp @@ -265,20 +265,25 @@ bool pointer_test(const T& default_value, const T& new_value) if (p != (*result) ) { std::cerr << "Pointer passed in different than one returned\n"; + delete p; return false; } if (*p != *(*result) ) { std::cerr << "Somehow dereferenced pointer values are not the same?\n"; + delete p; return false; } + delete p; return true; } catch (const exception::bad_boxed_cast &) { std::cerr << "Bad boxed cast performing ** to ** test\n"; + delete p; return false; } catch (...) { std::cerr << "Unknown exception performing ** to ** test\n"; + delete p; return false; } From adfc56db8b752adc07e152b223080541c8d93685 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 15 Jan 2015 17:49:26 -0700 Subject: [PATCH 32/36] Warning cleanups --- src/test_module.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test_module.cpp b/src/test_module.cpp index 2544d53..b161817 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -9,7 +9,7 @@ class TestBaseType public: TestBaseType() : val(10), const_val(15) { } TestBaseType(int) : val(10), const_val(15) {} - TestBaseType(int *i) : val(10), const_val(15) { } + TestBaseType(int *) : val(10), const_val(15) { } TestBaseType(const TestBaseType &) = default; virtual ~TestBaseType() {} virtual int func() { return 0; } @@ -100,7 +100,7 @@ std::string hello_world() return "Hello World"; } -int global_i = 1; +static int global_i = 1; int *get_new_int() { From c3f343450d9adbe37ba6c735b817bfb4448f6363 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 16 Jan 2015 10:10:14 -0700 Subject: [PATCH 33/36] Fix issues found with cppcheck inconclusive --- .decent_ci-Linux.yaml | 2 +- include/chaiscript/chaiscript_threading.hpp | 29 ++++++++++++++++--- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 1 + .../chaiscript/dispatchkit/boxed_number.hpp | 4 ++- .../chaiscript/dispatchkit/dispatchkit.hpp | 13 ++++++--- .../dispatchkit/type_conversions.hpp | 14 ++++++--- .../chaiscript/language/chaiscript_engine.hpp | 18 ++++++------ unittests/object_lifetime_test2.cpp | 3 +- 8 files changed, 60 insertions(+), 24 deletions(-) diff --git a/.decent_ci-Linux.yaml b/.decent_ci-Linux.yaml index 45fdd6f..31c7b52 100644 --- a/.decent_ci-Linux.yaml +++ b/.decent_ci-Linux.yaml @@ -21,5 +21,5 @@ compilers: skip_packaging: true cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON - name: cppcheck - compiler_extra_flags: --enable=all -I include --inline-suppr + compiler_extra_flags: --enable=all -I include --inline-suppr -Umax --suppress="*:cmake*" diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 485f7ee..cf7aa47 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -82,16 +82,27 @@ namespace chaiscript t().erase(m_key); } - inline T *operator->() const + inline const T *operator->() const { return &(t()[m_key]); } - inline T &operator*() const + inline const T &operator*() const { return t()[m_key]; } + inline T *operator->() + { + return &(t()[m_key]); + } + + inline T &operator*() + { + return t()[m_key]; + } + + void *m_key; private: @@ -117,12 +128,22 @@ namespace chaiscript { } - inline T *operator->() const + inline const T *operator->() const { return get_tls().get(); } - inline T &operator*() const + inline const T &operator*() const + { + return *get_tls(); + } + + inline T *operator->() + { + return get_tls().get(); + } + + inline T &operator*() { return *get_tls(); } diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index dc27fe1..4e787c0 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -246,6 +246,7 @@ namespace chaiscript template ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) { + // cppcheck-suppress syntaxError typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); typedef typename ContainerType::const_reference(ContainerType::*constindexoper)(size_t) const; diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index f4264cd..12cd374 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -67,7 +67,7 @@ namespace chaiscript case Operators::not_equal: return const_var(t != u); default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -560,6 +560,7 @@ namespace chaiscript } } + // cppcheck-suppress operatorEq Boxed_Number operator=(const Boxed_Value &v) { validate_boxed_number(v); @@ -567,6 +568,7 @@ namespace chaiscript return *this; } + // cppcheck-suppress operatorEq Boxed_Number operator=(const Boxed_Number &t_rhs) const { return oper(Operators::assign, this->bv, t_rhs.bv); diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 99ade8c..16d1f2c 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -454,7 +454,7 @@ namespace chaiscript /// Adds a named object to the current scope /// \warning This version does not check the validity of the name /// it is meant for internal use only - void add_object(const std::string &name, const Boxed_Value &obj) const + void add_object(const std::string &name, const Boxed_Value &obj) { if (!get_stack_data().back().insert(std::make_pair(name, obj)).second) { @@ -704,10 +704,10 @@ namespace chaiscript /// std::map get_scripting_objects() const { - Stack_Holder &s = *m_stack_holder; + const Stack_Holder &s = *m_stack_holder; // We don't want the current context, but one up if it exists - StackData &stack = (s.stacks.size()==1)?(s.stacks.back()):(s.stacks[s.stacks.size()-2]); + const StackData &stack = (s.stacks.size()==1)?(s.stacks.back()):(s.stacks[s.stacks.size()-2]); std::map retval; @@ -974,7 +974,12 @@ namespace chaiscript private: /// Returns the current stack /// make const/non const versions - StackData &get_stack_data() const + const StackData &get_stack_data() const + { + return m_stack_holder->stacks.back(); + } + + StackData &get_stack_data() { return m_stack_holder->stacks.back(); } diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index d4cf429..7f396a9 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -217,14 +217,20 @@ namespace chaiscript }; Type_Conversions() - : m_num_types(0), + : m_mutex(), + m_conversions(), + m_convertableTypes(), + m_num_types(0), m_thread_cache(this), m_conversion_saves(this) { } Type_Conversions(const Type_Conversions &t_other) - : m_conversions(t_other.get_conversions()), m_num_types(m_conversions.size()), + : m_mutex(), + m_conversions(t_other.get_conversions()), + m_convertableTypes(), + m_num_types(m_conversions.size()), m_thread_cache(this), m_conversion_saves(this) @@ -370,8 +376,8 @@ namespace chaiscript std::set> m_conversions; std::set m_convertableTypes; std::atomic_size_t m_num_types; - chaiscript::detail::threading::Thread_Storage> m_thread_cache; - chaiscript::detail::threading::Thread_Storage m_conversion_saves; + mutable chaiscript::detail::threading::Thread_Storage> m_thread_cache; + mutable chaiscript::detail::threading::Thread_Storage m_conversion_saves; }; typedef std::shared_ptr Type_Conversion; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index a4d354e..3c92911 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -370,10 +370,10 @@ namespace chaiscript m_engine.add(fun(&ChaiScript::internal_eval, this), "eval"); m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval"); - m_engine.add(fun(&ChaiScript::version_major, this), "version_major"); - m_engine.add(fun(&ChaiScript::version_minor, this), "version_minor"); - m_engine.add(fun(&ChaiScript::version_patch, this), "version_patch"); - m_engine.add(fun(&ChaiScript::version, this), "version"); + m_engine.add(fun(&ChaiScript::version_major), "version_major"); + m_engine.add(fun(&ChaiScript::version_minor), "version_minor"); + m_engine.add(fun(&ChaiScript::version_patch), "version_patch"); + m_engine.add(fun(&ChaiScript::version), "version"); m_engine.add(fun(&ChaiScript::add_global_const, this), "add_global_const"); m_engine.add(fun(&ChaiScript::add_global, this), "add_global"); @@ -490,22 +490,22 @@ namespace chaiscript build_eval_system(ModulePtr()); } - int version_major() const + static int version_major() { return chaiscript::version_major; } - int version_minor() const + static int version_minor() { return chaiscript::version_minor; } - int version_patch() const + static int version_patch() { return chaiscript::version_patch; } - std::string version() const + static std::string version() { std::stringstream ss; ss << version_major() << "." << version_minor() << "." << version_patch(); @@ -604,7 +604,7 @@ namespace chaiscript /// chaiscript::ChaiScript chai; /// chaiscript::ChaiScript::State s = chai.get_state(); // represents bootstrapped initial state /// \endcode - State get_state() + State get_state() const { chaiscript::detail::threading::lock_guard l(m_use_mutex); chaiscript::detail::threading::shared_lock l2(m_mutex); diff --git a/unittests/object_lifetime_test2.cpp b/unittests/object_lifetime_test2.cpp index 31c5858..9716fef 100644 --- a/unittests/object_lifetime_test2.cpp +++ b/unittests/object_lifetime_test2.cpp @@ -20,10 +20,11 @@ struct Vector2 return Vector2(*this += vec_r); } - void operator=(const Vector2& ver_r) + Vector2 &operator=(const Vector2& ver_r) { x = ver_r.x; y = ver_r.y; + return *this; } From 9b19aa3b6eef2b8807c88d60b7a77af34393aab0 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 17 Jan 2015 07:05:10 -0700 Subject: [PATCH 34/36] Get ready for 5.6.0 release - Update copyrights to 2015 - Set version to 5.6.0 - Update release notes --- CMakeLists.txt | 4 +-- include/chaiscript/chaiscript.hpp | 2 +- include/chaiscript/chaiscript_defines.hpp | 8 +++--- include/chaiscript/chaiscript_threading.hpp | 2 +- .../chaiscript/dispatchkit/bad_boxed_cast.hpp | 2 +- include/chaiscript/dispatchkit/bind_first.hpp | 2 +- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 2 +- include/chaiscript/dispatchkit/boxed_cast.hpp | 2 +- .../dispatchkit/boxed_cast_helper.hpp | 2 +- .../chaiscript/dispatchkit/boxed_number.hpp | 3 ++- .../chaiscript/dispatchkit/boxed_value.hpp | 2 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 2 +- .../chaiscript/dispatchkit/dynamic_object.hpp | 2 +- .../dispatchkit/dynamic_object_detail.hpp | 2 +- .../dispatchkit/exception_specification.hpp | 2 +- .../chaiscript/dispatchkit/function_call.hpp | 2 +- .../dispatchkit/function_call_detail.hpp | 2 +- .../chaiscript/dispatchkit/handle_return.hpp | 2 +- include/chaiscript/dispatchkit/operators.hpp | 2 +- .../dispatchkit/proxy_constructors.hpp | 2 +- .../dispatchkit/proxy_functions.hpp | 2 +- .../dispatchkit/proxy_functions_detail.hpp | 2 +- .../dispatchkit/register_function.hpp | 2 +- .../dispatchkit/type_conversions.hpp | 2 +- include/chaiscript/dispatchkit/type_info.hpp | 2 +- .../language/chaiscript_algebraic.hpp | 2 +- .../chaiscript/language/chaiscript_common.hpp | 2 +- .../chaiscript/language/chaiscript_engine.hpp | 2 +- .../chaiscript/language/chaiscript_eval.hpp | 2 +- .../chaiscript/language/chaiscript_parser.hpp | 2 +- include/chaiscript/utility/utility.hpp | 2 +- license.txt | 2 +- readme.md | 7 ++--- releasenotes.md | 26 ++++++++++++++++++- samples/fun_call_performance.cpp | 2 +- src/main.cpp | 2 +- src/stl_extra.cpp | 2 +- 38 files changed, 70 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4811852..36b5698 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,8 +81,8 @@ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.md") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt") set(CPACK_PACKAGE_VERSION_MAJOR 5) -set(CPACK_PACKAGE_VERSION_MINOR 5) -set(CPACK_PACKAGE_VERSION_PATCH 1) +set(CPACK_PACKAGE_VERSION_MINOR 6) +set(CPACK_PACKAGE_VERSION_PATCH 0) set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval") set(CPACK_PACKAGE_VENDOR "ChaiScript.com") diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index 4acabcf..479c0fb 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_HPP_ diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 2b05603..5fbc475 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_DEFINES_HPP_ @@ -17,7 +17,7 @@ #endif #if (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) -/// Currently only g++>=4.8supports this natively +/// Currently only g++>=4.8 supports this natively /// \todo Make this support other compilers when possible #define CHAISCRIPT_HAS_THREAD_LOCAL #endif @@ -45,8 +45,8 @@ namespace chaiscript { static const int version_major = 5; - static const int version_minor = 5; - static const int version_patch = 1; + static const int version_minor = 6; + static const int version_patch = 0; } #endif diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index cf7aa47..4568116 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_THREADING_HPP_ diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index 7afc6dc..31344d4 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BAD_BOXED_CAST_HPP_ diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index 6a3adda..92675e1 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BIND_FIRST_HPP_ diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index dd1f880..6537ffd 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BOOTSTRAP_HPP_ diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index 4e787c0..da3aacf 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com /// \file diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index 1d11d6e..40b7857 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BOXED_CAST_HPP_ diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index 3222fd1..a71c7cd 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BOXED_CAST_HELPER_HPP_ diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 4e91dca..0042751 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_ @@ -29,6 +29,7 @@ namespace chaiscript struct arithmetic_error : public std::runtime_error { arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {} + arithmetic_error(const arithmetic_error &) = default; virtual ~arithmetic_error() CHAISCRIPT_NOEXCEPT {} }; } diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 65ed7a6..94825a5 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BOXED_VALUE_HPP_ diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 16d1f2c..f882b0d 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_DISPATCHKIT_HPP_ diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index d90fe1b..c300a8d 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_ diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index 5683404..36e8dff 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_DYNAMIC_OBJECT_DETAIL_HPP_ diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index e323484..54f19c4 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_ diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index a434f07..0a90ca2 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_FUNCTION_CALL_HPP_ diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index ee1d1bd..798053d 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_ diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index cb1c977..a9e1164 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_HANDLE_RETURN_HPP_ diff --git a/include/chaiscript/dispatchkit/operators.hpp b/include/chaiscript/dispatchkit/operators.hpp index 353035e..ce1bd97 100644 --- a/include/chaiscript/dispatchkit/operators.hpp +++ b/include/chaiscript/dispatchkit/operators.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_OPERATORS_HPP_ diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index 291fa43..f354ae5 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 1711e98..639c981 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index e5c6f3f..5cb1d82 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index a664922..678f0a8 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_ diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 7f396a9..13eb680 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_DYNAMIC_CAST_CONVERSION_HPP_ diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 2cf6455..eaa791d 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_TYPE_INFO_HPP_ diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index b5d1b31..aab4af7 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_ALGEBRAIC_HPP_ diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index b7e976d..e383d16 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_COMMON_HPP_ diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 3c92911..89b555e 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_ENGINE_HPP_ diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 83deb92..33477d8 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_EVAL_HPP_ diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index c18fc1e..117f5d6 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_PARSER_HPP_ diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 07fdff4..9c36b13 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_UTILITY_UTILITY_HPP_ diff --git a/license.txt b/license.txt index 3416309..48f5292 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright 2009-2014 Jason Turner +Copyright 2009-2015 Jason Turner Copyright 2009-2012 Jonathan Turner. All Rights Reserved. diff --git a/readme.md b/readme.md index 026ea09..f4446e7 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,7 @@ ChaiScript http://www.chaiscript.com (c) 2009-2012 Jonathan Turner -(c) 2009-2014 Jason Turner +(c) 2009-2015 Jason Turner Release under the BSD license, see "license.txt" for details. @@ -35,9 +35,10 @@ Requirements ============ ChaiScript requires a C++11 compiler to build with support for variadic -templates. It has been tested with gcc 4.7 and clang 3.1 (with libcxx). MacOS +templates. It has been tested with gcc 4.6 and clang 3.1 (with libcxx). MacOS 10.8 (Mountain Lion) is also known to support the C++11 build with Apple's -clang 4.0. +clang 4.0. MSVC 2013 or newer is supports also. For more information see the build +[dashboard](http://chaiscript.com/ChaiScript-BuildResults/index.html). Usage ===== diff --git a/releasenotes.md b/releasenotes.md index d71c5b3..506a9c9 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -1,6 +1,30 @@ Notes: ======= -Current Version: 5.5.1 +Current Version: 5.6.0 + +### Changes since 5.5.1 +* Throw exception on integer divide by 0 +* Add optional type specification to function declarations + ``` + def func(int i, j, double k) { + // i must be an int. + // j can be anything + // k must be a double + // normal conversion rules still apply + } + ``` +* Many minor fixes for compiler warnings +* Add support for `std::future` and `std::async` + ``` + var f := async(someFunction); + var f2 := async(someFunction2); + + // someFunction and someFunction2 are running in parallel now + f.get(); + f2.get(); + ``` +* Fully support r-value returns, supporting move-only objects and reducing object copies + ### Changes since 5.5.0 * 30% performance increase diff --git a/samples/fun_call_performance.cpp b/samples/fun_call_performance.cpp index e16efaa..c9830d0 100644 --- a/samples/fun_call_performance.cpp +++ b/samples/fun_call_performance.cpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #include diff --git a/src/main.cpp b/src/main.cpp index 59e96e0..109a538 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #include diff --git a/src/stl_extra.cpp b/src/stl_extra.cpp index eb6bb8c..6f0c5e4 100644 --- a/src/stl_extra.cpp +++ b/src/stl_extra.cpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #include From b43679127202f77a19ada287cfd347f85a0920b3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 17 Jan 2015 07:09:47 -0700 Subject: [PATCH 35/36] Change to TBZ2 for MacOS packages --- .decent_ci-MacOS.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.decent_ci-MacOS.yaml b/.decent_ci-MacOS.yaml index f8a07ca..f297a14 100644 --- a/.decent_ci-MacOS.yaml +++ b/.decent_ci-MacOS.yaml @@ -1,6 +1,7 @@ compilers: - name: clang cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=$COMMIT_SHA + build_package_generator: TBZ2 - name: clang build_type: Debug cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=$COMMIT_SHA From 343264944ae1ef28740b9da01742c53cae3712dc Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 17 Jan 2015 14:28:06 -0700 Subject: [PATCH 36/36] Update releasenotes.md --- releasenotes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/releasenotes.md b/releasenotes.md index 506a9c9..e88dd36 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -5,6 +5,7 @@ Current Version: 5.6.0 ### Changes since 5.5.1 * Throw exception on integer divide by 0 * Add optional type specification to function declarations + ``` def func(int i, j, double k) { // i must be an int. @@ -12,7 +13,7 @@ Current Version: 5.6.0 // k must be a double // normal conversion rules still apply } - ``` + ``` * Many minor fixes for compiler warnings * Add support for `std::future` and `std::async` ```