Bypass dispatch during numeric operations. 2x speedup
This commit is contained in:
parent
f423969a8e
commit
2c4d69bfc0
@ -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<typename LHS, typename RHS, bool Float>
|
||||
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<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return boolean::go<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs), boxed_cast<const RHS &>(t_rhs));
|
||||
} else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) {
|
||||
return binary::go<LHS, RHS>(t_oper, boxed_cast<LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return binary::go<LHS, RHS>(t_oper, boxed_cast<LHS &>(t_lhs), boxed_cast<const RHS &>(t_rhs));
|
||||
} else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) {
|
||||
return binary_int::go<LHS, RHS>(t_oper, boxed_cast<LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return binary_int::go<LHS, RHS>(t_oper, boxed_cast<LHS &>(t_lhs), boxed_cast<const RHS &>(t_rhs));
|
||||
} else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) {
|
||||
return const_binary_int::go<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return const_binary_int::go<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs), boxed_cast<const RHS &>(t_rhs));
|
||||
} else if (t_oper > Operators::const_flag) {
|
||||
return const_binary::go<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return const_binary::go<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs), boxed_cast<const RHS &>(t_rhs));
|
||||
} else {
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
@ -185,19 +182,19 @@ namespace chaiscript
|
||||
template<typename LHS, typename RHS>
|
||||
struct Go<LHS, RHS, true>
|
||||
{
|
||||
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<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return boolean::go<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs), boxed_cast<const RHS &>(t_rhs));
|
||||
} else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag) {
|
||||
return binary::go<LHS, RHS>(t_oper, boxed_cast<LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return binary::go<LHS, RHS>(t_oper, boxed_cast<LHS &>(t_lhs), boxed_cast<const RHS &>(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<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs.bv), boxed_cast<const RHS &>(t_rhs.bv));
|
||||
return const_binary::go<LHS, RHS>(t_oper, boxed_cast<const LHS &>(t_lhs), boxed_cast<const RHS &>(t_rhs));
|
||||
} else {
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
@ -205,12 +202,13 @@ namespace chaiscript
|
||||
};
|
||||
|
||||
template<typename LHS, bool Float>
|
||||
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<LHS, int, Float>::go(t_oper, t_lhs, t_rhs);
|
||||
} else if (inp_ == typeid(double)) {
|
||||
return Go<LHS, double, true>::go(t_oper, t_lhs, t_rhs);
|
||||
} else if (inp_ == typeid(float)) {
|
||||
return Go<LHS, float, true>::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<int, false>(t_oper, t_lhs, t_rhs);
|
||||
} else if (inp_ == typeid(double)) {
|
||||
return oper_rhs<double, true>(t_oper, t_lhs, t_rhs);
|
||||
} else if (inp_ == typeid(long double)) {
|
||||
return oper_rhs<long double, true>(t_oper, t_lhs, t_rhs);
|
||||
@ -258,8 +257,6 @@ namespace chaiscript
|
||||
return oper_rhs<float, true>(t_oper, t_lhs, t_rhs);
|
||||
} else if (inp_ == typeid(char)) {
|
||||
return oper_rhs<char, false>(t_oper, t_lhs, t_rhs);
|
||||
} else if (inp_ == typeid(int)) {
|
||||
return oper_rhs<int, false>(t_oper, t_lhs, t_rhs);
|
||||
} else if (inp_ == typeid(unsigned int)) {
|
||||
return oper_rhs<unsigned int, false>(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<bool>(oper(Operators::equals, *this, r));
|
||||
return boxed_cast<bool>(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<bool>(oper(Operators::less_than, *this, r));
|
||||
return boxed_cast<bool>(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<bool>(oper(Operators::greater_than, *this, r));
|
||||
return boxed_cast<bool>(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<bool>(oper(Operators::greater_than_equal, *this, r));
|
||||
return boxed_cast<bool>(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<bool>(oper(Operators::less_than_equal, *this, r));
|
||||
return boxed_cast<bool>(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<bool>(oper(Operators::not_equal, *this, r));
|
||||
return boxed_cast<bool>(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;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
@ -149,7 +150,7 @@ namespace chaiscript
|
||||
{
|
||||
return Type_Info(boost::is_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||
boost::is_void<T>::value,
|
||||
boost::is_arithmetic<T>::value,
|
||||
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
|
||||
&typeid(T),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@ -164,7 +165,7 @@ namespace chaiscript
|
||||
{
|
||||
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||
boost::is_void<T>::value,
|
||||
boost::is_arithmetic<T>::value,
|
||||
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
|
||||
&typeid(boost::shared_ptr<T> ),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@ -179,7 +180,7 @@ namespace chaiscript
|
||||
{
|
||||
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||
boost::is_void<T>::value,
|
||||
boost::is_arithmetic<T>::value,
|
||||
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
|
||||
&typeid(const boost::shared_ptr<T> &),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@ -194,7 +195,7 @@ namespace chaiscript
|
||||
{
|
||||
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||
boost::is_void<T>::value,
|
||||
boost::is_arithmetic<T>::value,
|
||||
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
|
||||
&typeid(boost::reference_wrapper<T> ),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@ -209,7 +210,7 @@ namespace chaiscript
|
||||
{
|
||||
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||
boost::is_void<T>::value,
|
||||
boost::is_arithmetic<T>::value,
|
||||
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
|
||||
&typeid(const boost::reference_wrapper<T> &),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<std::string> &t_fname=boost::shared_ptr<std::string>(), 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<std::string> &t_fname=boost::shared_ptr<std::string>(), 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<int>(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<std::string> &t_fname=boost::shared_ptr<std::string>(), 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);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user