From 3a675bf379cc38c4b7c3902ccd603b9272cdb910 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 16 Oct 2015 18:21:49 -0600 Subject: [PATCH 1/4] Add config option for compiling with gprof output --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 07ae809a..0b67b72f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,13 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(LINKER_FLAGS "${LINKER_FLAGS} -flto") endif() + option(GPROF_OUTPUT "Generate profile data" FALSE) + if (GPROF_OUTPUT) + add_definitions(-pg) + set(LINKER_FLAGS "${LINKER_FLAGS} -pg") + endif() + + option(PROFILE_GENERATE "Generate profile data" FALSE) if (PROFILE_GENERATE) add_definitions(-fprofile-generate) From 38b98c55ccd97ef38d941ab019c1aace5e33e9f2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 16 Oct 2015 18:37:02 -0600 Subject: [PATCH 2/4] Add test for dynamic object option explicit --- .../dynamic_object_dynamic_attrs_explicit.chai | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 unittests/dynamic_object_dynamic_attrs_explicit.chai diff --git a/unittests/dynamic_object_dynamic_attrs_explicit.chai b/unittests/dynamic_object_dynamic_attrs_explicit.chai new file mode 100644 index 00000000..b26b6100 --- /dev/null +++ b/unittests/dynamic_object_dynamic_attrs_explicit.chai @@ -0,0 +1,14 @@ + +class MyClass { + def MyClass() + { + this.set_explicit(true); + } +}; + +var o = MyClass(); + +assert_true(o.is_explicit()); + +assert_throws(fun[o](){o.x = 2}) + From 882cbf2dfbe0bd50a03c8a5056754f18d1d63300 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 16 Oct 2015 18:47:26 -0600 Subject: [PATCH 3/4] Add option explicit code, but don't throw yet Work towards #218 --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 ++ include/chaiscript/dispatchkit/dynamic_object.hpp | 15 +++++++++++++-- .../dynamic_object_dynamic_attrs_explicit.chai | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index ac8c5dc1..7e3a3015 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -440,6 +440,8 @@ namespace chaiscript m->add(constructor(), "Dynamic_Object"); m->add(fun(&dispatch::Dynamic_Object::get_type_name), "get_type_name"); m->add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs"); + m->add(fun(&dispatch::Dynamic_Object::set_explicit), "set_explicit"); + m->add(fun(&dispatch::Dynamic_Object::is_explicit), "is_explicit"); m->add(fun(static_cast(&dispatch::Dynamic_Object::get_attr)), "get_attr"); m->add(fun(static_cast(&dispatch::Dynamic_Object::get_attr)), "get_attr"); diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 9ea827c9..7df1abf4 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -28,14 +28,24 @@ namespace chaiscript { public: Dynamic_Object(std::string t_type_name) - : m_type_name(std::move(t_type_name)) + : m_type_name(std::move(t_type_name)), m_option_explicit(false) { } - Dynamic_Object() : m_type_name("") + Dynamic_Object() : m_type_name(""), m_option_explicit(false) { } + bool is_explicit() const + { + return m_option_explicit; + } + + void set_explicit(const bool t_explicit) + { + m_option_explicit = t_explicit; + } + std::string get_type_name() const { return m_type_name; @@ -85,6 +95,7 @@ namespace chaiscript private: std::string m_type_name; + bool m_option_explicit; std::map m_attrs; }; diff --git a/unittests/dynamic_object_dynamic_attrs_explicit.chai b/unittests/dynamic_object_dynamic_attrs_explicit.chai index b26b6100..b37dc0fb 100644 --- a/unittests/dynamic_object_dynamic_attrs_explicit.chai +++ b/unittests/dynamic_object_dynamic_attrs_explicit.chai @@ -10,5 +10,5 @@ var o = MyClass(); assert_true(o.is_explicit()); -assert_throws(fun[o](){o.x = 2}) +assert_throws("error", fun[o](){o.x = 2}) From 7ba7b81a5cd6ded8788d94040d9d66322aecb109 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 16 Oct 2015 21:41:54 -0600 Subject: [PATCH 4/4] Implement option explicit for dynamic objects. Closes #218 --- cheatsheet.md | 12 ++++++++++++ include/chaiscript/dispatchkit/dispatchkit.hpp | 17 +++++++++++------ .../chaiscript/dispatchkit/dynamic_object.hpp | 18 ++++++++++++++++++ .../chaiscript/dispatchkit/proxy_functions.hpp | 8 ++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/cheatsheet.md b/cheatsheet.md index 9ff4ad4b..841cb924 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -354,6 +354,18 @@ o.f = fun(y) { print(this.x + y); } o.f(10); // prints 13 ``` +### Option Explicit + +If you want to disable dynamic parameter definitions, you can `set_explicit`. + +``` +class My_Class { + def My_Class() { + this.set_explicit(true); + this.x = 2; // this would fail with explicit set to true + } +}; + ## method_missing A function of the signature `method_missing(object, name, param1, param2, param3)` will be called if an appropriate diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 305de996..aa094867 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1002,12 +1002,17 @@ namespace chaiscript }(); if (!functions.empty()) { - if (is_no_param) { - std::vector tmp_params(params); - tmp_params.insert(tmp_params.begin() + 1, var(t_name)); - return do_attribute_call(2, tmp_params, functions, m_conversions); - } else { - return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}, m_conversions); + try { + if (is_no_param) { + std::vector tmp_params(params); + tmp_params.insert(tmp_params.begin() + 1, var(t_name)); + return do_attribute_call(2, tmp_params, functions, m_conversions); + } else { + return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}, m_conversions); + } + } catch (const dispatch::option_explicit_set &e) { + throw chaiscript::exception::dispatch_error(params, std::vector(funs.second->begin(), funs.second->end()), + e.what()); } } diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 7df1abf4..eaabf9bd 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -24,6 +24,16 @@ namespace chaiscript { namespace dispatch { + struct option_explicit_set : std::runtime_error { + option_explicit_set(const std::string &t_param_name) + : std::runtime_error("option explicit set and parameter '" + t_param_name + "' does not exist") + { + + } + + virtual ~option_explicit_set() CHAISCRIPT_NOEXCEPT {} + }; + class Dynamic_Object { public: @@ -79,11 +89,19 @@ namespace chaiscript Boxed_Value &method_missing(const std::string &t_method_name) { + if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) { + throw option_explicit_set(t_method_name); + } + return get_attr(t_method_name); } const Boxed_Value &method_missing(const std::string &t_method_name) const { + if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) { + throw option_explicit_set(t_method_name); + } + return get_attr(t_method_name); } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index d9da2e61..6214b4dd 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -760,6 +760,14 @@ namespace chaiscript { } + dispatch_error(std::vector t_parameters, + std::vector t_functions, + const std::string &t_desc) + : std::runtime_error(t_desc), parameters(std::move(t_parameters)), functions(std::move(t_functions)) + { + } + + dispatch_error(const dispatch_error &) = default; virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}