diff --git a/cheatsheet.md b/cheatsheet.md index b6c2fc4..3a22508 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -91,6 +91,33 @@ chai.add(chaiscript::user_type(), "MyClass"); User defined type conversions are possible, defined in either script or in C++. + +### ChaiScript Defined Conversions + +Function objects (including lambdas) can be used to add type conversions +from inside of ChaiScript: + +``` +add_type_conversion(type("string"), type("Type_Info"), fun(s) { return type(s); }); +``` + +### C++ Defined Conversions + +Invoking a C++ type conversion possible with `static_cast` + +``` +chai.add(chaiscript::type_conversion()); +``` + +Calling a user defined type conversion that takes a lambda + +``` +chai.add(chaiscript::type_conversion([](const TestBaseType &t_bt) { /* return converted thing */ })); +``` + + +### Helpers + A helper function exists for strongly typed and ChaiScript `Vector` function conversion definition: ``` @@ -104,6 +131,7 @@ chai.add(chaiscript::map_conversion>()); ``` + This allows you to pass a ChaiScript function to a function requiring `std::vector` ## Adding Objects diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 2e8e05c..7a70892 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -537,9 +537,9 @@ namespace chaiscript } - static bool get_bool_condition(const Boxed_Value &t_bv) { + static bool get_bool_condition(const Boxed_Value &t_bv, const chaiscript::detail::Dispatch_State &t_ss) { try { - return boxed_cast(t_bv); + return t_ss->boxed_cast(t_bv); } catch (const exception::bad_boxed_cast &) { throw exception::eval_error("Condition not boolean"); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 58be8a0..76706ff 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -773,7 +773,7 @@ namespace chaiscript chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); try { - while (this->get_bool_condition(this->children[0]->eval(t_ss))) { + while (this->get_bool_condition(this->children[0]->eval(t_ss), t_ss)) { try { this->children[1]->eval(t_ss); } catch (detail::Continue_Loop &) { @@ -815,13 +815,12 @@ namespace chaiscript { assert(this->children.size() == 3); } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - if (this->get_bool_condition(this->children[0]->eval(t_ss))) { + if (this->get_bool_condition(this->children[0]->eval(t_ss), t_ss)) { return this->children[1]->eval(t_ss); } else { return this->children[2]->eval(t_ss); } } - }; @@ -834,7 +833,7 @@ namespace chaiscript } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - if (this->get_bool_condition(this->children[0]->eval(t_ss))) { + if (this->get_bool_condition(this->children[0]->eval(t_ss), t_ss)) { return this->children[1]->eval(t_ss); } else { return this->children[2]->eval(t_ss); @@ -932,7 +931,7 @@ namespace chaiscript try { for ( this->children[0]->eval(t_ss); - this->get_bool_condition(this->children[1]->eval(t_ss)); + this->get_bool_condition(this->children[1]->eval(t_ss), t_ss); this->children[2]->eval(t_ss) ) { try { @@ -1482,8 +1481,8 @@ namespace chaiscript Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - return const_var(this->get_bool_condition(this->children[0]->eval(t_ss)) - && this->get_bool_condition(this->children[1]->eval(t_ss))); + return const_var(this->get_bool_condition(this->children[0]->eval(t_ss), t_ss) + && this->get_bool_condition(this->children[1]->eval(t_ss), t_ss)); } }; @@ -1496,8 +1495,8 @@ namespace chaiscript Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - return const_var(this->get_bool_condition(this->children[0]->eval(t_ss)) - || this->get_bool_condition(this->children[1]->eval(t_ss))); + return const_var(this->get_bool_condition(this->children[0]->eval(t_ss), t_ss) + || this->get_bool_condition(this->children[1]->eval(t_ss), t_ss)); } }; } diff --git a/unittests/conversion_to_bool.chai b/unittests/conversion_to_bool.chai new file mode 100644 index 0000000..d5512bf --- /dev/null +++ b/unittests/conversion_to_bool.chai @@ -0,0 +1,17 @@ + +// all we care is that this executes, really + +add_type_conversion(type("int"), type("bool"), fun(int i) { return i != 0; }); + +if (0) { + assert_true(false); +} + +while (0) { + assert_true(false); +} + +for (; 0; ) { + assert_true(false); +} +