From 71245aa70306a24eebc3c7c6801b52ee482e929a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 17 Apr 2015 20:02:09 -0600 Subject: [PATCH] Add array type support #167 --- include/chaiscript/dispatchkit/bootstrap.hpp | 37 +++++++++++++++++++ .../dispatchkit/boxed_cast_helper.hpp | 3 +- .../chaiscript/language/chaiscript_eval.hpp | 2 +- .../chaiscript/language/chaiscript_parser.hpp | 4 +- src/test_module.cpp | 10 +++++ unittests/array_types.chai | 12 ++++++ 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 unittests/array_types.chai diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 32c11c1..4ce7e3e 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -52,6 +52,43 @@ namespace chaiscript } } + template::value>::type > + ModulePtr array(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + typedef typename std::remove_extent::type ReturnType; + const auto extent = std::extent::value; + m->add(user_type(), type); + m->add(fun( + [extent](T& t, size_t index)->ReturnType &{ + if (extent > 0 && index >= extent) { + throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); + } else { + return t[index]; + } + } + ), "[]" + ); + + m->add(fun( + [extent](const T &t, size_t index)->const ReturnType &{ + if (extent > 0 && index >= extent) { + throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); + } else { + return t[index]; + } + } + ), "[]" + ); + + m->add(fun( + [extent](const T &) { + return extent; + }), "size"); + + + return m; + } + /// \brief Adds a copy constructor for the given type to the given Model /// \param[in] type The name of the type. The copy constructor will be named "type". /// \param[in,out] m The Module to add the copy constructor to diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index c218d30..a2a1331 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -40,7 +40,8 @@ namespace chaiscript { if (ob.get_type_info().bare_equal_type_info(typeid(Result))) { - return *(static_cast(throw_if_null(ob.get_const_ptr()))); + auto p = throw_if_null(ob.get_const_ptr()); + return std::cref(*static_cast(p)); } else { throw chaiscript::detail::exception::bad_any_cast(); } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 59e09ba..8a0f897 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -712,7 +712,7 @@ namespace chaiscript fpp.save_params(params); - std::string fun_name = [&](){ + std::string fun_name = [&]()->std::string{ if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) { return this->children[i]->children[0]->text; } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 73a33e2..66ea3f4 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -617,7 +617,7 @@ namespace chaiscript } - const size_t size = [&](){ + const size_t size = [&]()->size_t{ if (longlong_) { return sizeof(int64_t) * 8; @@ -800,7 +800,7 @@ namespace chaiscript const auto prev_line = m_line; if (Id_()) { m_match_stack.push_back(std::make_shared( - [&](){ + [&]()->std::string{ if (*start == '`') { //Id Literal return std::string(start+1, m_input_pos-1); diff --git a/src/test_module.cpp b/src/test_module.cpp index b161817..5609775 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -1,5 +1,6 @@ #include +#include #include @@ -21,6 +22,8 @@ class TestBaseType int val; const int const_val; + int mdarray[2][3][5]; + private: TestBaseType &operator=(const TestBaseType &); }; @@ -159,6 +162,13 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo m->add(chaiscript::fun(&TestBaseType::const_val), "const_val"); m->add(chaiscript::fun(&TestBaseType::base_only_func), "base_only_func"); + // Array types + m->add(chaiscript::fun(&TestBaseType::mdarray), "mdarray"); + m->add(chaiscript::bootstrap::array("IntArray_2_3_5")); + m->add(chaiscript::bootstrap::array("IntArray_3_5")); + m->add(chaiscript::bootstrap::array("IntArray_5")); + // end array types + m->add(chaiscript::fun(&get_new_int), "get_new_int"); diff --git a/unittests/array_types.chai b/unittests/array_types.chai new file mode 100644 index 0000000..f6c7791 --- /dev/null +++ b/unittests/array_types.chai @@ -0,0 +1,12 @@ +load_module("test_module") + +auto t0 = TestBaseType() + +assert_true(t0.mdarray.size() == 2) +assert_true(t0.mdarray[0].size() == 3) +assert_true(t0.mdarray[0][0].size() == 5) + +t0.mdarray[1][2][4] = 15; + +assert_true(t0.mdarray[1][2][4] == 15) +