diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index b65d5e3..c953886 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -171,6 +171,24 @@ namespace chaiscript } } + template + static Boxed_Value unary_go(Operators::Opers t_oper, T &t, const Boxed_Value &t_lhs) + { + switch (t_oper) + { + case Operators::pre_increment: + ++t; + break; + case Operators::pre_decrement: + --t; + break; + default: + throw chaiscript::detail::exception::bad_any_cast(); + } + + return t_lhs; + } + template static Boxed_Value binary_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) { @@ -179,12 +197,6 @@ namespace chaiscript case Operators::assign: t = u; break; - case Operators::pre_increment: - ++t; - break; - case Operators::pre_decrement: - --t; - break; case Operators::assign_product: t *= u; break; @@ -235,6 +247,18 @@ namespace chaiscript return t_lhs; } + template + static Boxed_Value const_unary_int_go(Operators::Opers t_oper, const T &t) + { + switch (t_oper) + { + case Operators::bitwise_complement: + return const_var(~t); + default: + throw chaiscript::detail::exception::bad_any_cast(); + } + } + template static Boxed_Value const_binary_int_go(Operators::Opers t_oper, const T &t, const T &u) { @@ -253,8 +277,20 @@ namespace chaiscript return const_var(t | u); case Operators::bitwise_xor: return const_var(t ^ u); - case Operators::bitwise_complement: - return const_var(~t); + default: + throw chaiscript::detail::exception::bad_any_cast(); + } + } + + template + static Boxed_Value const_unary_go(Operators::Opers t_oper, const T &t) + { + switch (t_oper) + { + case Operators::unary_minus: + return const_var(-t); + case Operators::unary_plus: + return const_var(+t); default: throw chaiscript::detail::exception::bad_any_cast(); } @@ -274,10 +310,6 @@ namespace chaiscript return const_var(t * u); case Operators::difference: return const_var(t - u); - case Operators::unary_minus: - return const_var(-t); - case Operators::unary_plus: - return const_var(+t); default: throw chaiscript::detail::exception::bad_any_cast(); } @@ -314,10 +346,6 @@ namespace chaiscript return boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { return binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs), t_lhs); - } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { - throw chaiscript::detail::exception::bad_any_cast(); - } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { - throw chaiscript::detail::exception::bad_any_cast(); } else if (t_oper > Operators::const_flag) { return const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); } else { @@ -325,6 +353,35 @@ namespace chaiscript } } + // Unary + template + static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) + -> typename std::enable_if::value, Boxed_Value>::type + { + if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + return unary_go(t_oper, *static_cast(t_lhs.get_ptr()), t_lhs); + } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { + return const_unary_int_go(t_oper, *static_cast(t_lhs.get_const_ptr())); + } else if (t_oper > Operators::const_flag) { + return const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + } + + template + static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) + -> typename std::enable_if::value, Boxed_Value>::type + { + if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + return unary_go(t_oper, *static_cast(t_lhs.get_ptr()), t_lhs); + } else if (t_oper > Operators::const_flag) { + return const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + } + template inline static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { @@ -354,7 +411,38 @@ namespace chaiscript } throw chaiscript::detail::exception::bad_any_cast(); - } + } + + inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs) + { + switch (get_common_type(t_lhs)) { + case Common_Types::t_int32: + return go(t_oper, t_lhs); + case Common_Types::t_uint8: + return go(t_oper, t_lhs); + case Common_Types::t_int8: + return go(t_oper, t_lhs); + case Common_Types::t_uint16: + return go(t_oper, t_lhs); + case Common_Types::t_int16: + return go(t_oper, t_lhs); + case Common_Types::t_uint32: + return go(t_oper, t_lhs); + case Common_Types::t_uint64: + return go(t_oper, t_lhs); + case Common_Types::t_int64: + return go(t_oper, t_lhs); + case Common_Types::t_double: + return go(t_oper, t_lhs); + case Common_Types::t_float: + return go(t_oper, t_lhs); + case Common_Types::t_long_double: + return go(t_oper, t_lhs); + } + + throw chaiscript::detail::exception::bad_any_cast(); + } + inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { @@ -565,12 +653,12 @@ namespace chaiscript Boxed_Number operator--() { - return oper(Operators::pre_decrement, this->bv, var(0)); + return oper(Operators::pre_decrement, this->bv); } Boxed_Number operator++() { - return oper(Operators::pre_increment, this->bv, var(0)); + return oper(Operators::pre_increment, this->bv); } Boxed_Number operator+(const Boxed_Number &t_rhs) const @@ -580,12 +668,12 @@ namespace chaiscript Boxed_Number operator+() const { - return oper(Operators::unary_plus, this->bv, Boxed_Value(0)); + return oper(Operators::unary_plus, this->bv); } Boxed_Number operator-() const { - return oper(Operators::unary_minus, this->bv, Boxed_Value(0)); + return oper(Operators::unary_minus, this->bv); } Boxed_Number operator-(const Boxed_Number &t_rhs) const @@ -658,7 +746,7 @@ namespace chaiscript Boxed_Number operator~() const { - return oper(Operators::bitwise_complement, this->bv, Boxed_Value(0)); + return oper(Operators::bitwise_complement, this->bv); } Boxed_Number operator^(const Boxed_Number &t_rhs) const @@ -747,12 +835,12 @@ namespace chaiscript static Boxed_Number pre_decrement(Boxed_Number t_lhs) { - return oper(Operators::pre_decrement, t_lhs.bv, var(0)); + return oper(Operators::pre_decrement, t_lhs.bv); } static Boxed_Number pre_increment(Boxed_Number t_lhs) { - return oper(Operators::pre_increment, t_lhs.bv, var(0)); + return oper(Operators::pre_increment, t_lhs.bv); } static const Boxed_Number sum(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) @@ -762,12 +850,12 @@ namespace chaiscript static const Boxed_Number unary_plus(const Boxed_Number &t_lhs) { - return oper(Operators::unary_plus, t_lhs.bv, Boxed_Value(0)); + return oper(Operators::unary_plus, t_lhs.bv); } static const Boxed_Number unary_minus(const Boxed_Number &t_lhs) { - return oper(Operators::unary_minus, t_lhs.bv, Boxed_Value(0)); + return oper(Operators::unary_minus, t_lhs.bv); } static const Boxed_Number difference(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) @@ -883,7 +971,7 @@ namespace chaiscript static Boxed_Value do_oper(Operators::Opers t_oper, const Boxed_Value &t_lhs) { - return oper(t_oper, t_lhs, const_var(0)); + return oper(t_oper, t_lhs); } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index e56e0f2..3c84eaa 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1151,7 +1151,7 @@ namespace chaiscript // short circuit arithmetic operations if (m_oper != Operators::invalid && bv.get_type_info().is_arithmetic()) { - return Boxed_Number::do_oper(m_oper, std::move(bv)); + return Boxed_Number::do_oper(m_oper, bv); } else { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);