From 9f30d84f3950a1d48de5abb02e6dede135462012 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 26 Oct 2016 12:29:30 -0600 Subject: [PATCH 1/2] Add conversion to bool tests as conditionals --- unittests/conversion_to_bool.chai | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 unittests/conversion_to_bool.chai 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); +} + From 0d4a99af82d8cb077ed71a0fbbe703d027affa3e Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 26 Oct 2016 13:41:15 -0600 Subject: [PATCH 2/2] Enable conversion to bool in conditionals closes #295 --- cheatsheet.md | 28 +++++++++++++++++++ .../chaiscript/language/chaiscript_common.hpp | 4 +-- .../chaiscript/language/chaiscript_eval.hpp | 18 ++++++------ 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/cheatsheet.md b/cheatsheet.md index c37045f..6314728 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -84,6 +84,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: ``` @@ -97,6 +124,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 b44a5a3..6562938 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -489,9 +489,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 000257e..ae26fec 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -809,7 +809,7 @@ namespace chaiscript chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); try { - while (get_bool_condition(this->children[0]->eval(t_ss))) { + while (get_bool_condition(this->children[0]->eval(t_ss), t_ss)) { try { this->children[1]->eval(t_ss); } catch (detail::Continue_Loop &) { @@ -851,7 +851,7 @@ namespace chaiscript { assert(children.size() == 3); } virtual ~Ternary_Cond_AST_Node() {} virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE { - if (get_bool_condition(children[0]->eval(t_ss))) { + if (get_bool_condition(children[0]->eval(t_ss), t_ss)) { return children[1]->eval(t_ss); } else { @@ -868,7 +868,7 @@ namespace chaiscript virtual ~If_AST_Node() {} virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{ - if (get_bool_condition(children[0]->eval(t_ss))) { + if (get_bool_condition(children[0]->eval(t_ss), t_ss)) { return children[1]->eval(t_ss); } else { if (children.size() > 2) { @@ -878,7 +878,7 @@ namespace chaiscript return children[i+1]->eval(t_ss); } else if (children[i]->text == "else if") { - if (get_bool_condition(children[i+1]->eval(t_ss))) { + if (get_bool_condition(children[i+1]->eval(t_ss), t_ss)) { return children[i+2]->eval(t_ss); } } @@ -905,7 +905,7 @@ namespace chaiscript try { for ( children[0]->eval(t_ss); - get_bool_condition(children[1]->eval(t_ss)); + get_bool_condition(children[1]->eval(t_ss), t_ss); children[2]->eval(t_ss) ) { try { @@ -1498,8 +1498,8 @@ namespace chaiscript virtual ~Logical_And_AST_Node() {} virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{ - return const_var(get_bool_condition(children[0]->eval(t_ss)) - && get_bool_condition(children[2]->eval(t_ss))); + return const_var(get_bool_condition(children[0]->eval(t_ss), t_ss) + && get_bool_condition(children[2]->eval(t_ss), t_ss)); } virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE @@ -1515,8 +1515,8 @@ namespace chaiscript { assert(children.size() == 3); } virtual ~Logical_Or_AST_Node() {} virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{ - return const_var(get_bool_condition(children[0]->eval(t_ss)) - || get_bool_condition(children[2]->eval(t_ss))); + return const_var(get_bool_condition(children[0]->eval(t_ss), t_ss) + || get_bool_condition(children[2]->eval(t_ss), t_ss)); } virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE