From bba1ffde38322c56d3b8816d45bf9f7a53e0d127 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 24 May 2011 12:39:39 -0600 Subject: [PATCH 01/11] Rename Boxed_POD_Value to Boxed_Numeric, which is more correct. --- include/chaiscript/chaiscript.hpp | 2 +- include/chaiscript/dispatchkit/bootstrap.hpp | 98 +++++++++---------- ...{boxed_pod_value.hpp => boxed_numeric.hpp} | 56 +++++------ .../chaiscript/dispatchkit/dispatchkit.hpp | 2 +- .../dispatchkit/proxy_functions.hpp | 4 +- unittests/boxed_cast_test.cpp | 16 +-- 6 files changed, 89 insertions(+), 89 deletions(-) rename include/chaiscript/dispatchkit/{boxed_pod_value.hpp => boxed_numeric.hpp} (76%) diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index 85d704fc..0d1e3565 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -563,7 +563,7 @@ #include "dispatchkit/bootstrap_stl.hpp" #include "dispatchkit/function_call.hpp" #include "dispatchkit/dynamic_object.hpp" -#include "dispatchkit/boxed_pod_value.hpp" +#include "dispatchkit/boxed_numeric.hpp" #ifdef BOOST_HAS_DECLSPEC #define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index d8f62ac5..49a3aa76 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -11,7 +11,7 @@ #include "dynamic_object.hpp" #include "register_function.hpp" #include "operators.hpp" -#include "boxed_pod_value.hpp" +#include "boxed_numeric.hpp" #include namespace chaiscript @@ -22,13 +22,13 @@ namespace chaiscript namespace detail { - /// \brief Assigns a POD value from a Boxed_POD_Value. Helps support operators between + /// \brief Assigns a POD value from a Boxed_Numeric. Helps support operators between /// disparate POD types. /// \param[in,out] p1 object to assign to - /// \param[in] v Boxed_POD_Value to assign from + /// \param[in] v Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_pod(P1 &p1, const Boxed_POD_Value &v) + P1 &assign_pod(P1 &p1, const Boxed_Numeric &v) { if (v.isfloat) { @@ -38,11 +38,11 @@ namespace chaiscript } } - /// \brief Constructs a new POD value object from a Boxed_POD_Value - /// \param[in] v Boxed_POD_Value to copy into the new object + /// \brief Constructs a new POD value object from a Boxed_Numeric + /// \param[in] v Boxed_Numeric to copy into the new object /// \returns The newly created object. template - P1 construct_pod(Boxed_POD_Value v) + P1 construct_pod(Boxed_Numeric v) { if (v.isfloat) { @@ -52,12 +52,12 @@ namespace chaiscript } } - /// \brief Performs a bitwise and assignment (&=) on the given object with the given Boxed_POD_Value + /// \brief Performs a bitwise and assignment (&=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to bitwise and assign to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_bitwise_and_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_bitwise_and_pod(P1 &p1, Boxed_Numeric r) { if (!r.isfloat) { @@ -67,12 +67,12 @@ namespace chaiscript throw exception::bad_boxed_cast("&= only valid for integer types"); } - /// \brief Performs a xor assignment (^=) on the given object with the given Boxed_POD_Value + /// \brief Performs a xor assignment (^=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to xor assign to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_xor_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_xor_pod(P1 &p1, Boxed_Numeric r) { if (!r.isfloat) { @@ -82,12 +82,12 @@ namespace chaiscript throw exception::bad_boxed_cast("^= only valid for integer types"); } - /// \brief Performs a bitwise or assignment (|=) on the given object with the given Boxed_POD_Value + /// \brief Performs a bitwise or assignment (|=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to bitwise or assign to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_bitwise_or_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_bitwise_or_pod(P1 &p1, Boxed_Numeric r) { if (!r.isfloat) { @@ -97,12 +97,12 @@ namespace chaiscript throw exception::bad_boxed_cast("&= only valid for integer types"); } - /// \brief Performs an assign difference (-=) on the given object with the given Boxed_POD_Value + /// \brief Performs an assign difference (-=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to difference assign to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_difference_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_difference_pod(P1 &p1, Boxed_Numeric r) { if (r.isfloat) { @@ -112,12 +112,12 @@ namespace chaiscript } } - /// \brief Performs an assign shift left (<<=) on the given object with the given Boxed_POD_Value + /// \brief Performs an assign shift left (<<=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to assign shift left to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_left_shift_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_left_shift_pod(P1 &p1, Boxed_Numeric r) { if (!r.isfloat) { @@ -128,12 +128,12 @@ namespace chaiscript } - /// \brief Performs an assign product (*=) on the given object with the given Boxed_POD_Value + /// \brief Performs an assign product (*=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to assign product to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_product_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_product_pod(P1 &p1, Boxed_Numeric r) { if (r.isfloat) { @@ -143,12 +143,12 @@ namespace chaiscript } } - /// \brief Performs an assign quotient (/=) on the given object with the given Boxed_POD_Value + /// \brief Performs an assign quotient (/=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to assign quotient to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_quotient_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_quotient_pod(P1 &p1, Boxed_Numeric r) { if (r.isfloat) { @@ -158,12 +158,12 @@ namespace chaiscript } } - /// \brief Performs an assign remainder (%=) on the given object with the given Boxed_POD_Value + /// \brief Performs an assign remainder (%=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to assign remainder to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_remainder_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_remainder_pod(P1 &p1, Boxed_Numeric r) { if (!r.isfloat) { @@ -174,12 +174,12 @@ namespace chaiscript } - /// \brief Performs an assign shift right (>>=) on the given object with the given Boxed_POD_Value + /// \brief Performs an assign shift right (>>=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to assign shift right to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_right_shift_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_right_shift_pod(P1 &p1, Boxed_Numeric r) { if (!r.isfloat) { @@ -189,12 +189,12 @@ namespace chaiscript throw exception::bad_boxed_cast(">>= only valid for integer types"); } - /// \brief Performs an assign sum (+=) on the given object with the given Boxed_POD_Value + /// \brief Performs an assign sum (+=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to sum assign to - /// \param[in] r Boxed_POD_Value to assign from + /// \param[in] r Boxed_Numeric to assign from /// \returns Reference to p1, to support normal C assignment semantics template - P1 &assign_sum_pod(P1 &p1, Boxed_POD_Value r) + P1 &assign_sum_pod(P1 &p1, Boxed_Numeric r) { if (r.isfloat) { @@ -485,16 +485,16 @@ namespace chaiscript */ static void opers_arithmetic_pod(ModulePtr m = ModulePtr(new Module())) { - m->add(fun(&operators::addition), "+"); - m->add(fun(&operators::subtraction), "-"); - m->add(fun(&operators::bitwise_and), "&"); - m->add(fun(&operators::bitwise_xor), "^"); - m->add(fun(&operators::bitwise_or), "|"); - m->add(fun(&operators::division), "/"); - m->add(fun(&operators::left_shift), "<<"); - m->add(fun(&operators::multiplication), "*"); - m->add(fun(&operators::remainder), "%"); - m->add(fun(&operators::right_shift), ">>"); + m->add(fun(&operators::addition), "+"); + m->add(fun(&operators::subtraction), "-"); + m->add(fun(&operators::bitwise_and), "&"); + m->add(fun(&operators::bitwise_xor), "^"); + m->add(fun(&operators::bitwise_or), "|"); + m->add(fun(&operators::division), "/"); + m->add(fun(&operators::left_shift), "<<"); + m->add(fun(&operators::multiplication), "*"); + m->add(fun(&operators::remainder), "%"); + m->add(fun(&operators::right_shift), ">>"); } /** @@ -619,7 +619,7 @@ namespace chaiscript m->add(user_type(), "void"); m->add(user_type(), "bool"); m->add(user_type(), "Object"); - m->add(user_type(), "PODObject"); + m->add(user_type(), "PODObject"); m->add(user_type(), "Function"); m->add(user_type(), "exception"); @@ -694,7 +694,7 @@ namespace chaiscript operators::logical_compliment(m); - opers_comparison(m); + opers_comparison(m); opers_arithmetic_pod(m); diff --git a/include/chaiscript/dispatchkit/boxed_pod_value.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp similarity index 76% rename from include/chaiscript/dispatchkit/boxed_pod_value.hpp rename to include/chaiscript/dispatchkit/boxed_numeric.hpp index 215eba01..3dd826aa 100644 --- a/include/chaiscript/dispatchkit/boxed_pod_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -4,8 +4,8 @@ // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com -#ifndef CHAISCRIPT_BOXED_POD_VALUE_HPP_ -#define CHAISCRIPT_BOXED_POD_VALUE_HPP_ +#ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_ +#define CHAISCRIPT_BOXED_NUMERIC_HPP_ #include "type_info.hpp" #include "boxed_value.hpp" @@ -18,10 +18,10 @@ namespace chaiscript { /// \brief Represents any numeric type, generically. Used internally for generic operations between POD values - class Boxed_POD_Value + class Boxed_Numeric { public: - Boxed_POD_Value(const Boxed_Value &v) + Boxed_Numeric(const Boxed_Value &v) : d(0), i(0), isfloat(false) { if (v.get_type_info().is_undef()) @@ -69,37 +69,37 @@ namespace chaiscript } } - bool operator==(const Boxed_POD_Value &r) const + bool operator==(const Boxed_Numeric &r) const { return ((isfloat)?d:i) == ((r.isfloat)?r.d:r.i); } - bool operator<(const Boxed_POD_Value &r) const + bool operator<(const Boxed_Numeric &r) const { return ((isfloat)?d:i) < ((r.isfloat)?r.d:r.i); } - bool operator>(const Boxed_POD_Value &r) const + bool operator>(const Boxed_Numeric &r) const { return ((isfloat)?d:i) > ((r.isfloat)?r.d:r.i); } - bool operator>=(const Boxed_POD_Value &r) const + bool operator>=(const Boxed_Numeric &r) const { return ((isfloat)?d:i) >= ((r.isfloat)?r.d:r.i); } - bool operator<=(const Boxed_POD_Value &r) const + bool operator<=(const Boxed_Numeric &r) const { return ((isfloat)?d:i) <= ((r.isfloat)?r.d:r.i); } - bool operator!=(const Boxed_POD_Value &r) const + bool operator!=(const Boxed_Numeric &r) const { return ((isfloat)?d:i) != ((r.isfloat)?r.d:r.i); } - Boxed_Value operator+(const Boxed_POD_Value &r) const + Boxed_Value operator+(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -109,7 +109,7 @@ namespace chaiscript return Boxed_Value(((isfloat)?d:i) + ((r.isfloat)?r.d:r.i)); } - Boxed_Value operator-(const Boxed_POD_Value &r) const + Boxed_Value operator-(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -119,7 +119,7 @@ namespace chaiscript return Boxed_Value(((isfloat)?d:i) - ((r.isfloat)?r.d:r.i)); } - Boxed_Value operator&(const Boxed_POD_Value &r) const + Boxed_Value operator&(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -129,7 +129,7 @@ namespace chaiscript throw exception::bad_boxed_cast("& only valid for integer types"); } - Boxed_Value operator^(const Boxed_POD_Value &r) const + Boxed_Value operator^(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -139,7 +139,7 @@ namespace chaiscript throw exception::bad_boxed_cast("^ only valid for integer types"); } - Boxed_Value operator|(const Boxed_POD_Value &r) const + Boxed_Value operator|(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -149,7 +149,7 @@ namespace chaiscript throw exception::bad_boxed_cast("| only valid for integer types"); } - Boxed_Value operator/(const Boxed_POD_Value &r) const + Boxed_Value operator/(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -159,7 +159,7 @@ namespace chaiscript return Boxed_Value(((isfloat)?d:i) / ((r.isfloat)?r.d:r.i)); } - Boxed_Value operator<<(const Boxed_POD_Value &r) const + Boxed_Value operator<<(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -170,7 +170,7 @@ namespace chaiscript } - Boxed_Value operator*(const Boxed_POD_Value &r) const + Boxed_Value operator*(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -181,7 +181,7 @@ namespace chaiscript } - Boxed_Value operator%(const Boxed_POD_Value &r) const + Boxed_Value operator%(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -191,7 +191,7 @@ namespace chaiscript throw exception::bad_boxed_cast("% only valid for integer types"); } - Boxed_Value operator>>(const Boxed_POD_Value &r) const + Boxed_Value operator>>(const Boxed_Numeric &r) const { if (!isfloat && !r.isfloat) { @@ -222,32 +222,32 @@ namespace chaiscript namespace detail { /** - * Cast_Helper for converting from Boxed_Value to Boxed_POD_Value + * Cast_Helper for converting from Boxed_Value to Boxed_Numeric */ template<> - struct Cast_Helper + struct Cast_Helper { - typedef Boxed_POD_Value Result_Type; + typedef Boxed_Numeric Result_Type; static Result_Type cast(const Boxed_Value &ob) { - return Boxed_POD_Value(ob); + return Boxed_Numeric(ob); } }; /** - * Cast_Helper for converting from Boxed_Value to Boxed_POD_Value + * Cast_Helper for converting from Boxed_Value to Boxed_Numeric */ template<> - struct Cast_Helper : Cast_Helper + struct Cast_Helper : Cast_Helper { }; /** - * Cast_Helper for converting from Boxed_Value to Boxed_POD_Value + * Cast_Helper for converting from Boxed_Value to Boxed_Numeric */ template<> - struct Cast_Helper : Cast_Helper + struct Cast_Helper : Cast_Helper { }; } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index c87acd6a..c2861491 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -811,7 +811,7 @@ namespace chaiscript const size_t rhssize = rhsparamtypes.size(); const Type_Info boxed_type = user_type(); - const Type_Info boxed_pod_type = user_type(); + const Type_Info boxed_pod_type = user_type(); boost::shared_ptr dynamic_lhs(boost::dynamic_pointer_cast(lhs)); boost::shared_ptr dynamic_rhs(boost::dynamic_pointer_cast(rhs)); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index a86a62cb..fa0c89d5 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -20,7 +20,7 @@ namespace chaiscript { - class Boxed_POD_Value; + class Boxed_Numeric; struct AST_Node; typedef boost::shared_ptr AST_NodePtr; @@ -139,7 +139,7 @@ namespace chaiscript if (ti.is_undef() || ti.bare_equal(user_type()) || (!bv.get_type_info().is_undef() - && (ti.bare_equal(user_type()) + && (ti.bare_equal(user_type()) || ti.bare_equal(bv.get_type_info()) || chaiscript::detail::dynamic_cast_converts(ti, bv.get_type_info()) || bv.get_type_info().bare_equal(user_type >()) diff --git a/unittests/boxed_cast_test.cpp b/unittests/boxed_cast_test.cpp index ab9b8820..ca53707f 100644 --- a/unittests/boxed_cast_test.cpp +++ b/unittests/boxed_cast_test.cpp @@ -86,14 +86,14 @@ bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTR passed &= test_type_conversion >(bv, ConstBoostConstRef); passed &= test_type_conversion &>(bv, ConstBoostRefRef); passed &= test_type_conversion &>(bv, ConstBoostConstRefRef); - passed &= test_type_conversion(bv, PODValue); - passed &= test_type_conversion(bv, ConstPODValue); - passed &= test_type_conversion(bv, false); - passed &= test_type_conversion(bv, ConstPODValueRef); - passed &= test_type_conversion(bv, false); - passed &= test_type_conversion(bv, false); - passed &= test_type_conversion(bv, false); - passed &= test_type_conversion(bv, false); + passed &= test_type_conversion(bv, PODValue); + passed &= test_type_conversion(bv, ConstPODValue); + passed &= test_type_conversion(bv, false); + passed &= test_type_conversion(bv, ConstPODValueRef); + passed &= test_type_conversion(bv, false); + passed &= test_type_conversion(bv, false); + passed &= test_type_conversion(bv, false); + passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, TPtrConstRef); From 1845114d367fbeab603587395bc6d624a031815c Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 26 May 2011 05:58:19 -0600 Subject: [PATCH 02/11] Progress towards eliminating arithmetic operators on a per-type basis --- include/chaiscript/dispatchkit/bootstrap.hpp | 111 ++------ .../chaiscript/dispatchkit/boxed_numeric.hpp | 249 ++++++++++++++++-- include/chaiscript/dispatchkit/type_info.hpp | 18 +- 3 files changed, 263 insertions(+), 115 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 49a3aa76..7c593668 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -97,21 +97,6 @@ namespace chaiscript throw exception::bad_boxed_cast("&= only valid for integer types"); } - /// \brief Performs an assign difference (-=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to difference assign to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_difference_pod(P1 &p1, Boxed_Numeric r) - { - if (r.isfloat) - { - return p1 -= P1(r.d); - } else { - return p1 -= P1(r.i); - } - } - /// \brief Performs an assign shift left (<<=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to assign shift left to /// \param[in] r Boxed_Numeric to assign from @@ -128,36 +113,6 @@ namespace chaiscript } - /// \brief Performs an assign product (*=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to assign product to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_product_pod(P1 &p1, Boxed_Numeric r) - { - if (r.isfloat) - { - return p1 *= P1(r.d); - } else { - return p1 *= P1(r.i); - } - } - - /// \brief Performs an assign quotient (/=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to assign quotient to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_quotient_pod(P1 &p1, Boxed_Numeric r) - { - if (r.isfloat) - { - return p1 /= P1(r.d); - } else { - return p1 /= P1(r.i); - } - } - /// \brief Performs an assign remainder (%=) on the given object with the given Boxed_Numeric /// \param[in,out] p1 object to assign remainder to /// \param[in] r Boxed_Numeric to assign from @@ -189,20 +144,6 @@ namespace chaiscript throw exception::bad_boxed_cast(">>= only valid for integer types"); } - /// \brief Performs an assign sum (+=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to sum assign to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_sum_pod(P1 &p1, Boxed_Numeric r) - { - if (r.isfloat) - { - return p1 += P1(r.d); - } else { - return p1 += P1(r.i); - } - } } @@ -234,27 +175,27 @@ namespace chaiscript operators::assign_bitwise_and(m); operators::assign_xor(m); operators::assign_bitwise_or(m); - operators::assign_difference(m); +// operators::assign_difference(m); operators::assign_left_shift(m); - operators::assign_product(m); - operators::assign_quotient(m); - operators::assign_remainder(m); +// operators::assign_product(m); +// operators::assign_quotient(m); +// operators::assign_remainder(m); operators::assign_right_shift(m); - operators::assign_sum(m); +// operators::assign_sum(m); - operators::prefix_decrement(m); - operators::prefix_increment(m); - operators::addition(m); +// operators::prefix_decrement(m); +// operators::prefix_increment(m); +// operators::addition(m); operators::unary_plus(m); - operators::subtraction(m); +// operators::subtraction(m); operators::unary_minus(m); operators::bitwise_and(m); operators::bitwise_compliment(m); operators::bitwise_xor(m); operators::bitwise_or(m); - operators::division(m); +// operators::division(m); operators::left_shift(m); - operators::multiplication(m); +// operators::multiplication(m); operators::remainder(m); operators::right_shift(m); return m; @@ -268,17 +209,17 @@ namespace chaiscript template ModulePtr opers_float_arithmetic(ModulePtr m = ModulePtr(new Module())) { - operators::assign_difference(m); - operators::assign_product(m); - operators::assign_quotient(m); - operators::assign_sum(m); +// operators::assign_difference(m); +// operators::assign_product(m); +// operators::assign_quotient(m); +// operators::assign_sum(m); - operators::addition(m); +// operators::addition(m); operators::unary_plus(m); - operators::subtraction(m); +// operators::subtraction(m); operators::unary_minus(m); - operators::division(m); - operators::multiplication(m); +// operators::division(m); +// operators::multiplication(m); return m; } @@ -365,10 +306,10 @@ namespace chaiscript oper_assign_pod(m); construct_pod(name, m); - m->add(fun(&detail::assign_sum_pod), "+="); - m->add(fun(&detail::assign_difference_pod), "-="); - m->add(fun(&detail::assign_product_pod), "*="); - m->add(fun(&detail::assign_quotient_pod), "/="); +// m->add(fun(&detail::assign_sum_pod), "+="); +// m->add(fun(&detail::assign_difference_pod), "-="); +// m->add(fun(&detail::assign_product_pod), "*="); +// m->add(fun(&detail::assign_quotient_pod), "/="); m->add(fun(&to_string), "to_string"); m->add(fun(&parse_string), "to_" + name); @@ -495,6 +436,12 @@ namespace chaiscript m->add(fun(&operators::multiplication), "*"); m->add(fun(&operators::remainder), "%"); m->add(fun(&operators::right_shift), ">>"); + m->add(fun(&Boxed_Numeric::operator*=), "*="); + m->add(fun(&Boxed_Numeric::operator/=), "/="); + m->add(fun(&Boxed_Numeric::operator+=), "+="); + m->add(fun(&Boxed_Numeric::operator-=), "-="); + m->add(fun(&Boxed_Numeric::operator--), "--"); + m->add(fun(&Boxed_Numeric::operator++), "++"); } /** diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 3dd826aa..1c406404 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -20,17 +20,200 @@ namespace chaiscript /// \brief Represents any numeric type, generically. Used internally for generic operations between POD values class Boxed_Numeric { + private: + template + struct choose_const + { + typedef T& type; + }; + + template + struct choose_const + { + typedef const T& type; + }; + + template + struct lhs_type + { + typedef typename choose_const::type type; + }; + + struct equals + { + static const bool lhs_const = true; + template + static bool go(const T &t, const U &u) { return t == u; } + }; + + struct add + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t + u); } + }; + + struct subtract + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t - u); } + }; + + struct multiply + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t * u); } + }; + + struct divide + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t / u); } + }; + + struct assign_product + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t *= u)); } + }; + + struct assign_quotient + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t /= u)); } + }; + + struct assign_sum + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t += u)); } + }; + + struct assign_difference + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t -= u)); } + }; + + struct pre_increment + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U) { return var(&++t); } + }; + + struct pre_decrement + { + static const bool lhs_const = false; + + template + static Boxed_Value go(boost::reference_wrapper, const U) { std::cout<< "why where?"<< std::endl; throw boost::bad_any_cast(); } + + template + static Boxed_Value go(T &t, const U) { return var(&--t); } + }; + + template + static Ret oper_lhs(L l, const Boxed_Numeric &r) + { + const Type_Info &inp_ = r.bv.get_type_info(); + + if (inp_ == typeid(double)) + { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(float)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(bool)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(char)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(int)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(unsigned int)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(long)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(unsigned long)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int8_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int16_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int32_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int64_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint8_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint16_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint32_t)) { + return O::go(l, boxed_cast(r.bv)); + } else { + throw boost::bad_any_cast(); + } + } + + template + static Ret oper(const Boxed_Numeric &l, const Boxed_Numeric &r) + { + const Type_Info &inp_ = l.bv.get_type_info(); + + if (inp_ == typeid(double)) + { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(float)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(bool)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(char)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(int)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(unsigned int)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(long)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(unsigned long)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int8_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int16_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int32_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int64_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint8_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint16_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint32_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else { + throw boost::bad_any_cast(); + } + }; + + public: Boxed_Numeric(const Boxed_Value &v) - : d(0), i(0), isfloat(false) + : bv(v), d(0), i(0), isfloat(false) { - if (v.get_type_info().is_undef()) + const Type_Info &inp_ = v.get_type_info(); + + if (!inp_.is_arithmetic()) { throw boost::bad_any_cast(); } - const Type_Info &inp_ = v.get_type_info(); - if (inp_ == typeid(double)) { d = boxed_cast(v); @@ -71,7 +254,7 @@ namespace chaiscript bool operator==(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) == ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator<(const Boxed_Numeric &r) const @@ -99,24 +282,24 @@ namespace chaiscript return ((isfloat)?d:i) != ((r.isfloat)?r.d:r.i); } + Boxed_Value operator--() const + { + return oper(*this, var(0)); + } + + Boxed_Value operator++() const + { + return oper(*this, var(0)); + } + Boxed_Value operator+(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return smart_size(i + r.i); - } - - return Boxed_Value(((isfloat)?d:i) + ((r.isfloat)?r.d:r.i)); + return oper(*this, r); } Boxed_Value operator-(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return smart_size(i - r.i); - } - - return Boxed_Value(((isfloat)?d:i) - ((r.isfloat)?r.d:r.i)); + return oper(*this, r); } Boxed_Value operator&(const Boxed_Numeric &r) const @@ -149,14 +332,26 @@ namespace chaiscript throw exception::bad_boxed_cast("| only valid for integer types"); } + Boxed_Value operator*=(const Boxed_Numeric &r) const + { + return oper(*this, r); + } + Boxed_Value operator/=(const Boxed_Numeric &r) const + { + return oper(*this, r); + } + Boxed_Value operator+=(const Boxed_Numeric &r) const + { + return oper(*this, r); + } + Boxed_Value operator-=(const Boxed_Numeric &r) const + { + return oper(*this, r); + } + Boxed_Value operator/(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return smart_size(i / r.i); - } - - return Boxed_Value(((isfloat)?d:i) / ((r.isfloat)?r.d:r.i)); + return oper(*this, r); } Boxed_Value operator<<(const Boxed_Numeric &r) const @@ -172,12 +367,7 @@ namespace chaiscript Boxed_Value operator*(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return smart_size(i * r.i); - } - - return Boxed_Value(((isfloat)?d:i) * ((r.isfloat)?r.d:r.i)); + return oper(*this, r); } @@ -213,6 +403,7 @@ namespace chaiscript } + Boxed_Value bv; double d; boost::int64_t i; diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 605fbb6c..acbdbad1 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -36,9 +37,9 @@ namespace chaiscript { public: Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, - const std::type_info *t_ti, const std::type_info *t_bareti) + bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bareti) : m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer), - m_is_void(t_is_void), + m_is_void(t_is_void), m_is_arithmetic(t_is_arithmetic), m_type_info(t_ti), m_bare_type_info(t_bareti), m_is_undef(false) { @@ -46,7 +47,7 @@ namespace chaiscript Type_Info() : m_is_const(false), m_is_reference(false), m_is_pointer(false), - m_is_void(false), m_type_info(0), m_bare_type_info(0), + m_is_void(false), m_is_arithmetic(false), m_type_info(0), m_bare_type_info(0), m_is_undef(true) { } @@ -54,7 +55,8 @@ namespace chaiscript Type_Info(const Type_Info &ti) : m_is_const(ti.m_is_const), m_is_reference(ti.m_is_reference), m_is_pointer(ti.m_is_pointer), - m_is_void(ti.m_is_void), m_type_info(ti.m_type_info), + m_is_void(ti.m_is_void), m_is_arithmetic(ti.m_is_arithmetic), + m_type_info(ti.m_type_info), m_bare_type_info(ti.m_bare_type_info), m_is_undef(ti.m_is_undef) { @@ -66,6 +68,7 @@ namespace chaiscript m_is_reference = ti.m_is_reference; m_is_pointer = ti.m_is_pointer; m_is_void = ti.m_is_void; + m_is_arithmetic = ti.m_is_arithmetic; m_type_info = ti.m_type_info; m_bare_type_info = ti.m_bare_type_info; m_is_undef = ti.m_is_undef; @@ -97,6 +100,7 @@ namespace chaiscript bool is_const() const { return m_is_const; } bool is_reference() const { return m_is_reference; } bool is_void() const { return m_is_void; } + bool is_arithmetic() const { return m_is_arithmetic; } bool is_undef() const { return m_is_undef || m_bare_type_info == 0; } bool is_pointer() const { return m_is_pointer; } @@ -125,6 +129,7 @@ namespace chaiscript bool m_is_reference; bool m_is_pointer; bool m_is_void; + bool m_is_arithmetic; const std::type_info *m_type_info; const std::type_info *m_bare_type_info; bool m_is_undef; @@ -144,6 +149,7 @@ namespace chaiscript { return Type_Info(boost::is_const::type>::type>::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, + boost::is_arithmetic::value, &typeid(T), &typeid(typename Bare_Type::type)); } @@ -158,6 +164,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, + boost::is_arithmetic::value, &typeid(boost::shared_ptr ), &typeid(typename Bare_Type::type)); } @@ -172,6 +179,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, + boost::is_arithmetic::value, &typeid(const boost::shared_ptr &), &typeid(typename Bare_Type::type)); } @@ -186,6 +194,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, + boost::is_arithmetic::value, &typeid(boost::reference_wrapper ), &typeid(typename Bare_Type::type)); } @@ -200,6 +209,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, + boost::is_arithmetic::value, &typeid(const boost::reference_wrapper &), &typeid(typename Bare_Type::type)); } From 6993d58fdc3dfa1d119e6a573f3411f131f16416 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 28 May 2011 23:48:17 -0600 Subject: [PATCH 03/11] wrap up support for all built in C++ Arithmetic types --- include/chaiscript/dispatchkit/bootstrap.hpp | 317 +++----------- .../chaiscript/dispatchkit/boxed_numeric.hpp | 398 +++++++++++++----- 2 files changed, 364 insertions(+), 351 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 7c593668..b1918927 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -21,130 +21,30 @@ namespace chaiscript { namespace detail { - - /// \brief Assigns a POD value from a Boxed_Numeric. Helps support operators between - /// disparate POD types. - /// \param[in,out] p1 object to assign to - /// \param[in] v Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_pod(P1 &p1, const Boxed_Numeric &v) - { - if (v.isfloat) - { - return (p1 = P1(v.d)); - } else { - return (p1 = P1(v.i)); - } - } - /// \brief Constructs a new POD value object from a Boxed_Numeric /// \param[in] v Boxed_Numeric to copy into the new object /// \returns The newly created object. template - P1 construct_pod(Boxed_Numeric v) + boost::shared_ptr construct_pod(Boxed_Numeric v) { - if (v.isfloat) - { - return P1(v.d); - } else { - return P1(v.i); - } + boost::shared_ptr p(new P1()); + Boxed_Value bv(p); + Boxed_Numeric nb(bv); + nb = v; + return p; } + } - /// \brief Performs a bitwise and assignment (&=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to bitwise and assign to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_bitwise_and_pod(P1 &p1, Boxed_Numeric r) - { - if (!r.isfloat) - { - return p1 &= P1(r.i); - } - - throw exception::bad_boxed_cast("&= only valid for integer types"); - } - - /// \brief Performs a xor assignment (^=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to xor assign to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_xor_pod(P1 &p1, Boxed_Numeric r) - { - if (!r.isfloat) - { - return p1 ^= P1(r.i); - } - - throw exception::bad_boxed_cast("^= only valid for integer types"); - } - - /// \brief Performs a bitwise or assignment (|=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to bitwise or assign to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_bitwise_or_pod(P1 &p1, Boxed_Numeric r) - { - if (!r.isfloat) - { - return p1 |= P1(r.i); - } - - throw exception::bad_boxed_cast("&= only valid for integer types"); - } - - /// \brief Performs an assign shift left (<<=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to assign shift left to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_left_shift_pod(P1 &p1, Boxed_Numeric r) - { - if (!r.isfloat) - { - return p1 <<= P1(r.i); - } - - throw exception::bad_boxed_cast("<<= only valid for integer types"); - } - - - /// \brief Performs an assign remainder (%=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to assign remainder to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_remainder_pod(P1 &p1, Boxed_Numeric r) - { - if (!r.isfloat) - { - return p1 %= P1(r.i); - } - - throw exception::bad_boxed_cast("%= only valid for integer types"); - } - - - /// \brief Performs an assign shift right (>>=) on the given object with the given Boxed_Numeric - /// \param[in,out] p1 object to assign shift right to - /// \param[in] r Boxed_Numeric to assign from - /// \returns Reference to p1, to support normal C assignment semantics - template - P1 &assign_right_shift_pod(P1 &p1, Boxed_Numeric r) - { - if (!r.isfloat) - { - return p1 >>= P1(r.i); - } - - throw exception::bad_boxed_cast(">>= only valid for integer types"); - } - - + /// \brief Adds a copy constructor for the given type to the given Model + /// \param[in] type The name of the type. The copy constructor will be named "type". + /// \param[in,out] m The Module to add the copy constructor to + /// \tparam T The type to add a copy constructor for + /// \returns The passed in ModulePtr, or the newly constructed one if the default param is used + template + ModulePtr copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(constructor(), type); + return m; } /// \brief Add all comparison operators for the templated type. Used during bootstrap, also available to users. @@ -164,76 +64,6 @@ namespace chaiscript } - /// \brief Add all arithmetic operators appropriate for integers for the templated type. - /// Used during bootstrap, also available to users. - /// \tparam T Type to create arithmetic operators for - /// \param[in,out] m module to add arithmetic operators to - /// \returns the passed in ModulePtr or the newly constructed one if the default params are used. - template - ModulePtr opers_integer_arithmetic(ModulePtr m = ModulePtr(new Module())) - { - operators::assign_bitwise_and(m); - operators::assign_xor(m); - operators::assign_bitwise_or(m); -// operators::assign_difference(m); - operators::assign_left_shift(m); -// operators::assign_product(m); -// operators::assign_quotient(m); -// operators::assign_remainder(m); - operators::assign_right_shift(m); -// operators::assign_sum(m); - -// operators::prefix_decrement(m); -// operators::prefix_increment(m); -// operators::addition(m); - operators::unary_plus(m); -// operators::subtraction(m); - operators::unary_minus(m); - operators::bitwise_and(m); - operators::bitwise_compliment(m); - operators::bitwise_xor(m); - operators::bitwise_or(m); -// operators::division(m); - operators::left_shift(m); -// operators::multiplication(m); - operators::remainder(m); - operators::right_shift(m); - return m; - } - - /// \brief Add all arithmetic operators appropriate for floating point numbers for the templated type. - /// Used during bootstrap, also available to users. - /// \tparam T Type to create arithmetic operators for - /// \param[in,out] m module to add arithmetic operators to - /// \returns the passed in ModulePtr or the newly constructed one if the default params are used. - template - ModulePtr opers_float_arithmetic(ModulePtr m = ModulePtr(new Module())) - { -// operators::assign_difference(m); -// operators::assign_product(m); -// operators::assign_quotient(m); -// operators::assign_sum(m); - -// operators::addition(m); - operators::unary_plus(m); -// operators::subtraction(m); - operators::unary_minus(m); -// operators::division(m); -// operators::multiplication(m); - return m; - } - - /// \brief Adds a copy constructor for the given type to the given Model - /// \param[in] type The name of the type. The copy constructor will be named "type". - /// \param[in,out] m The Module to add the copy constructor to - /// \tparam T The type to add a copy constructor for - /// \returns The passed in ModulePtr, or the newly constructed one if the default param is used - template - ModulePtr copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(constructor(), type); - return m; - } /// \brief Adds default and copy constructors for the given type /// \param[in] type The name of the type to add the constructors for. @@ -283,15 +113,6 @@ namespace chaiscript } - /** - * Add assignment operator for T = POD. - */ - template - ModulePtr oper_assign_pod(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::assign_pod), "="); - return m; - } /** * Add all common functions for a POD type. All operators, and @@ -301,52 +122,14 @@ namespace chaiscript ModulePtr bootstrap_pod_type(const std::string &name, ModulePtr m = ModulePtr(new Module())) { m->add(user_type(), name); - basic_constructors(name, m); - operators::assign(m); - oper_assign_pod(m); + m->add(constructor(), name); construct_pod(name, m); -// m->add(fun(&detail::assign_sum_pod), "+="); -// m->add(fun(&detail::assign_difference_pod), "-="); -// m->add(fun(&detail::assign_product_pod), "*="); -// m->add(fun(&detail::assign_quotient_pod), "/="); - m->add(fun(&to_string), "to_string"); m->add(fun(&parse_string), "to_" + name); return m; } - /** - * Add all common functions for a POD type. All operators, and - * common conversions - */ - template - ModulePtr bootstrap_integer_type(const std::string &name, ModulePtr m = ModulePtr(new Module())) - { - bootstrap_pod_type(name, m); - - m->add(fun(&detail::assign_bitwise_and_pod), "&="); - m->add(fun(&detail::assign_xor_pod), "^="); - m->add(fun(&detail::assign_bitwise_or_pod), "|="); - m->add(fun(&detail::assign_left_shift_pod), "<<="); - m->add(fun(&detail::assign_remainder_pod), "%="); - m->add(fun(&detail::assign_right_shift_pod), ">>="); - - opers_integer_arithmetic(m); - return m; - } - - /** - * Add all common functions for a POD type. All operators, and - * common conversions - */ - template - ModulePtr bootstrap_float_type(const std::string &name, ModulePtr m = ModulePtr(new Module())) - { - bootstrap_pod_type(name, m); - opers_float_arithmetic(m); - return m; - } /** * "clone" function for a shared_ptr type. This is used in the case @@ -421,28 +204,48 @@ namespace chaiscript std::cout << s << std::endl; } + /** * Add all arithmetic operators for PODs */ static void opers_arithmetic_pod(ModulePtr m = ModulePtr(new Module())) { - m->add(fun(&operators::addition), "+"); - m->add(fun(&operators::subtraction), "-"); - m->add(fun(&operators::bitwise_and), "&"); - m->add(fun(&operators::bitwise_xor), "^"); - m->add(fun(&operators::bitwise_or), "|"); - m->add(fun(&operators::division), "/"); - m->add(fun(&operators::left_shift), "<<"); - m->add(fun(&operators::multiplication), "*"); - m->add(fun(&operators::remainder), "%"); - m->add(fun(&operators::right_shift), ">>"); + m->add(fun(&Boxed_Numeric::operator&=), "&="); + m->add(fun(&Boxed_Numeric::operator|=), "|="); + m->add(fun(&Boxed_Numeric::operator%=), "%="); + m->add(fun(&Boxed_Numeric::operator^=), "^="); + m->add(fun(&Boxed_Numeric::operator<<=), "<<="); + m->add(fun(&Boxed_Numeric::operator>>=), ">>="); + + m->add(fun(&Boxed_Numeric::operator&), "&"); + m->add(fun(&Boxed_Numeric::operator~), "~"); + m->add(fun(&Boxed_Numeric::operator^), "^"); + m->add(fun(&Boxed_Numeric::operator|), "|"); + m->add(fun(&Boxed_Numeric::operator<<), "<<"); + m->add(fun(&Boxed_Numeric::operator%), "%"); + m->add(fun(&Boxed_Numeric::operator>>), ">>"); + + m->add(fun(&Boxed_Numeric::operator=), "="); m->add(fun(&Boxed_Numeric::operator*=), "*="); m->add(fun(&Boxed_Numeric::operator/=), "/="); m->add(fun(&Boxed_Numeric::operator+=), "+="); m->add(fun(&Boxed_Numeric::operator-=), "-="); m->add(fun(&Boxed_Numeric::operator--), "--"); m->add(fun(&Boxed_Numeric::operator++), "++"); - } + m->add(fun(&Boxed_Numeric::operator/), "/"); + m->add(fun(&Boxed_Numeric::operator*), "*"); + m->add(fun(&Boxed_Numeric::operator+), "+"); + m->add(fun(&Boxed_Numeric::operator-), "-"); + m->add(fun(&Boxed_Numeric::operator+), "+"); + m->add(fun(&Boxed_Numeric::operator-), "-"); + + m->add(fun(&Boxed_Numeric::operator==), "=="); + m->add(fun(&Boxed_Numeric::operator>), ">"); + m->add(fun(&Boxed_Numeric::operator>=), ">="); + m->add(fun(&Boxed_Numeric::operator<), "<"); + m->add(fun(&Boxed_Numeric::operator<=), "<="); + m->add(fun(&Boxed_Numeric::operator!=), "!="); + } /** * Create a bound function object. The first param is the function to bind @@ -633,15 +436,25 @@ namespace chaiscript m->add(fun(&throw_exception), "throw"); m->add(fun(&what), "what"); - bootstrap_float_type("double", m); - bootstrap_integer_type("int", m); - bootstrap_integer_type("size_t", m); - bootstrap_integer_type("char", m); - bootstrap_integer_type("int64_t", m); + bootstrap_pod_type("double", m); + bootstrap_pod_type("long_double", m); + bootstrap_pod_type("float", m); + bootstrap_pod_type("int", m); + bootstrap_pod_type("unsigned_int", m); + bootstrap_pod_type("unsigned_long", m); + bootstrap_pod_type("size_t", m); + bootstrap_pod_type("char", m); + bootstrap_pod_type("int8_t", m); + bootstrap_pod_type("int16_t", m); + bootstrap_pod_type("int32_t", m); + bootstrap_pod_type("int64_t", m); + bootstrap_pod_type("uint8_t", m); + bootstrap_pod_type("uint16_t", m); + bootstrap_pod_type("uint32_t", m); + bootstrap_pod_type("uint64_t", m); operators::logical_compliment(m); - opers_comparison(m); opers_arithmetic_pod(m); diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 1c406404..1e230053 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -42,10 +42,51 @@ namespace chaiscript struct equals { static const bool lhs_const = true; +#pragma GCC diagnostic ignored "-Wsign-compare" template static bool go(const T &t, const U &u) { return t == u; } }; + struct less_than + { + static const bool lhs_const = true; +#pragma GCC diagnostic ignored "-Wsign-compare" + template + static bool go(const T &t, const U &u) { return t < u; } + }; + + struct greater_than + { + static const bool lhs_const = true; +#pragma GCC diagnostic ignored "-Wsign-compare" + template + static bool go(const T &t, const U &u) { return t > u; } + }; + + struct greater_than_equal + { + static const bool lhs_const = true; +#pragma GCC diagnostic ignored "-Wsign-compare" + template + static bool go(const T &t, const U &u) { return t >= u; } + }; + + struct less_than_equal + { + static const bool lhs_const = true; +#pragma GCC diagnostic ignored "-Wsign-compare" + template + static bool go(const T &t, const U &u) { return t <= u; } + }; + + struct not_equal + { + static const bool lhs_const = true; +#pragma GCC diagnostic ignored "-Wsign-compare" + template + static bool go(const T &t, const U &u) { return t != u; } + }; + struct add { static const bool lhs_const = true; @@ -95,6 +136,13 @@ namespace chaiscript static Boxed_Value go(T &t, const U &u) { return var(&(t += u)); } }; + struct assign + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t.get() = u.get())); } + }; + struct assign_difference { static const bool lhs_const = false; @@ -102,6 +150,49 @@ namespace chaiscript static Boxed_Value go(T &t, const U &u) { return var(&(t -= u)); } }; + struct assign_bitwise_and + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t &= u)); } + }; + + struct assign_bitwise_or + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t |= u)); } + }; + + struct assign_bitwise_xor + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t ^= u)); } + }; + + struct assign_remainder + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t %= u)); } + }; + + struct assign_bitshift_left + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t <<= u)); } + }; + + struct assign_bitshift_right + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t >>= u)); } + }; + + struct pre_increment { static const bool lhs_const = false; @@ -109,6 +200,69 @@ namespace chaiscript static Boxed_Value go(T &t, const U) { return var(&++t); } }; + struct unary_plus + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U) { return const_var(+t); } + }; + + struct bitwise_complement + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U) { return const_var(~t); } + }; + + struct unary_minus + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U) { return const_var(-t); } + }; + + struct bitwise_and + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t & u); } + }; + + struct bitwise_xor + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t ^ u); } + }; + + struct bitwise_or + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t | u); } + }; + + struct remainder + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t % u); } + }; + + struct left_shift + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t << u); } + }; + + struct right_shift + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U &u) { return const_var(t >> u); } + }; + struct pre_decrement { static const bool lhs_const = false; @@ -130,12 +284,12 @@ namespace chaiscript return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(float)) { return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(long double)) { + return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(bool)) { return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(char)) { return O::go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(int)) { - return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(unsigned int)) { return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(long)) { @@ -156,6 +310,8 @@ namespace chaiscript return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint32_t)) { return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint64_t)) { + return O::go(l, boxed_cast(r.bv)); } else { throw boost::bad_any_cast(); } @@ -169,6 +325,8 @@ namespace chaiscript if (inp_ == typeid(double)) { return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(long double)) { + return oper_lhs(boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(float)) { return oper_lhs(boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(bool)) { @@ -197,15 +355,91 @@ namespace chaiscript return oper_lhs(boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint32_t)) { return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint64_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else { + throw boost::bad_any_cast(); + } + } + + + template + static Ret oper_int_lhs(L l, const Boxed_Numeric &r) + { + const Type_Info &inp_ = r.bv.get_type_info(); + + if (inp_ == typeid(bool)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(char)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(unsigned int)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(long)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(unsigned long)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int8_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int16_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int32_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int64_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint8_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint16_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint32_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint64_t)) { + return O::go(l, boxed_cast(r.bv)); + } else { + throw boost::bad_any_cast(); + } + } + + template + static Ret oper_int(const Boxed_Numeric &l, const Boxed_Numeric &r) + { + const Type_Info &inp_ = l.bv.get_type_info(); + + if (inp_ == typeid(bool)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(char)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(int)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(unsigned int)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(long)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(unsigned long)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int8_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int16_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int32_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int64_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint8_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint16_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint32_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint64_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); } else { throw boost::bad_any_cast(); } }; - public: Boxed_Numeric(const Boxed_Value &v) - : bv(v), d(0), i(0), isfloat(false) + : bv(v) { const Type_Info &inp_ = v.get_type_info(); @@ -213,45 +447,9 @@ namespace chaiscript { throw boost::bad_any_cast(); } - - if (inp_ == typeid(double)) - { - d = boxed_cast(v); - isfloat = true; - } else if (inp_ == typeid(float)) { - d = boxed_cast(v); - isfloat = true; - } else if (inp_ == typeid(bool)) { - i = boxed_cast(v); - } else if (inp_ == typeid(char)) { - i = boxed_cast(v); - } else if (inp_ == typeid(int)) { - i = boxed_cast(v); - } else if (inp_ == typeid(unsigned int)) { - i = boxed_cast(v); - } else if (inp_ == typeid(long)) { - i = boxed_cast(v); - } else if (inp_ == typeid(unsigned long)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int8_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int16_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int32_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int64_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint8_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint16_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint32_t)) { - i = boxed_cast(v); - } else { - throw boost::bad_any_cast(); - } } + bool operator==(const Boxed_Numeric &r) const { return oper(*this, r); @@ -259,27 +457,27 @@ namespace chaiscript bool operator<(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) < ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator>(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) > ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator>=(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) >= ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator<=(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) <= ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator!=(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) != ((r.isfloat)?r.d:r.i); + return oper(*this, r); } Boxed_Value operator--() const @@ -297,39 +495,74 @@ namespace chaiscript return oper(*this, r); } + Boxed_Value operator+() const + { + return oper(*this, Boxed_Value(0)); + } + + Boxed_Value operator-() const + { + return oper(*this, Boxed_Value(0)); + } + Boxed_Value operator-(const Boxed_Numeric &r) const { return oper(*this, r); } + Boxed_Value operator&=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator=(const Boxed_Numeric &r) const + { + return oper(*this, r); + } + + Boxed_Value operator|=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator^=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator%=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator<<=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator>>=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + Boxed_Value operator&(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return Boxed_Value(i & r.i); - } + return oper_int(*this, r); + } - throw exception::bad_boxed_cast("& only valid for integer types"); + Boxed_Value operator~() const + { + return oper_int(*this, Boxed_Value(0)); } Boxed_Value operator^(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return Boxed_Value(i ^ r.i); - } - - throw exception::bad_boxed_cast("^ only valid for integer types"); + return oper_int(*this, r); } Boxed_Value operator|(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return Boxed_Value(i | r.i); - } - - throw exception::bad_boxed_cast("| only valid for integer types"); + return oper_int(*this, r); } Boxed_Value operator*=(const Boxed_Numeric &r) const @@ -356,58 +589,25 @@ namespace chaiscript Boxed_Value operator<<(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return smart_size(i << r.i); - } - - throw exception::bad_boxed_cast("<< only valid for integer types"); + return oper_int(*this, r); } - Boxed_Value operator*(const Boxed_Numeric &r) const { return oper(*this, r); } - Boxed_Value operator%(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return smart_size(i % r.i); - } - - throw exception::bad_boxed_cast("% only valid for integer types"); + return oper_int(*this, r); } Boxed_Value operator>>(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return smart_size(i >> r.i); - } - - throw exception::bad_boxed_cast(">> only valid for integer types"); + return oper_int(*this, r); } - Boxed_Value smart_size(boost::int64_t t_i) const - { - if (t_i < boost::integer_traits::const_min - || t_i > boost::integer_traits::const_max) - { - return Boxed_Value(t_i); - } else { - return Boxed_Value(static_cast(t_i)); - } - } - - Boxed_Value bv; - double d; - boost::int64_t i; - - bool isfloat; }; namespace detail From fdd1b40a9f902b86946db49fd7b45078b6740f55 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 29 May 2011 09:14:48 -0600 Subject: [PATCH 04/11] Significant reduction in templates instantiated by grouping of operators - smaller code and compile time --- .../chaiscript/dispatchkit/boxed_numeric.hpp | 622 +++++++++--------- 1 file changed, 301 insertions(+), 321 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 1e230053..93bd8a2c 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -39,324 +39,308 @@ namespace chaiscript typedef typename choose_const::type type; }; - struct equals + struct boolean { + enum oper + { + equals, + less_than, + greater_than, + less_than_equal, + greater_than_equal, + not_equal + }; + + oper m_oper; + + boolean(boolean::oper t_oper) + : m_oper(t_oper) + { + } + static const bool lhs_const = true; + #pragma GCC diagnostic ignored "-Wsign-compare" template - static bool go(const T &t, const U &u) { return t == u; } + bool go(const T &t, const U &u) const + { + switch (m_oper) + { + case equals: + return t == u; + case less_than: + return t < u; + case greater_than: + return t > u; + case less_than_equal: + return t <= u; + case greater_than_equal: + return t >= u; + case not_equal: + return t != u; + } + throw boost::bad_any_cast(); + } }; - struct less_than + struct binary { - static const bool lhs_const = true; -#pragma GCC diagnostic ignored "-Wsign-compare" - template - static bool go(const T &t, const U &u) { return t < u; } - }; + enum oper + { + assign, + pre_increment, + pre_decrement, + assign_product, + assign_sum, + assign_quotient, + assign_difference, + }; - struct greater_than - { - static const bool lhs_const = true; -#pragma GCC diagnostic ignored "-Wsign-compare" - template - static bool go(const T &t, const U &u) { return t > u; } - }; + oper m_oper; - struct greater_than_equal - { - static const bool lhs_const = true; -#pragma GCC diagnostic ignored "-Wsign-compare" - template - static bool go(const T &t, const U &u) { return t >= u; } - }; + binary(binary::oper t_oper) + : m_oper(t_oper) + { + } - struct less_than_equal - { - static const bool lhs_const = true; -#pragma GCC diagnostic ignored "-Wsign-compare" - template - static bool go(const T &t, const U &u) { return t <= u; } - }; - - struct not_equal - { - static const bool lhs_const = true; -#pragma GCC diagnostic ignored "-Wsign-compare" - template - static bool go(const T &t, const U &u) { return t != u; } - }; - - struct add - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t + u); } - }; - - struct subtract - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t - u); } - }; - - struct multiply - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t * u); } - }; - - struct divide - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t / u); } - }; - - struct assign_product - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t *= u)); } - }; - - struct assign_quotient - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t /= u)); } - }; - - struct assign_sum - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t += u)); } - }; - - struct assign - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t.get() = u.get())); } - }; - - struct assign_difference - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t -= u)); } - }; - - struct assign_bitwise_and - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t &= u)); } - }; - - struct assign_bitwise_or - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t |= u)); } - }; - - struct assign_bitwise_xor - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t ^= u)); } - }; - - struct assign_remainder - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t %= u)); } - }; - - struct assign_bitshift_left - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t <<= u)); } - }; - - struct assign_bitshift_right - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U &u) { return var(&(t >>= u)); } - }; - - - struct pre_increment - { - static const bool lhs_const = false; - template - static Boxed_Value go(T &t, const U) { return var(&++t); } - }; - - struct unary_plus - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U) { return const_var(+t); } - }; - - struct bitwise_complement - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U) { return const_var(~t); } - }; - - struct unary_minus - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U) { return const_var(-t); } - }; - - struct bitwise_and - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t & u); } - }; - - struct bitwise_xor - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t ^ u); } - }; - - struct bitwise_or - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t | u); } - }; - - struct remainder - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t % u); } - }; - - struct left_shift - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t << u); } - }; - - struct right_shift - { - static const bool lhs_const = true; - template - static Boxed_Value go(const T &t, const U &u) { return const_var(t >> u); } - }; - - struct pre_decrement - { static const bool lhs_const = false; - template - static Boxed_Value go(boost::reference_wrapper, const U) { std::cout<< "why where?"<< std::endl; throw boost::bad_any_cast(); } + template + Boxed_Value go(T &t, const U &u) const + { + switch (m_oper) + { + case assign: + return var(&(t.get() = u.get())); + case pre_increment: + return var(&(++t)); + case pre_decrement: + return var(&(--t)); + case assign_product: + return var(&(t *= u)); + case assign_sum: + return var(&(t += u)); + case assign_quotient: + return var(&(t /= u)); + case assign_difference: + return var(&(t -= u)); + } + throw boost::bad_any_cast(); + } + }; + + + struct binary_int + { + enum oper + { + assign_bitwise_and, + assign_bitwise_or, + assign_shift_left, + assign_shift_right, + assign_remainder, + assign_bitwise_xor, + }; + + oper m_oper; + + binary_int(binary_int::oper t_oper) + : m_oper(t_oper) + { + } + + static const bool lhs_const = false; template - static Boxed_Value go(T &t, const U) { return var(&--t); } + Boxed_Value go(T &t, const U &u) const + { + switch (m_oper) + { + case assign_bitwise_and: + return var(&(t &= u)); + case assign_bitwise_or: + return var(&(t |= u)); + case assign_shift_left: + return var(&(t <<= u)); + case assign_shift_right: + return var(&(t >>= u)); + case assign_remainder: + return var(&(t %= u)); + case assign_bitwise_xor: + return var(&(t ^= u)); + } + throw boost::bad_any_cast(); + } + }; + + struct const_binary_int + { + enum oper + { + shift_left, + shift_right, + remainder, + bitwise_and, + bitwise_or, + bitwise_xor, + bitwise_complement + }; + + oper m_oper; + + const_binary_int(const_binary_int::oper t_oper) + : m_oper(t_oper) + { + } + + static const bool lhs_const = true; + + template + Boxed_Value go(const T &t, const U &u) const + { + switch (m_oper) + { + case shift_left: + return const_var(t << u); + case shift_right: + return const_var(t >> u); + case remainder: + return const_var(t % u); + case bitwise_and: + return const_var(t & u); + case bitwise_or: + return const_var(t | u); + case bitwise_xor: + return const_var(t ^ u); + case bitwise_complement: + return const_var(~t); + } + throw boost::bad_any_cast(); + } + }; + + struct const_binary + { + enum oper + { + sum, + quotient, + product, + difference, + unary_plus, + unary_minus + }; + + oper m_oper; + + const_binary(const_binary::oper t_oper) + : m_oper(t_oper) + { + } + + static const bool lhs_const = true; + + template + Boxed_Value go(const T &t, const U &u) const + { + switch (m_oper) + { + case sum: + return const_var(t + u); + case quotient: + return const_var(t / u); + case product: + return const_var(t * u); + case difference: + return const_var(t - u); + case unary_minus: + return const_var(-t); + case unary_plus: + return const_var(+t); + } + throw boost::bad_any_cast(); + } }; template - static Ret oper_lhs(L l, const Boxed_Numeric &r) + static Ret oper_lhs(const O &t_o, L l, const Boxed_Numeric &r) { const Type_Info &inp_ = r.bv.get_type_info(); if (inp_ == typeid(double)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(float)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(long double)) { - return O::go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(bool)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(char)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(unsigned int)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(long)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(unsigned long)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int8_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int16_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int32_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int64_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint8_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint16_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint32_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint64_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else { throw boost::bad_any_cast(); } } template - static Ret oper(const Boxed_Numeric &l, const Boxed_Numeric &r) + static Ret oper(const O& t_o, const Boxed_Numeric &l, const Boxed_Numeric &r) { const Type_Info &inp_ = l.bv.get_type_info(); if (inp_ == typeid(double)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(long double)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(float)) { - return oper_lhs(boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(bool)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(char)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(int)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(unsigned int)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(long)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(unsigned long)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int8_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int16_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int32_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int64_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint8_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint16_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint32_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint64_t)) { - return oper_lhs(boxed_cast::type>(l.bv), r); + return oper_lhs(t_o, boxed_cast::type>(l.bv), r); } else { throw boost::bad_any_cast(); } @@ -364,74 +348,70 @@ namespace chaiscript template - static Ret oper_int_lhs(L l, const Boxed_Numeric &r) + static Ret oper_int_lhs(const O &t_o, L l, const Boxed_Numeric &r) { const Type_Info &inp_ = r.bv.get_type_info(); - if (inp_ == typeid(bool)) { - return O::go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(char)) { - return O::go(l, boxed_cast(r.bv)); + if (inp_ == typeid(char)) { + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(unsigned int)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(long)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(unsigned long)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int8_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int16_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int32_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::int64_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint8_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint16_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint32_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint64_t)) { - return O::go(l, boxed_cast(r.bv)); + return t_o.go(l, boxed_cast(r.bv)); } else { throw boost::bad_any_cast(); } } template - static Ret oper_int(const Boxed_Numeric &l, const Boxed_Numeric &r) + static Ret oper_int(const O &t_o, const Boxed_Numeric &l, const Boxed_Numeric &r) { const Type_Info &inp_ = l.bv.get_type_info(); - if (inp_ == typeid(bool)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(char)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + if (inp_ == typeid(char)) { + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(int)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(unsigned int)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(long)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(unsigned long)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int8_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int16_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int32_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::int64_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint8_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint16_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint32_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint64_t)) { - return oper_int_lhs(boxed_cast::type>(l.bv), r); + return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); } else { throw boost::bad_any_cast(); } @@ -452,159 +432,159 @@ namespace chaiscript bool operator==(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(boolean(boolean::equals), *this, r); } bool operator<(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(boolean(boolean::less_than), *this, r); } bool operator>(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(boolean(boolean::greater_than), *this, r); } bool operator>=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(boolean(boolean::greater_than_equal), *this, r); } bool operator<=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(boolean(boolean::less_than_equal), *this, r); } bool operator!=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(boolean(boolean::not_equal), *this, r); } Boxed_Value operator--() const { - return oper(*this, var(0)); + return oper(binary(binary::pre_decrement), *this, var(0)); } Boxed_Value operator++() const { - return oper(*this, var(0)); + return oper(binary(binary::pre_increment), *this, var(0)); } Boxed_Value operator+(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(const_binary(const_binary::sum), *this, r); } Boxed_Value operator+() const { - return oper(*this, Boxed_Value(0)); + return oper(const_binary(const_binary::unary_plus), *this, Boxed_Value(0)); } Boxed_Value operator-() const { - return oper(*this, Boxed_Value(0)); + return oper(const_binary(const_binary::unary_minus), *this, Boxed_Value(0)); } Boxed_Value operator-(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(const_binary(const_binary::difference), *this, r); } Boxed_Value operator&=(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(binary_int(binary_int::assign_bitwise_or), *this, r); } Boxed_Value operator=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(binary(binary::assign), *this, r); } Boxed_Value operator|=(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(binary_int(binary_int::assign_bitwise_or), *this, r); } Boxed_Value operator^=(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(binary_int(binary_int::assign_bitwise_xor), *this, r); } Boxed_Value operator%=(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(binary_int(binary_int::assign_remainder), *this, r); } Boxed_Value operator<<=(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(binary_int(binary_int::assign_shift_left), *this, r); } Boxed_Value operator>>=(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(binary_int(binary_int::assign_shift_right), *this, r); } Boxed_Value operator&(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(const_binary_int(const_binary_int::bitwise_and), *this, r); } Boxed_Value operator~() const { - return oper_int(*this, Boxed_Value(0)); + return oper_int(const_binary_int(const_binary_int::bitwise_complement), *this, Boxed_Value(0)); } Boxed_Value operator^(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(const_binary_int(const_binary_int::bitwise_xor), *this, r); } Boxed_Value operator|(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(const_binary_int(const_binary_int::bitwise_or), *this, r); } Boxed_Value operator*=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(binary(binary::assign_product), *this, r); } Boxed_Value operator/=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(binary(binary::assign_quotient), *this, r); } Boxed_Value operator+=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(binary(binary::assign_sum), *this, r); } Boxed_Value operator-=(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(binary(binary::assign_difference), *this, r); } Boxed_Value operator/(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(const_binary(const_binary::quotient), *this, r); } Boxed_Value operator<<(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(const_binary_int(const_binary_int::shift_left), *this, r); } Boxed_Value operator*(const Boxed_Numeric &r) const { - return oper(*this, r); + return oper(const_binary(const_binary::product), *this, r); } Boxed_Value operator%(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(const_binary_int(const_binary_int::remainder), *this, r); } Boxed_Value operator>>(const Boxed_Numeric &r) const { - return oper_int(*this, r); + return oper_int(const_binary_int(const_binary_int::shift_right), *this, r); } Boxed_Value bv; From 1f130c089188070bc9c7128186b5d28396fd022b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 29 May 2011 17:33:45 -0600 Subject: [PATCH 05/11] Further simplification and refinement of enhanced Algebraic types support --- .../chaiscript/dispatchkit/boxed_numeric.hpp | 445 +++++++----------- 1 file changed, 178 insertions(+), 267 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 93bd8a2c..45275795 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -21,63 +21,71 @@ namespace chaiscript class Boxed_Numeric { private: - template - struct choose_const + + enum opers { - typedef T& type; + boolean_flag, + equals, + less_than, + greater_than, + less_than_equal, + greater_than_equal, + not_equal, + non_const_flag, + assign, + pre_increment, + pre_decrement, + assign_product, + assign_sum, + assign_quotient, + assign_difference, + non_const_int_flag, + assign_bitwise_and, + assign_bitwise_or, + assign_shift_left, + assign_shift_right, + assign_remainder, + assign_bitwise_xor, + shift_left, + shift_right, + const_int_flag, + remainder, + bitwise_and, + bitwise_or, + bitwise_xor, + bitwise_complement, + const_flag, + sum, + quotient, + product, + difference, + unary_plus, + unary_minus }; - template - struct choose_const - { - typedef const T& type; - }; - - template - struct lhs_type - { - typedef typename choose_const::type type; - }; struct boolean { - enum oper - { - equals, - less_than, - greater_than, - less_than_equal, - greater_than_equal, - not_equal - }; - - oper m_oper; - - boolean(boolean::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = true; - #pragma GCC diagnostic ignored "-Wsign-compare" template - bool go(const T &t, const U &u) const + static Boxed_Value go(opers t_oper, const T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case equals: - return t == u; + return const_var(t == u); case less_than: - return t < u; + return const_var(t < u); case greater_than: - return t > u; + return const_var(t > u); case less_than_equal: - return t <= u; + return const_var(t <= u); case greater_than_equal: - return t >= u; + return const_var(t >= u); case not_equal: - return t != u; + return const_var(t != u); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } @@ -85,33 +93,13 @@ namespace chaiscript struct binary { - enum oper - { - assign, - pre_increment, - pre_decrement, - assign_product, - assign_sum, - assign_quotient, - assign_difference, - }; - - oper m_oper; - - binary(binary::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = false; - template - Boxed_Value go(T &t, const U &u) const + static Boxed_Value go(opers t_oper, T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case assign: - return var(&(t.get() = u.get())); + return var(&(t = u)); case pre_increment: return var(&(++t)); case pre_decrement: @@ -124,37 +112,19 @@ namespace chaiscript return var(&(t /= u)); case assign_difference: return var(&(t -= u)); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } }; - struct binary_int { - enum oper - { - assign_bitwise_and, - assign_bitwise_or, - assign_shift_left, - assign_shift_right, - assign_remainder, - assign_bitwise_xor, - }; - - oper m_oper; - - binary_int(binary_int::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = false; - template - Boxed_Value go(T &t, const U &u) const + static Boxed_Value go(opers t_oper, T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case assign_bitwise_and: return var(&(t &= u)); @@ -168,6 +138,8 @@ namespace chaiscript return var(&(t %= u)); case assign_bitwise_xor: return var(&(t ^= u)); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } @@ -175,30 +147,10 @@ namespace chaiscript struct const_binary_int { - enum oper - { - shift_left, - shift_right, - remainder, - bitwise_and, - bitwise_or, - bitwise_xor, - bitwise_complement - }; - - oper m_oper; - - const_binary_int(const_binary_int::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = true; - template - Boxed_Value go(const T &t, const U &u) const + static Boxed_Value go(opers t_oper, const T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case shift_left: return const_var(t << u); @@ -214,6 +166,8 @@ namespace chaiscript return const_var(t ^ u); case bitwise_complement: return const_var(~t); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } @@ -221,29 +175,10 @@ namespace chaiscript struct const_binary { - enum oper - { - sum, - quotient, - product, - difference, - unary_plus, - unary_minus - }; - - oper m_oper; - - const_binary(const_binary::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = true; - template - Boxed_Value go(const T &t, const U &u) const + static Boxed_Value go(opers t_oper, const T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case sum: return const_var(t + u); @@ -257,165 +192,141 @@ namespace chaiscript return const_var(-t); case unary_plus: return const_var(+t); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } }; - template - static Ret oper_lhs(const O &t_o, L l, const Boxed_Numeric &r) + template + struct Go + { + static Boxed_Value go(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { - const Type_Info &inp_ = r.bv.get_type_info(); + if (t_oper > boolean_flag && t_oper < non_const_flag) + { + return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_flag && t_oper < non_const_int_flag) { + return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_int_flag && t_oper < const_int_flag) { + return binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > const_int_flag && t_oper < const_flag) { + return const_binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > const_flag) { + return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else { + throw boost::bad_any_cast(); + } + } + }; + + template + struct Go + { + static Boxed_Value go(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + { + if (t_oper > boolean_flag && t_oper < non_const_flag) + { + return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_flag && t_oper < non_const_int_flag) { + return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_int_flag && t_oper < const_int_flag) { + throw boost::bad_any_cast(); + } else if (t_oper > const_int_flag && t_oper < const_flag) { + throw boost::bad_any_cast(); + } else if (t_oper > const_flag) { + return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else { + throw boost::bad_any_cast(); + } + } + }; + + template + static Boxed_Value oper_rhs(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + { + const Type_Info &inp_ = t_rhs.bv.get_type_info(); if (inp_ == typeid(double)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(float)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long double)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(char)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned int)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int8_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int16_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int32_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int64_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint8_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint16_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint32_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint64_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else { throw boost::bad_any_cast(); } } - template - static Ret oper(const O& t_o, const Boxed_Numeric &l, const Boxed_Numeric &r) + static Boxed_Value oper(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { - const Type_Info &inp_ = l.bv.get_type_info(); + const Type_Info &inp_ = t_lhs.bv.get_type_info(); if (inp_ == typeid(double)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long double)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(float)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(char)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(int)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned int)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int8_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int16_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int32_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int64_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint8_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint16_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint32_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint64_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else { throw boost::bad_any_cast(); } } - template - static Ret oper_int_lhs(const O &t_o, L l, const Boxed_Numeric &r) - { - const Type_Info &inp_ = r.bv.get_type_info(); - - if (inp_ == typeid(char)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(unsigned int)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(long)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(unsigned long)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int8_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int16_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int32_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int64_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint8_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint16_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint32_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint64_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else { - throw boost::bad_any_cast(); - } - } - - template - static Ret oper_int(const O &t_o, const Boxed_Numeric &l, const Boxed_Numeric &r) - { - const Type_Info &inp_ = l.bv.get_type_info(); - - if (inp_ == typeid(char)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(int)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(unsigned int)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(long)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(unsigned long)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int8_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int16_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int32_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int64_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint8_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint16_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint32_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint64_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else { - throw boost::bad_any_cast(); - } - }; public: Boxed_Numeric(const Boxed_Value &v) @@ -432,159 +343,159 @@ namespace chaiscript bool operator==(const Boxed_Numeric &r) const { - return oper(boolean(boolean::equals), *this, r); + return boxed_cast(oper(equals, *this, r)); } bool operator<(const Boxed_Numeric &r) const { - return oper(boolean(boolean::less_than), *this, r); + return boxed_cast(oper(less_than, *this, r)); } bool operator>(const Boxed_Numeric &r) const { - return oper(boolean(boolean::greater_than), *this, r); + return boxed_cast(oper(greater_than, *this, r)); } bool operator>=(const Boxed_Numeric &r) const { - return oper(boolean(boolean::greater_than_equal), *this, r); + return boxed_cast(oper(greater_than_equal, *this, r)); } bool operator<=(const Boxed_Numeric &r) const { - return oper(boolean(boolean::less_than_equal), *this, r); + return boxed_cast(oper(less_than_equal, *this, r)); } bool operator!=(const Boxed_Numeric &r) const { - return oper(boolean(boolean::not_equal), *this, r); + return boxed_cast(oper(not_equal, *this, r)); } Boxed_Value operator--() const { - return oper(binary(binary::pre_decrement), *this, var(0)); + return oper(pre_decrement, *this, var(0)); } Boxed_Value operator++() const { - return oper(binary(binary::pre_increment), *this, var(0)); + return oper(pre_increment, *this, var(0)); } Boxed_Value operator+(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::sum), *this, r); + return oper(sum, *this, r); } Boxed_Value operator+() const { - return oper(const_binary(const_binary::unary_plus), *this, Boxed_Value(0)); + return oper(unary_plus, *this, Boxed_Value(0)); } Boxed_Value operator-() const { - return oper(const_binary(const_binary::unary_minus), *this, Boxed_Value(0)); + return oper(unary_minus, *this, Boxed_Value(0)); } Boxed_Value operator-(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::difference), *this, r); + return oper(difference, *this, r); } Boxed_Value operator&=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_bitwise_or), *this, r); + return oper(assign_bitwise_and, *this, r); } Boxed_Value operator=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign), *this, r); + return oper(assign, *this, r); } Boxed_Value operator|=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_bitwise_or), *this, r); + return oper(assign_bitwise_or, *this, r); } Boxed_Value operator^=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_bitwise_xor), *this, r); + return oper(assign_bitwise_xor, *this, r); } Boxed_Value operator%=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_remainder), *this, r); + return oper(assign_remainder, *this, r); } Boxed_Value operator<<=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_shift_left), *this, r); + return oper(assign_shift_left, *this, r); } Boxed_Value operator>>=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_shift_right), *this, r); + return oper(assign_shift_right, *this, r); } Boxed_Value operator&(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::bitwise_and), *this, r); + return oper(bitwise_and, *this, r); } Boxed_Value operator~() const { - return oper_int(const_binary_int(const_binary_int::bitwise_complement), *this, Boxed_Value(0)); + return oper(bitwise_complement, *this, Boxed_Value(0)); } Boxed_Value operator^(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::bitwise_xor), *this, r); + return oper(bitwise_xor, *this, r); } Boxed_Value operator|(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::bitwise_or), *this, r); + return oper(bitwise_or, *this, r); } Boxed_Value operator*=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_product), *this, r); + return oper(assign_product, *this, r); } Boxed_Value operator/=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_quotient), *this, r); + return oper(assign_quotient, *this, r); } Boxed_Value operator+=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_sum), *this, r); + return oper(assign_sum, *this, r); } Boxed_Value operator-=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_difference), *this, r); + return oper(assign_difference, *this, r); } Boxed_Value operator/(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::quotient), *this, r); + return oper(quotient, *this, r); } Boxed_Value operator<<(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::shift_left), *this, r); + return oper(shift_left, *this, r); } Boxed_Value operator*(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::product), *this, r); + return oper(product, *this, r); } Boxed_Value operator%(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::remainder), *this, r); + return oper(remainder, *this, r); } Boxed_Value operator>>(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::shift_right), *this, r); + return oper(shift_right, *this, r); } Boxed_Value bv; From 85f69782b2bafc906c290c02816c3766e82f1064 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 30 May 2011 19:38:04 -0600 Subject: [PATCH 06/11] Wrap up new Boxed_Numeric support --- include/chaiscript/dispatchkit/bootstrap.hpp | 1 + include/chaiscript/dispatchkit/boxed_numeric.hpp | 8 ++++++-- unittests/boxed_cast_test.cpp | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index b1918927..5f62237f 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -429,6 +429,7 @@ namespace chaiscript basic_constructors("bool", m); operators::assign(m); + operators::equal(m); m->add(fun(&to_string), "internal_to_string"); m->add(fun(&Bootstrap::bool_to_string), "internal_to_string"); diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 45275795..52700e89 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -46,9 +46,9 @@ namespace chaiscript assign_shift_right, assign_remainder, assign_bitwise_xor, + const_int_flag, shift_left, shift_right, - const_int_flag, remainder, bitwise_and, bitwise_or, @@ -321,7 +321,7 @@ namespace chaiscript return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint64_t)) { return oper_rhs(t_oper, t_lhs, t_rhs); - } else { + } else { throw boost::bad_any_cast(); } } @@ -333,6 +333,10 @@ namespace chaiscript : bv(v) { const Type_Info &inp_ = v.get_type_info(); + if (inp_ == typeid(bool)) + { + throw boost::bad_any_cast(); + } if (!inp_.is_arithmetic()) { diff --git a/unittests/boxed_cast_test.cpp b/unittests/boxed_cast_test.cpp index ca53707f..078ec975 100644 --- a/unittests/boxed_cast_test.cpp +++ b/unittests/boxed_cast_test.cpp @@ -301,7 +301,9 @@ int main() passed &= built_in_type_test(5, true); passed &= built_in_type_test(1.1, true); passed &= built_in_type_test('a', true); - passed &= built_in_type_test(false, true); + passed &= built_in_type_test('a', true); + passed &= built_in_type_test('a', true); + passed &= built_in_type_test(false, false); passed &= built_in_type_test("Hello World", false); // storing a pointer From 36cd4c370a2f2ac83f0968bab3aa1eed6cba1bd6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 31 May 2011 07:42:30 -0600 Subject: [PATCH 07/11] Begin move of Operators code out a level so that it can be used before dispatch --- .../chaiscript/dispatchkit/boxed_numeric.hpp | 207 +++++++----------- .../chaiscript/language/chaiscript_common.hpp | 37 ++++ 2 files changed, 121 insertions(+), 123 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 52700e89..b2a37ff8 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -10,6 +10,7 @@ #include "type_info.hpp" #include "boxed_value.hpp" #include "boxed_cast_helper.hpp" +#include "../language/chaiscript_common.hpp" #include #include #include @@ -22,67 +23,27 @@ namespace chaiscript { private: - enum opers - { - boolean_flag, - equals, - less_than, - greater_than, - less_than_equal, - greater_than_equal, - not_equal, - non_const_flag, - assign, - pre_increment, - pre_decrement, - assign_product, - assign_sum, - assign_quotient, - assign_difference, - non_const_int_flag, - assign_bitwise_and, - assign_bitwise_or, - assign_shift_left, - assign_shift_right, - assign_remainder, - assign_bitwise_xor, - const_int_flag, - shift_left, - shift_right, - remainder, - bitwise_and, - bitwise_or, - bitwise_xor, - bitwise_complement, - const_flag, - sum, - quotient, - product, - difference, - unary_plus, - unary_minus - }; struct boolean { #pragma GCC diagnostic ignored "-Wsign-compare" template - static Boxed_Value go(opers t_oper, const T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u) { switch (t_oper) { - case equals: + case Operators::equals: return const_var(t == u); - case less_than: + case Operators::less_than: return const_var(t < u); - case greater_than: + case Operators::greater_than: return const_var(t > u); - case less_than_equal: + case Operators::less_than_equal: return const_var(t <= u); - case greater_than_equal: + case Operators::greater_than_equal: return const_var(t >= u); - case not_equal: + case Operators::not_equal: return const_var(t != u); default: throw boost::bad_any_cast(); @@ -94,23 +55,23 @@ namespace chaiscript struct binary { template - static Boxed_Value go(opers t_oper, T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u) { switch (t_oper) { - case assign: + case Operators::assign: return var(&(t = u)); - case pre_increment: + case Operators::pre_increment: return var(&(++t)); - case pre_decrement: + case Operators::pre_decrement: return var(&(--t)); - case assign_product: + case Operators::assign_product: return var(&(t *= u)); - case assign_sum: + case Operators::assign_sum: return var(&(t += u)); - case assign_quotient: + case Operators::assign_quotient: return var(&(t /= u)); - case assign_difference: + case Operators::assign_difference: return var(&(t -= u)); default: throw boost::bad_any_cast(); @@ -122,21 +83,21 @@ namespace chaiscript struct binary_int { template - static Boxed_Value go(opers t_oper, T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u) { switch (t_oper) { - case assign_bitwise_and: + case Operators::assign_bitwise_and: return var(&(t &= u)); - case assign_bitwise_or: + case Operators::assign_bitwise_or: return var(&(t |= u)); - case assign_shift_left: + case Operators::assign_shift_left: return var(&(t <<= u)); - case assign_shift_right: + case Operators::assign_shift_right: return var(&(t >>= u)); - case assign_remainder: + case Operators::assign_remainder: return var(&(t %= u)); - case assign_bitwise_xor: + case Operators::assign_bitwise_xor: return var(&(t ^= u)); default: throw boost::bad_any_cast(); @@ -148,23 +109,23 @@ namespace chaiscript struct const_binary_int { template - static Boxed_Value go(opers t_oper, const T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u) { switch (t_oper) { - case shift_left: + case Operators::shift_left: return const_var(t << u); - case shift_right: + case Operators::shift_right: return const_var(t >> u); - case remainder: + case Operators::remainder: return const_var(t % u); - case bitwise_and: + case Operators::bitwise_and: return const_var(t & u); - case bitwise_or: + case Operators::bitwise_or: return const_var(t | u); - case bitwise_xor: + case Operators::bitwise_xor: return const_var(t ^ u); - case bitwise_complement: + case Operators::bitwise_complement: return const_var(~t); default: throw boost::bad_any_cast(); @@ -176,21 +137,21 @@ namespace chaiscript struct const_binary { template - static Boxed_Value go(opers t_oper, const T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u) { switch (t_oper) { - case sum: + case Operators::sum: return const_var(t + u); - case quotient: + case Operators::quotient: return const_var(t / u); - case product: + case Operators::product: return const_var(t * u); - case difference: + case Operators::difference: return const_var(t - u); - case unary_minus: + case Operators::unary_minus: return const_var(-t); - case unary_plus: + case Operators::unary_plus: return const_var(+t); default: throw boost::bad_any_cast(); @@ -202,18 +163,18 @@ namespace chaiscript template struct Go { - static Boxed_Value go(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value go(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { - if (t_oper > boolean_flag && t_oper < non_const_flag) + if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); - } else if (t_oper > non_const_flag && t_oper < non_const_int_flag) { + } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) { return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); - } else if (t_oper > non_const_int_flag && t_oper < const_int_flag) { + } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { return binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); - } else if (t_oper > const_int_flag && t_oper < const_flag) { + } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { return const_binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); - } else if (t_oper > const_flag) { + } else if (t_oper > Operators::const_flag) { return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); } else { throw boost::bad_any_cast(); @@ -224,18 +185,18 @@ namespace chaiscript template struct Go { - static Boxed_Value go(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value go(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { - if (t_oper > boolean_flag && t_oper < non_const_flag) + if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); - } else if (t_oper > non_const_flag && t_oper < non_const_int_flag) { + } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) { return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); - } else if (t_oper > non_const_int_flag && t_oper < const_int_flag) { + } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { throw boost::bad_any_cast(); - } else if (t_oper > const_int_flag && t_oper < const_flag) { + } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { throw boost::bad_any_cast(); - } else if (t_oper > const_flag) { + } else if (t_oper > Operators::const_flag) { return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); } else { throw boost::bad_any_cast(); @@ -244,7 +205,7 @@ namespace chaiscript }; template - static Boxed_Value oper_rhs(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { const Type_Info &inp_ = t_rhs.bv.get_type_info(); @@ -284,7 +245,7 @@ namespace chaiscript } } - static Boxed_Value oper(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { const Type_Info &inp_ = t_lhs.bv.get_type_info(); @@ -347,159 +308,159 @@ namespace chaiscript bool operator==(const Boxed_Numeric &r) const { - return boxed_cast(oper(equals, *this, r)); + return boxed_cast(oper(Operators::equals, *this, r)); } bool operator<(const Boxed_Numeric &r) const { - return boxed_cast(oper(less_than, *this, r)); + return boxed_cast(oper(Operators::less_than, *this, r)); } bool operator>(const Boxed_Numeric &r) const { - return boxed_cast(oper(greater_than, *this, r)); + return boxed_cast(oper(Operators::greater_than, *this, r)); } bool operator>=(const Boxed_Numeric &r) const { - return boxed_cast(oper(greater_than_equal, *this, r)); + return boxed_cast(oper(Operators::greater_than_equal, *this, r)); } bool operator<=(const Boxed_Numeric &r) const { - return boxed_cast(oper(less_than_equal, *this, r)); + return boxed_cast(oper(Operators::less_than_equal, *this, r)); } bool operator!=(const Boxed_Numeric &r) const { - return boxed_cast(oper(not_equal, *this, r)); + return boxed_cast(oper(Operators::not_equal, *this, r)); } Boxed_Value operator--() const { - return oper(pre_decrement, *this, var(0)); + return oper(Operators::pre_decrement, *this, var(0)); } Boxed_Value operator++() const { - return oper(pre_increment, *this, var(0)); + return oper(Operators::pre_increment, *this, var(0)); } Boxed_Value operator+(const Boxed_Numeric &r) const { - return oper(sum, *this, r); + return oper(Operators::sum, *this, r); } Boxed_Value operator+() const { - return oper(unary_plus, *this, Boxed_Value(0)); + return oper(Operators::unary_plus, *this, Boxed_Value(0)); } Boxed_Value operator-() const { - return oper(unary_minus, *this, Boxed_Value(0)); + return oper(Operators::unary_minus, *this, Boxed_Value(0)); } Boxed_Value operator-(const Boxed_Numeric &r) const { - return oper(difference, *this, r); + return oper(Operators::difference, *this, r); } Boxed_Value operator&=(const Boxed_Numeric &r) const { - return oper(assign_bitwise_and, *this, r); + return oper(Operators::assign_bitwise_and, *this, r); } Boxed_Value operator=(const Boxed_Numeric &r) const { - return oper(assign, *this, r); + return oper(Operators::assign, *this, r); } Boxed_Value operator|=(const Boxed_Numeric &r) const { - return oper(assign_bitwise_or, *this, r); + return oper(Operators::assign_bitwise_or, *this, r); } Boxed_Value operator^=(const Boxed_Numeric &r) const { - return oper(assign_bitwise_xor, *this, r); + return oper(Operators::assign_bitwise_xor, *this, r); } Boxed_Value operator%=(const Boxed_Numeric &r) const { - return oper(assign_remainder, *this, r); + return oper(Operators::assign_remainder, *this, r); } Boxed_Value operator<<=(const Boxed_Numeric &r) const { - return oper(assign_shift_left, *this, r); + return oper(Operators::assign_shift_left, *this, r); } Boxed_Value operator>>=(const Boxed_Numeric &r) const { - return oper(assign_shift_right, *this, r); + return oper(Operators::assign_shift_right, *this, r); } Boxed_Value operator&(const Boxed_Numeric &r) const { - return oper(bitwise_and, *this, r); + return oper(Operators::bitwise_and, *this, r); } Boxed_Value operator~() const { - return oper(bitwise_complement, *this, Boxed_Value(0)); + return oper(Operators::bitwise_complement, *this, Boxed_Value(0)); } Boxed_Value operator^(const Boxed_Numeric &r) const { - return oper(bitwise_xor, *this, r); + return oper(Operators::bitwise_xor, *this, r); } Boxed_Value operator|(const Boxed_Numeric &r) const { - return oper(bitwise_or, *this, r); + return oper(Operators::bitwise_or, *this, r); } Boxed_Value operator*=(const Boxed_Numeric &r) const { - return oper(assign_product, *this, r); + return oper(Operators::assign_product, *this, r); } Boxed_Value operator/=(const Boxed_Numeric &r) const { - return oper(assign_quotient, *this, r); + return oper(Operators::assign_quotient, *this, r); } Boxed_Value operator+=(const Boxed_Numeric &r) const { - return oper(assign_sum, *this, r); + return oper(Operators::assign_sum, *this, r); } Boxed_Value operator-=(const Boxed_Numeric &r) const { - return oper(assign_difference, *this, r); + return oper(Operators::assign_difference, *this, r); } Boxed_Value operator/(const Boxed_Numeric &r) const { - return oper(quotient, *this, r); + return oper(Operators::quotient, *this, r); } Boxed_Value operator<<(const Boxed_Numeric &r) const { - return oper(shift_left, *this, r); + return oper(Operators::shift_left, *this, r); } Boxed_Value operator*(const Boxed_Numeric &r) const { - return oper(product, *this, r); + return oper(Operators::product, *this, r); } Boxed_Value operator%(const Boxed_Numeric &r) const { - return oper(remainder, *this, r); + return oper(Operators::remainder, *this, r); } Boxed_Value operator>>(const Boxed_Numeric &r) const { - return oper(shift_right, *this, r); + return oper(Operators::shift_right, *this, r); } Boxed_Value bv; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 1479d38a..2f5bb173 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -15,6 +15,43 @@ namespace chaiscript /// Signature of module entry point that all binary loadable modules must implement. typedef ModulePtr (*Create_Module_Func)(); + struct Operators { + enum Opers + { + boolean_flag, + equals, less_than, greater_than, less_than_equal, greater_than_equal, not_equal, + non_const_flag, + assign, pre_increment, pre_decrement, assign_product, assign_sum, + assign_quotient, assign_difference, + non_const_int_flag, + assign_bitwise_and, assign_bitwise_or, assign_shift_left, assign_shift_right, + assign_remainder, assign_bitwise_xor, + const_int_flag, + shift_left, shift_right, remainder, bitwise_and, bitwise_or, bitwise_xor, bitwise_complement, + const_flag, + sum, quotient, product, difference, unary_plus, unary_minus + }; + + static const char *to_string(Opers t_oper) { + const char *opers[] = { + "", + "==", "<", ">", "<=", ">=", "!=", + "", + "=", "++", "--", "*=", "+=", + "/=", "-=", + "", + "&=", "|=", "<<=", ">>=", + "%=", "^=", + "", + "<<", ">>", "%", "&", "|", "^", "~", + "", + "+", "/", "*", "-", "+", "-" + }; + return opers[t_oper]; + } + + }; + /// Types of AST nodes available to the parser and eval class AST_Node_Type { public: From f423969a8ed401dc2015a8ca85ed56838d622a29 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 31 May 2011 08:09:30 -0600 Subject: [PATCH 08/11] Add is_prime profile script --- contrib/codeanalysis/is_prime.chai | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 contrib/codeanalysis/is_prime.chai diff --git a/contrib/codeanalysis/is_prime.chai b/contrib/codeanalysis/is_prime.chai new file mode 100644 index 00000000..c0df2fb4 --- /dev/null +++ b/contrib/codeanalysis/is_prime.chai @@ -0,0 +1,25 @@ +def isprime(n) +{ + for (var i = 2; i < n; ++i) + { + if (n % i == 0) {return false} + } + + return true +} + + +def primes(n) +{ + var count = 0 + for (var i = 2; i <= n; ++i) + { + if (isprime(i)) {++count} + } + + return count +} + + +var N = 500 +print("primes: " + primes(N).to_string()) From 2c4d69bfc0509623876aabe7598b06fbbadbb0ea Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 1 Jun 2011 22:12:50 -0600 Subject: [PATCH 09/11] Bypass dispatch during numeric operations. 2x speedup --- .../chaiscript/dispatchkit/boxed_numeric.hpp | 171 +++++++++--------- include/chaiscript/dispatchkit/type_info.hpp | 11 +- .../chaiscript/language/chaiscript_common.hpp | 80 +++++++- .../chaiscript/language/chaiscript_eval.hpp | 70 +++++-- .../chaiscript/language/chaiscript_parser.hpp | 2 +- 5 files changed, 229 insertions(+), 105 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index b2a37ff8..1bcd46b2 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -22,9 +22,6 @@ namespace chaiscript class Boxed_Numeric { private: - - - struct boolean { #pragma GCC diagnostic ignored "-Wsign-compare" @@ -163,19 +160,19 @@ namespace chaiscript template struct Go { - static Boxed_Value go(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { - return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return boolean::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) { - return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { - return binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return binary_int::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { - return const_binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return const_binary_int::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return const_binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else { throw boost::bad_any_cast(); } @@ -185,19 +182,19 @@ namespace chaiscript template struct Go { - static Boxed_Value go(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { - return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return boolean::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) { - return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { throw boost::bad_any_cast(); } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { throw boost::bad_any_cast(); } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + return const_binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); } else { throw boost::bad_any_cast(); } @@ -205,12 +202,13 @@ namespace chaiscript }; template - static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { - const Type_Info &inp_ = t_rhs.bv.get_type_info(); + const Type_Info &inp_ = t_rhs.get_type_info(); - if (inp_ == typeid(double)) - { + if (inp_ == typeid(int)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(double)) { return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(float)) { return Go::go(t_oper, t_lhs, t_rhs); @@ -245,12 +243,13 @@ namespace chaiscript } } - static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { - const Type_Info &inp_ = t_lhs.bv.get_type_info(); + const Type_Info &inp_ = t_lhs.get_type_info(); - if (inp_ == typeid(double)) - { + if (inp_ == typeid(int)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(double)) { return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long double)) { return oper_rhs(t_oper, t_lhs, t_rhs); @@ -258,8 +257,6 @@ namespace chaiscript return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(char)) { return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(int)) { - return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned int)) { return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long)) { @@ -306,161 +303,171 @@ namespace chaiscript } - bool operator==(const Boxed_Numeric &r) const + bool operator==(const Boxed_Numeric &t_rhs) const { - return boxed_cast(oper(Operators::equals, *this, r)); + return boxed_cast(oper(Operators::equals, this->bv, t_rhs.bv)); } - bool operator<(const Boxed_Numeric &r) const + bool operator<(const Boxed_Numeric &t_rhs) const { - return boxed_cast(oper(Operators::less_than, *this, r)); + return boxed_cast(oper(Operators::less_than, this->bv, t_rhs.bv)); } - bool operator>(const Boxed_Numeric &r) const + bool operator>(const Boxed_Numeric &t_rhs) const { - return boxed_cast(oper(Operators::greater_than, *this, r)); + return boxed_cast(oper(Operators::greater_than, this->bv, t_rhs.bv)); } - bool operator>=(const Boxed_Numeric &r) const + bool operator>=(const Boxed_Numeric &t_rhs) const { - return boxed_cast(oper(Operators::greater_than_equal, *this, r)); + return boxed_cast(oper(Operators::greater_than_equal, this->bv, t_rhs.bv)); } - bool operator<=(const Boxed_Numeric &r) const + bool operator<=(const Boxed_Numeric &t_rhs) const { - return boxed_cast(oper(Operators::less_than_equal, *this, r)); + return boxed_cast(oper(Operators::less_than_equal, this->bv, t_rhs.bv)); } - bool operator!=(const Boxed_Numeric &r) const + bool operator!=(const Boxed_Numeric &t_rhs) const { - return boxed_cast(oper(Operators::not_equal, *this, r)); + return boxed_cast(oper(Operators::not_equal, this->bv, t_rhs.bv)); } Boxed_Value operator--() const { - return oper(Operators::pre_decrement, *this, var(0)); + return oper(Operators::pre_decrement, this->bv, var(0)); } Boxed_Value operator++() const { - return oper(Operators::pre_increment, *this, var(0)); + return oper(Operators::pre_increment, this->bv, var(0)); } - Boxed_Value operator+(const Boxed_Numeric &r) const + Boxed_Value operator+(const Boxed_Numeric &t_rhs) const { - return oper(Operators::sum, *this, r); + return oper(Operators::sum, this->bv, t_rhs.bv); } Boxed_Value operator+() const { - return oper(Operators::unary_plus, *this, Boxed_Value(0)); + return oper(Operators::unary_plus, this->bv, Boxed_Value(0)); } Boxed_Value operator-() const { - return oper(Operators::unary_minus, *this, Boxed_Value(0)); + return oper(Operators::unary_minus, this->bv, Boxed_Value(0)); } - Boxed_Value operator-(const Boxed_Numeric &r) const + Boxed_Value operator-(const Boxed_Numeric &t_rhs) const { - return oper(Operators::difference, *this, r); + return oper(Operators::difference, this->bv, t_rhs.bv); } - Boxed_Value operator&=(const Boxed_Numeric &r) const + Boxed_Value operator&=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_bitwise_and, *this, r); + return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv); } - Boxed_Value operator=(const Boxed_Numeric &r) const + Boxed_Value operator=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign, *this, r); + return oper(Operators::assign, this->bv, t_rhs.bv); } - Boxed_Value operator|=(const Boxed_Numeric &r) const + Boxed_Value operator|=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_bitwise_or, *this, r); + return oper(Operators::assign_bitwise_or, this->bv, t_rhs.bv); } - Boxed_Value operator^=(const Boxed_Numeric &r) const + Boxed_Value operator^=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_bitwise_xor, *this, r); + return oper(Operators::assign_bitwise_xor, this->bv, t_rhs.bv); } - Boxed_Value operator%=(const Boxed_Numeric &r) const + Boxed_Value operator%=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_remainder, *this, r); + return oper(Operators::assign_remainder, this->bv, t_rhs.bv); } - Boxed_Value operator<<=(const Boxed_Numeric &r) const + Boxed_Value operator<<=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_shift_left, *this, r); + return oper(Operators::assign_shift_left, this->bv, t_rhs.bv); } - Boxed_Value operator>>=(const Boxed_Numeric &r) const + Boxed_Value operator>>=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_shift_right, *this, r); + return oper(Operators::assign_shift_right, this->bv, t_rhs.bv); } - Boxed_Value operator&(const Boxed_Numeric &r) const + Boxed_Value operator&(const Boxed_Numeric &t_rhs) const { - return oper(Operators::bitwise_and, *this, r); + return oper(Operators::bitwise_and, this->bv, t_rhs.bv); } Boxed_Value operator~() const { - return oper(Operators::bitwise_complement, *this, Boxed_Value(0)); + return oper(Operators::bitwise_complement, this->bv, Boxed_Value(0)); } - Boxed_Value operator^(const Boxed_Numeric &r) const + Boxed_Value operator^(const Boxed_Numeric &t_rhs) const { - return oper(Operators::bitwise_xor, *this, r); + return oper(Operators::bitwise_xor, this->bv, t_rhs.bv); } - Boxed_Value operator|(const Boxed_Numeric &r) const + Boxed_Value operator|(const Boxed_Numeric &t_rhs) const { - return oper(Operators::bitwise_or, *this, r); + return oper(Operators::bitwise_or, this->bv, t_rhs.bv); } - Boxed_Value operator*=(const Boxed_Numeric &r) const + Boxed_Value operator*=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_product, *this, r); + return oper(Operators::assign_product, this->bv, t_rhs.bv); } - Boxed_Value operator/=(const Boxed_Numeric &r) const + Boxed_Value operator/=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_quotient, *this, r); + return oper(Operators::assign_quotient, this->bv, t_rhs.bv); } - Boxed_Value operator+=(const Boxed_Numeric &r) const + Boxed_Value operator+=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_sum, *this, r); + return oper(Operators::assign_sum, this->bv, t_rhs.bv); } - Boxed_Value operator-=(const Boxed_Numeric &r) const + Boxed_Value operator-=(const Boxed_Numeric &t_rhs) const { - return oper(Operators::assign_difference, *this, r); + return oper(Operators::assign_difference, this->bv, t_rhs.bv); } - Boxed_Value operator/(const Boxed_Numeric &r) const + Boxed_Value operator/(const Boxed_Numeric &t_rhs) const { - return oper(Operators::quotient, *this, r); + return oper(Operators::quotient, this->bv, t_rhs.bv); } - Boxed_Value operator<<(const Boxed_Numeric &r) const + Boxed_Value operator<<(const Boxed_Numeric &t_rhs) const { - return oper(Operators::shift_left, *this, r); + return oper(Operators::shift_left, this->bv, t_rhs.bv); } - Boxed_Value operator*(const Boxed_Numeric &r) const + Boxed_Value operator*(const Boxed_Numeric &t_rhs) const { - return oper(Operators::product, *this, r); + return oper(Operators::product, this->bv, t_rhs.bv); } - Boxed_Value operator%(const Boxed_Numeric &r) const + Boxed_Value operator%(const Boxed_Numeric &t_rhs) const { - return oper(Operators::remainder, *this, r); + return oper(Operators::remainder, this->bv, t_rhs.bv); } - Boxed_Value operator>>(const Boxed_Numeric &r) const + Boxed_Value operator>>(const Boxed_Numeric &t_rhs) const { - return oper(Operators::shift_right, *this, r); + return oper(Operators::shift_right, this->bv, t_rhs.bv); + } + + static Boxed_Value do_oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + { + return oper(t_oper, t_lhs, t_rhs); + } + + static Boxed_Value do_oper(Operators::Opers t_oper, const Boxed_Value &t_lhs) + { + return oper(t_oper, t_lhs, const_var(0)); } Boxed_Value bv; diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index acbdbad1..8bd0b9a7 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -149,7 +150,7 @@ namespace chaiscript { return Type_Info(boost::is_const::type>::type>::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, - boost::is_arithmetic::value, + boost::is_arithmetic::value && !boost::is_same::type, bool>::value, &typeid(T), &typeid(typename Bare_Type::type)); } @@ -164,7 +165,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, - boost::is_arithmetic::value, + boost::is_arithmetic::value && !boost::is_same::type, bool>::value, &typeid(boost::shared_ptr ), &typeid(typename Bare_Type::type)); } @@ -179,7 +180,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, - boost::is_arithmetic::value, + boost::is_arithmetic::value && !boost::is_same::type, bool>::value, &typeid(const boost::shared_ptr &), &typeid(typename Bare_Type::type)); } @@ -194,7 +195,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, - boost::is_arithmetic::value, + boost::is_arithmetic::value && !boost::is_same::type, bool>::value, &typeid(boost::reference_wrapper ), &typeid(typename Bare_Type::type)); } @@ -209,7 +210,7 @@ namespace chaiscript { return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, boost::is_void::value, - boost::is_arithmetic::value, + boost::is_arithmetic::value && !boost::is_same::type, bool>::value, &typeid(const boost::reference_wrapper &), &typeid(typename Bare_Type::type)); } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 2f5bb173..79e24d6a 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -29,7 +29,8 @@ namespace chaiscript const_int_flag, shift_left, shift_right, remainder, bitwise_and, bitwise_or, bitwise_xor, bitwise_complement, const_flag, - sum, quotient, product, difference, unary_plus, unary_minus + sum, quotient, product, difference, unary_plus, unary_minus, + invalid }; static const char *to_string(Opers t_oper) { @@ -45,11 +46,86 @@ namespace chaiscript "", "<<", ">>", "%", "&", "|", "^", "~", "", - "+", "/", "*", "-", "+", "-" + "+", "/", "*", "-", "+", "-", + "" }; return opers[t_oper]; } + static Opers to_operator(const std::string &t_str, bool t_is_unary = false) + { + if (t_str == "==") + { + return equals; + } else if (t_str == "<") { + return less_than; + } else if (t_str == ">") { + return greater_than; + } else if (t_str == "<=") { + return less_than_equal; + } else if (t_str == ">=") { + return greater_than_equal; + } else if (t_str == "!=") { + return not_equal; + } else if (t_str == "=") { + return assign; + } else if (t_str == "++") { + return pre_increment; + } else if (t_str == "--") { + return pre_decrement; + } else if (t_str == "*=") { + return assign_product; + } else if (t_str == "+=") { + return assign_sum; + } else if (t_str == "-=") { + return assign_difference; + } else if (t_str == "&=") { + return assign_bitwise_and; + } else if (t_str == "|=") { + return assign_bitwise_or; + } else if (t_str == "<<=") { + return assign_shift_left; + } else if (t_str == ">>=") { + return assign_shift_right; + } else if (t_str == "%=") { + return assign_remainder; + } else if (t_str == "^=") { + return assign_bitwise_xor; + } else if (t_str == "<<") { + return shift_left; + } else if (t_str == ">>") { + return shift_right; + } else if (t_str == "%") { + return remainder; + } else if (t_str == "&") { + return bitwise_and; + } else if (t_str == "|") { + return bitwise_or; + } else if (t_str == "^") { + return bitwise_xor; + } else if (t_str == "~") { + return bitwise_complement; + } else if (t_str == "+") { + if (t_is_unary) { + return unary_plus; + } else { + return sum; + } + } else if (t_str == "-") { + if (t_is_unary) { + return unary_minus; + } else { + return difference; + } + } else if (t_str == "/") { + return quotient; + } else if (t_str == "*") { + return product; + } else { + return invalid; + } + } + }; /// Types of AST nodes available to the parser and eval diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 5e59d7fd..0b1a0fbf 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -39,22 +39,36 @@ namespace chaiscript struct Binary_Operator_AST_Node : public AST_Node { public: Binary_Operator_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : - AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } + AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) + { } + virtual ~Binary_Operator_AST_Node() {} - virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ - Boxed_Value retval; - - retval = this->children[0]->eval(t_ss); + virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) { + Boxed_Value retval = this->children[0]->eval(t_ss); + // Else loop through all children collecting the retval for (size_t i = 1; i < this->children.size(); i += 2) { + Boxed_Value rhs(this->children[i+1]->eval(t_ss)); + Operators::Opers oper = Operators::to_operator(children[i]->text); + try { - retval = t_ss.call_function(this->children[i]->text, retval, this->children[i+1]->eval(t_ss)); + if (oper != Operators::invalid && retval.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) + { + // If it's an arithmetic operation we want to short circuit dispatch + try{ + retval = Boxed_Numeric::do_oper(oper, retval, rhs); + } catch (...) { + throw exception::eval_error("Error with numeric operator calling: " + children[i]->text); + } + + } else { + retval = t_ss.call_function(this->children[1]->text, retval, rhs); + } } catch(const exception::dispatch_error &){ throw exception::eval_error("Can not find appropriate '" + this->children[i]->text + "'"); } } - return retval; } @@ -258,16 +272,28 @@ namespace chaiscript struct Equation_AST_Node : public AST_Node { public: Equation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equation, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : - AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } + AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) + {} + virtual ~Equation_AST_Node() {} - virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ + virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) { Boxed_Value retval = this->children.back()->eval(t_ss); + if (this->children.size() > 1) { for (int i = static_cast(this->children.size())-3; i >= 0; i -= 2) { - if (this->children[i+1]->text == "=") { - Boxed_Value lhs = this->children[i]->eval(t_ss); + Boxed_Value lhs = this->children[i]->eval(t_ss); + Operators::Opers oper = Operators::to_operator(this->children[i+1]->text); + + if (oper != Operators::invalid && lhs.get_type_info().is_arithmetic() && retval.get_type_info().is_arithmetic()) + { + try { + retval = Boxed_Numeric::do_oper(oper, lhs, retval); + } catch (const std::exception &) { + throw exception::eval_error("Error with unsupported arithmetic assignment operation"); + } + } else if (this->children[i+1]->text == "=") { try { if (lhs.is_undef()) { retval = t_ss.call_function("clone", retval); @@ -286,7 +312,6 @@ namespace chaiscript } } else if (this->children[i+1]->text == ":=") { - Boxed_Value lhs = this->children[i]->eval(t_ss); if (lhs.is_undef() || type_match(lhs, retval)) { lhs.assign(retval); } else { @@ -295,7 +320,7 @@ namespace chaiscript } else { try { - retval = t_ss.call_function(this->children[i+1]->text, this->children[i]->eval(t_ss), retval); + retval = t_ss.call_function(this->children[i+1]->text, lhs, retval); } catch(const exception::dispatch_error &){ throw exception::eval_error("Can not find appropriate '" + this->children[i+1]->text + "'"); } @@ -304,6 +329,7 @@ namespace chaiscript } return retval; } + }; struct Var_Decl_AST_Node : public AST_Node { @@ -782,10 +808,24 @@ namespace chaiscript struct Prefix_AST_Node : public AST_Node { public: Prefix_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : - AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } + AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) + { } + virtual ~Prefix_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ - return t_ss.call_function(this->children[0]->text, this->children[1]->eval(t_ss)); + Boxed_Value bv(this->children[1]->eval(t_ss)); + + Operators::Opers oper = Operators::to_operator(children[0]->text, true); + try { + if (bv.get_type_info().is_arithmetic() && oper != Operators::invalid) + { + return Boxed_Numeric::do_oper(oper, bv); + } else { + return t_ss.call_function(this->children[0]->text, bv); + } + } catch (const exception::dispatch_error &) { + throw exception::eval_error("Error with prefix operator evaluation: " + children[0]->text); + } } }; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 035e3ec1..bafd4d82 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -249,7 +249,7 @@ namespace chaiscript m_match_stack.push_back(t_t); } else { - //todo: fix the fact that a successful match that captured no ast_nodes doesn't have any real start position + /// \todo fix the fact that a successful match that captured no ast_nodes doesn't have any real start position m_match_stack.push_back(t_t); } } From 6491262491f6cfb647fd54544ea6fa0944725bcc Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 3 Jun 2011 12:41:38 -0600 Subject: [PATCH 10/11] Add direct access to Boxed_Value data * for high performance operations --- .../chaiscript/dispatchkit/boxed_numeric.hpp | 22 ++++---- .../chaiscript/dispatchkit/boxed_value.hpp | 54 ++++++++++--------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 1bcd46b2..78c70aab 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -164,15 +164,15 @@ namespace chaiscript { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { - return boolean::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); - } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) { - return binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); - } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { - return binary_int::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); + return boolean::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); + } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const()) { + return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr())); + } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag && !t_lhs.is_const()) { + return binary_int::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr())); } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { - return const_binary_int::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); + return const_binary_int::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); + return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); } else { throw boost::bad_any_cast(); } @@ -186,15 +186,15 @@ namespace chaiscript { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { - return boolean::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); - } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) { - return binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); + return boolean::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); + } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const()) { + return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr())); } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { throw boost::bad_any_cast(); } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { throw boost::bad_any_cast(); } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, boxed_cast(t_lhs), boxed_cast(t_rhs)); + return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); } else { throw boost::bad_any_cast(); } diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 15a2a9d9..d49931fa 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -23,6 +23,7 @@ namespace chaiscript { + /// \brief A wrapper for holding any valid C++ type. All types in ChaiScript are Boxed_Value objects /// \sa chaiscript::boxed_cast class Boxed_Value @@ -41,19 +42,12 @@ namespace chaiscript */ struct Data { - template - static bool is_null(boost::any *a) - { - boost::shared_ptr *ptr = boost::any_cast >(a); - return ptr->get() == 0; - } - Data(const Type_Info &ti, const boost::any &to, bool tr, - const boost::function &t_is_null = boost::function()) - : m_type_info(ti), m_obj(to), - m_is_ref(tr), m_is_null(t_is_null) + const void *t_void_ptr) + : m_type_info(ti), m_obj(to), m_data_ptr(ti.is_const()?0:const_cast(t_void_ptr)), m_const_data_ptr(t_void_ptr), + m_is_ref(tr) { } @@ -62,7 +56,8 @@ namespace chaiscript m_type_info = rhs.m_type_info; m_obj = rhs.m_obj; m_is_ref = rhs.m_is_ref; - m_is_null = rhs.m_is_null; + m_data_ptr = rhs.m_data_ptr; + m_const_data_ptr = rhs.m_const_data_ptr; return *this; } @@ -73,8 +68,9 @@ namespace chaiscript Type_Info m_type_info; boost::any m_obj; + void *m_data_ptr; + const void *m_const_data_ptr; bool m_is_ref; - boost::function m_is_null; std::vector > m_dependencies; }; @@ -85,7 +81,8 @@ namespace chaiscript return boost::shared_ptr (new Data( detail::Get_Type_Info::get(), boost::any(), - false) + false, + 0) ); } @@ -102,7 +99,7 @@ namespace chaiscript detail::Get_Type_Info::get(), boost::any(obj), false, - boost::function(&Data::is_null)) + obj.get()) ); } @@ -117,19 +114,21 @@ namespace chaiscript { return boost::shared_ptr(new Data( detail::Get_Type_Info::get(), - boost::any(obj), - true) + boost::any(obj), + true, + obj.get_pointer()) ); } template static boost::shared_ptr get(const T& t) { + boost::shared_ptr p(new T(t)); return boost::shared_ptr(new Data( detail::Get_Type_Info::get(), - boost::any(boost::shared_ptr(new T(t))), + boost::any(p), false, - boost::function(&Data::is_null)) + p.get()) ); } @@ -138,7 +137,8 @@ namespace chaiscript return boost::shared_ptr (new Data( Type_Info(), boost::any(), - false) + false, + 0) ); } @@ -224,12 +224,7 @@ namespace chaiscript bool is_null() const { - if (m_data->m_is_null) - { - return m_data->m_is_null(&m_data->m_obj); - } else { - return false; - } + return (m_data->m_data_ptr == 0 && m_data->m_const_data_ptr == 0); } const boost::any & get() const @@ -265,6 +260,15 @@ namespace chaiscript } } + void *get_ptr() const + { + return m_data->m_data_ptr; + } + + const void *get_const_ptr() const + { + return m_data->m_const_data_ptr; + } private: boost::shared_ptr m_data; From d4ef226911139695aafd50fecf120e31c343fa04 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 3 Jun 2011 13:48:32 -0600 Subject: [PATCH 11/11] Reduce creation of new Boxed_Value containers when returning the same value that was passed in --- contrib/codeanalysis/is_prime.chai | 2 +- .../chaiscript/dispatchkit/boxed_numeric.hpp | 70 +++++++++++-------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/contrib/codeanalysis/is_prime.chai b/contrib/codeanalysis/is_prime.chai index c0df2fb4..d34bad25 100644 --- a/contrib/codeanalysis/is_prime.chai +++ b/contrib/codeanalysis/is_prime.chai @@ -21,5 +21,5 @@ def primes(n) } -var N = 500 +var N = 5000 print("primes: " + primes(N).to_string()) diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 78c70aab..86b8a401 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -26,7 +26,7 @@ namespace chaiscript { #pragma GCC diagnostic ignored "-Wsign-compare" template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { switch (t_oper) { @@ -52,61 +52,75 @@ namespace chaiscript struct binary { template - static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) { switch (t_oper) { case Operators::assign: - return var(&(t = u)); + t = u; + break; case Operators::pre_increment: - return var(&(++t)); + ++t; + break; case Operators::pre_decrement: - return var(&(--t)); + --t; + break; case Operators::assign_product: - return var(&(t *= u)); + t *= u; + break; case Operators::assign_sum: - return var(&(t += u)); + t += u; + break; case Operators::assign_quotient: - return var(&(t /= u)); + t /= u; + break; case Operators::assign_difference: - return var(&(t -= u)); + t -= u; + break; default: throw boost::bad_any_cast(); } - throw boost::bad_any_cast(); + + return t_lhs; } }; struct binary_int { template - static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) { switch (t_oper) { case Operators::assign_bitwise_and: - return var(&(t &= u)); + t &= u; + break; case Operators::assign_bitwise_or: - return var(&(t |= u)); + t |= u; + break; case Operators::assign_shift_left: - return var(&(t <<= u)); + t <<= u; + break; case Operators::assign_shift_right: - return var(&(t >>= u)); + t >>= u; + break; case Operators::assign_remainder: - return var(&(t %= u)); + t %= u; + break; case Operators::assign_bitwise_xor: - return var(&(t ^= u)); + t ^= u; + break; default: throw boost::bad_any_cast(); } - throw boost::bad_any_cast(); + return t_lhs; } }; struct const_binary_int { template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { switch (t_oper) { @@ -134,7 +148,7 @@ namespace chaiscript struct const_binary { template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u) + static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { switch (t_oper) { @@ -164,15 +178,15 @@ namespace chaiscript { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { - return boolean::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); + return boolean::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const()) { - return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr())); + return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag && !t_lhs.is_const()) { - return binary_int::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr())); + return binary_int::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { - return const_binary_int::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); + return const_binary_int::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); + return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else { throw boost::bad_any_cast(); } @@ -186,15 +200,15 @@ namespace chaiscript { if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { - return boolean::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); + return boolean::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const()) { - return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr())); + return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { throw boost::bad_any_cast(); } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { throw boost::bad_any_cast(); } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr())); + return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else { throw boost::bad_any_cast(); }