Merge branch 'develop' of github.com:ChaiScript/ChaiScript into develop
This commit is contained in:
commit
eec0299cbc
@ -68,6 +68,13 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|||||||
set(LINKER_FLAGS "${LINKER_FLAGS} -flto")
|
set(LINKER_FLAGS "${LINKER_FLAGS} -flto")
|
||||||
endif()
|
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)
|
option(PROFILE_GENERATE "Generate profile data" FALSE)
|
||||||
if (PROFILE_GENERATE)
|
if (PROFILE_GENERATE)
|
||||||
add_definitions(-fprofile-generate)
|
add_definitions(-fprofile-generate)
|
||||||
|
@ -354,6 +354,18 @@ o.f = fun(y) { print(this.x + y); }
|
|||||||
o.f(10); // prints 13
|
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
|
## method_missing
|
||||||
|
|
||||||
A function of the signature `method_missing(object, name, param1, param2, param3)` will be called if an appropriate
|
A function of the signature `method_missing(object, name, param1, param2, param3)` will be called if an appropriate
|
||||||
|
@ -440,6 +440,8 @@ namespace chaiscript
|
|||||||
m->add(constructor<dispatch::Dynamic_Object ()>(), "Dynamic_Object");
|
m->add(constructor<dispatch::Dynamic_Object ()>(), "Dynamic_Object");
|
||||||
m->add(fun(&dispatch::Dynamic_Object::get_type_name), "get_type_name");
|
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::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<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
||||||
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
||||||
|
@ -1002,6 +1002,7 @@ namespace chaiscript
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
if (!functions.empty()) {
|
if (!functions.empty()) {
|
||||||
|
try {
|
||||||
if (is_no_param) {
|
if (is_no_param) {
|
||||||
std::vector<Boxed_Value> tmp_params(params);
|
std::vector<Boxed_Value> tmp_params(params);
|
||||||
tmp_params.insert(tmp_params.begin() + 1, var(t_name));
|
tmp_params.insert(tmp_params.begin() + 1, var(t_name));
|
||||||
@ -1009,6 +1010,10 @@ namespace chaiscript
|
|||||||
} else {
|
} else {
|
||||||
return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, m_conversions);
|
return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, m_conversions);
|
||||||
}
|
}
|
||||||
|
} catch (const dispatch::option_explicit_set &e) {
|
||||||
|
throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()),
|
||||||
|
e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get all the way down here we know there was no "method_missing"
|
// If we get all the way down here we know there was no "method_missing"
|
||||||
|
@ -24,18 +24,38 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace dispatch
|
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
|
class Dynamic_Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Object(std::string t_type_name)
|
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
|
std::string get_type_name() const
|
||||||
{
|
{
|
||||||
return m_type_name;
|
return m_type_name;
|
||||||
@ -69,11 +89,19 @@ namespace chaiscript
|
|||||||
|
|
||||||
Boxed_Value &method_missing(const std::string &t_method_name)
|
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);
|
return get_attr(t_method_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Boxed_Value &method_missing(const std::string &t_method_name) const
|
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);
|
return get_attr(t_method_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +113,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_type_name;
|
std::string m_type_name;
|
||||||
|
bool m_option_explicit;
|
||||||
|
|
||||||
std::map<std::string, Boxed_Value> m_attrs;
|
std::map<std::string, Boxed_Value> m_attrs;
|
||||||
};
|
};
|
||||||
|
@ -760,6 +760,14 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch_error(std::vector<Boxed_Value> t_parameters,
|
||||||
|
std::vector<Const_Proxy_Function> 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;
|
dispatch_error(const dispatch_error &) = default;
|
||||||
virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}
|
||||||
|
|
||||||
|
14
unittests/dynamic_object_dynamic_attrs_explicit.chai
Normal file
14
unittests/dynamic_object_dynamic_attrs_explicit.chai
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
class MyClass {
|
||||||
|
def MyClass()
|
||||||
|
{
|
||||||
|
this.set_explicit(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var o = MyClass();
|
||||||
|
|
||||||
|
assert_true(o.is_explicit());
|
||||||
|
|
||||||
|
assert_throws("error", fun[o](){o.x = 2})
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user