Compare commits
33 Commits
v2.1.0
...
Release-2.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4457df9ff5 | ||
![]() |
e601de9d18 | ||
![]() |
37b2ac2056 | ||
![]() |
645cdddd70 | ||
![]() |
ac8462fb67 | ||
![]() |
636c55493c | ||
![]() |
e2a2c14c0d | ||
![]() |
c418644a5b | ||
![]() |
fbf8f53e04 | ||
![]() |
a0c6366479 | ||
![]() |
15ffbd200a | ||
![]() |
1c6b2725b3 | ||
![]() |
95c124ca35 | ||
![]() |
1bd73884b2 | ||
![]() |
d3e4af433e | ||
![]() |
9f65303370 | ||
![]() |
391eaa9e11 | ||
![]() |
ed11f48847 | ||
![]() |
9dddb49850 | ||
![]() |
cca477dae6 | ||
![]() |
07352a16a3 | ||
![]() |
e14931f389 | ||
![]() |
f4a680a582 | ||
![]() |
e6c6223c5b | ||
![]() |
cbc61d898c | ||
![]() |
3a37ceedb7 | ||
![]() |
1bc968e788 | ||
![]() |
fe5a935abd | ||
![]() |
4e5c972e66 | ||
![]() |
d946cb7e9d | ||
![]() |
18bfead387 | ||
![]() |
4c015d7e44 | ||
![]() |
1122f2c818 |
@@ -10,6 +10,7 @@
|
|||||||
#include "dispatchkit.hpp"
|
#include "dispatchkit.hpp"
|
||||||
#include "dynamic_object.hpp"
|
#include "dynamic_object.hpp"
|
||||||
#include "register_function.hpp"
|
#include "register_function.hpp"
|
||||||
|
#include "operators.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -17,141 +18,6 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Set of helper functions for common operators
|
|
||||||
*/
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
|
||||||
Ret add(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 + p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
|
||||||
Ret subtract(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 - p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
|
||||||
Ret divide(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 / p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
|
||||||
Ret multiply(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 * p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
|
||||||
Ret modulus(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 % p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
|
||||||
Ret shift_left(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 << p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
|
||||||
Ret shift_right(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 >> p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
P1 &assign(P1 &p1, const P2 &p2)
|
|
||||||
{
|
|
||||||
return (p1 = p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
bool equals(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 == p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
bool not_equals(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 != p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
bool less_than(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 < p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
bool greater_than(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 > p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
bool less_than_equals(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 <= p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
bool greater_than_equals(P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return p1 >= p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
P1 ×equal(P1 &p1, const P2 &p2)
|
|
||||||
{
|
|
||||||
return (p1 *= p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
P1 ÷sequal(P1 &p1, const P2 &p2)
|
|
||||||
{
|
|
||||||
return (p1 /= p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
P1 &addsequal(P1 &p1, const P2 &p2)
|
|
||||||
{
|
|
||||||
return (p1 += p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
|
||||||
P1 &subtractsequal(P1 &p1, const P2 &p2)
|
|
||||||
{
|
|
||||||
return (p1 -= p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1>
|
|
||||||
P1 &prefixincrement(P1 &p1)
|
|
||||||
{
|
|
||||||
return (++p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1>
|
|
||||||
P1 &prefixdecrement(P1 &p1)
|
|
||||||
{
|
|
||||||
return (--p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1>
|
|
||||||
P1 &prefixnegate(P1 &p1)
|
|
||||||
{
|
|
||||||
return (p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P1>
|
|
||||||
P1 &prefixnot(P1 &p1)
|
|
||||||
{
|
|
||||||
return (p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special helpers for generating generic "POD" type operators
|
/* Special helpers for generating generic "POD" type operators
|
||||||
* The POD operators are needed for general support of C++ POD
|
* The POD operators are needed for general support of C++ POD
|
||||||
@@ -162,6 +28,7 @@ namespace chaiscript
|
|||||||
template<typename P1>
|
template<typename P1>
|
||||||
P1 &assign_pod(P1 &p1, Boxed_POD_Value v)
|
P1 &assign_pod(P1 &p1, Boxed_POD_Value v)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (v.m_isfloat)
|
if (v.m_isfloat)
|
||||||
{
|
{
|
||||||
return (p1 = P1(v.d));
|
return (p1 = P1(v.d));
|
||||||
@@ -182,7 +49,63 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename P1>
|
template<typename P1>
|
||||||
P1 ×equal_pod(P1 &p1, Boxed_POD_Value r)
|
P1 &assign_bitwise_and_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
|
{
|
||||||
|
if (!r.m_isfloat)
|
||||||
|
{
|
||||||
|
return p1 &= P1(r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("&= only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename P1>
|
||||||
|
P1 &assign_xor_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
|
{
|
||||||
|
if (!r.m_isfloat)
|
||||||
|
{
|
||||||
|
return p1 ^= P1(r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("^= only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename P1>
|
||||||
|
P1 &assign_bitwise_or_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
|
{
|
||||||
|
if (!r.m_isfloat)
|
||||||
|
{
|
||||||
|
return p1 |= P1(r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("&= only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename P1>
|
||||||
|
P1 &assign_difference_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
|
{
|
||||||
|
if (r.m_isfloat)
|
||||||
|
{
|
||||||
|
return p1 -= P1(r.d);
|
||||||
|
} else {
|
||||||
|
return p1 -= P1(r.i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename P1>
|
||||||
|
P1 &assign_left_shift_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
|
{
|
||||||
|
if (!r.m_isfloat)
|
||||||
|
{
|
||||||
|
return p1 <<= P1(r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("<<= only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename P1>
|
||||||
|
P1 &assign_product_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
{
|
{
|
||||||
if (r.m_isfloat)
|
if (r.m_isfloat)
|
||||||
{
|
{
|
||||||
@@ -193,7 +116,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename P1>
|
template<typename P1>
|
||||||
P1 ÷sequal_pod(P1 &p1, Boxed_POD_Value r)
|
P1 &assign_quotient_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
{
|
{
|
||||||
if (r.m_isfloat)
|
if (r.m_isfloat)
|
||||||
{
|
{
|
||||||
@@ -204,7 +127,31 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename P1>
|
template<typename P1>
|
||||||
P1 &addsequal_pod(P1 &p1, Boxed_POD_Value r)
|
P1 &assign_remainder_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
|
{
|
||||||
|
if (!r.m_isfloat)
|
||||||
|
{
|
||||||
|
return p1 %= P1(r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("%= only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename P1>
|
||||||
|
P1 &assign_right_shift_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
|
{
|
||||||
|
if (!r.m_isfloat)
|
||||||
|
{
|
||||||
|
return p1 >>= P1(r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast(">>= only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename P1>
|
||||||
|
P1 &assign_sum_pod(P1 &p1, Boxed_POD_Value r)
|
||||||
{
|
{
|
||||||
if (r.m_isfloat)
|
if (r.m_isfloat)
|
||||||
{
|
{
|
||||||
@@ -214,223 +161,66 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename P1>
|
|
||||||
P1 &subtractsequal_pod(P1 &p1, Boxed_POD_Value r)
|
|
||||||
{
|
|
||||||
if (r.m_isfloat)
|
|
||||||
{
|
|
||||||
return p1 -= P1(r.d);
|
|
||||||
} else {
|
|
||||||
return p1 -= P1(r.i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "=" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_equals(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::equals<const T&, const T&>), "=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "+" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_add(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::add<T, const T&, const T&>), "+");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "+=" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_add_equals(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::addsequal<T, T>), "+=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "-" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_subtract(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::subtract<T, const T&, const T&>), "-");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "/" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_divide(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::divide<T, const T&, const T&>), "/");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "*" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_multiply(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::multiply<T, const T&, const T&>), "*");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "!=" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_not_equals(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::not_equals<const T&, const T&>), "!=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add user defined assignment operator for T = U
|
|
||||||
*/
|
|
||||||
template<typename T, typename U>
|
|
||||||
ModulePtr oper_assign_overload(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::assign<T,U>), "=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "=" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_assign(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::assign<T,T>), "=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add assignment operator for T = POD.
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_assign_pod(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::assign_pod<T>), "=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "<" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_less_than(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::less_than<const T&, const T&>), "<");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of ">" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_greater_than(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::greater_than<const T&, const T&>), ">");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of "<=" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_less_than_equals(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::less_than_equals<const T&, const T&>), "<=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical form of ">=" for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr oper_greater_than_equals(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::greater_than_equals<const T&, const T&>), ">=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add user defined comparison operators for T and R.
|
|
||||||
* Examples: T < R, T == R, etc.
|
|
||||||
*/
|
|
||||||
template<typename T, typename R>
|
|
||||||
ModulePtr opers_comparison_overload(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::equals<const T&, const R&>), "==");
|
|
||||||
m->add(fun(&detail::not_equals<const T&, const R&>), "!=");
|
|
||||||
m->add(fun(&detail::less_than<const T&, const R&>), "<");
|
|
||||||
m->add(fun(&detail::greater_than<const T&, const R&>), ">");
|
|
||||||
m->add(fun(&detail::less_than_equals<const T&, const R&>), "<=");
|
|
||||||
m->add(fun(&detail::greater_than_equals<const T&, const R&>), ">=");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical forms of all comparison operators for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr opers_comparison(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr opers_comparison(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
opers_comparison_overload<T, T>(m);
|
operators::equal<T>(m);
|
||||||
|
operators::greater_than<T>(m);
|
||||||
|
operators::greater_than_equal<T>(m);
|
||||||
|
operators::less_than<T>(m);
|
||||||
|
operators::less_than_equal<T>(m);
|
||||||
|
operators::not_equal<T>(m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add all arithmetic operators that return a type of Ret, taking
|
|
||||||
* a lhs of T and a rhs of R, when possible.
|
|
||||||
* examples: Ret = T + R;
|
|
||||||
* ++T
|
|
||||||
* T *= R;
|
|
||||||
*/
|
|
||||||
template<typename Ret, typename T, typename R>
|
|
||||||
ModulePtr opers_arithmetic_overload(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::add<Ret, T, R>), "+");
|
|
||||||
m->add(fun(&detail::subtract<Ret, T, R>), "-");
|
|
||||||
m->add(fun(&detail::divide<Ret, T, R>), "/");
|
|
||||||
m->add(fun(&detail::multiply<Ret, T, R>), "*");
|
|
||||||
m->add(fun(&detail::timesequal<T, R>), "*=");
|
|
||||||
m->add(fun(&detail::dividesequal<T, R>), "/=");
|
|
||||||
m->add(fun(&detail::subtractsequal<T, R>), "-=");
|
|
||||||
m->add(fun(&detail::addsequal<T, R>), "+=");
|
|
||||||
m->add(fun(&detail::prefixincrement<T>), "++");
|
|
||||||
m->add(fun(&detail::prefixdecrement<T>), "--");
|
|
||||||
m->add(fun(&detail::prefixnegate<T>), "-");
|
|
||||||
m->add(fun(&detail::prefixnot<T>), "!");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add arithmetic assign operators for POD types:
|
|
||||||
* example: POD *= T, POD /= T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr opers_arithmetic_modify_pod(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr opers_integer_arithmetic(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&detail::timesequal_pod<T>), "*=");
|
operators::assign_bitwise_and<T>(m);
|
||||||
m->add(fun(&detail::dividesequal_pod<T>), "/=");
|
operators::assign_xor<T>(m);
|
||||||
m->add(fun(&detail::subtractsequal_pod<T>), "-=");
|
operators::assign_bitwise_or<T>(m);
|
||||||
m->add(fun(&detail::addsequal_pod<T>), "+=");
|
operators::assign_difference<T>(m);
|
||||||
|
operators::assign_left_shift<T>(m);
|
||||||
|
operators::assign_product<T>(m);
|
||||||
|
operators::assign_quotient<T>(m);
|
||||||
|
operators::assign_remainder<T>(m);
|
||||||
|
operators::assign_right_shift<T>(m);
|
||||||
|
operators::assign_sum<T>(m);
|
||||||
|
|
||||||
|
operators::prefix_decrement<T>(m);
|
||||||
|
operators::prefix_increment<T>(m);
|
||||||
|
operators::addition<T>(m);
|
||||||
|
operators::unary_plus<T>(m);
|
||||||
|
operators::subtraction<T>(m);
|
||||||
|
operators::unary_minus<T>(m);
|
||||||
|
operators::bitwise_and<T>(m);
|
||||||
|
operators::bitwise_compliment<T>(m);
|
||||||
|
operators::bitwise_xor<T>(m);
|
||||||
|
operators::bitwise_or<T>(m);
|
||||||
|
operators::division<T>(m);
|
||||||
|
operators::left_shift<T>(m);
|
||||||
|
operators::multiplication<T>(m);
|
||||||
|
operators::remainder<T>(m);
|
||||||
|
operators::right_shift<T>(m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr opers_float_arithmetic(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
operators::assign_difference<T>(m);
|
||||||
|
operators::assign_product<T>(m);
|
||||||
|
operators::assign_quotient<T>(m);
|
||||||
|
operators::assign_sum<T>(m);
|
||||||
|
|
||||||
|
operators::addition<T>(m);
|
||||||
|
operators::unary_plus<T>(m);
|
||||||
|
operators::subtraction<T>(m);
|
||||||
|
operators::unary_minus<T>(m);
|
||||||
|
operators::division<T>(m);
|
||||||
|
operators::multiplication<T>(m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,16 +266,6 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add canonical forms of all arithmetic operators for type T
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
ModulePtr opers_arithmetic(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
opers_arithmetic_overload<T, T, T>(m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* to_string function for internal use. Uses ostream operator<<
|
* to_string function for internal use. Uses ostream operator<<
|
||||||
*/
|
*/
|
||||||
@@ -506,6 +286,17 @@ namespace chaiscript
|
|||||||
return boost::lexical_cast<Input>(i);
|
return boost::lexical_cast<Input>(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add assignment operator for T = POD.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr oper_assign_pod(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&detail::assign_pod<T>), "=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add all common functions for a POD type. All operators, and
|
* Add all common functions for a POD type. All operators, and
|
||||||
* common conversions
|
* common conversions
|
||||||
@@ -515,16 +306,52 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
m->add(user_type<T>(), name);
|
m->add(user_type<T>(), name);
|
||||||
basic_constructors<T>(name, m);
|
basic_constructors<T>(name, m);
|
||||||
oper_assign<T>(m);
|
operators::assign<T>(m);
|
||||||
oper_assign_pod<T>(m);
|
oper_assign_pod<T>(m);
|
||||||
construct_pod<T>(name, m);
|
construct_pod<T>(name, m);
|
||||||
opers_arithmetic<T>(m);
|
|
||||||
opers_arithmetic_modify_pod<T>(m);
|
m->add(fun(&detail::assign_sum_pod<T>), "+=");
|
||||||
|
m->add(fun(&detail::assign_difference_pod<T>), "-=");
|
||||||
|
m->add(fun(&detail::assign_product_pod<T>), "*=");
|
||||||
|
m->add(fun(&detail::assign_quotient_pod<T>), "/=");
|
||||||
|
|
||||||
m->add(fun(&to_string<T>), "to_string");
|
m->add(fun(&to_string<T>), "to_string");
|
||||||
m->add(fun(&parse_string<T>), "to_" + name);
|
m->add(fun(&parse_string<T>), "to_" + name);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all common functions for a POD type. All operators, and
|
||||||
|
* common conversions
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr bootstrap_integer_type(const std::string &name, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
bootstrap_pod_type<T>(name, m);
|
||||||
|
|
||||||
|
m->add(fun(&detail::assign_bitwise_and_pod<T>), "&=");
|
||||||
|
m->add(fun(&detail::assign_xor_pod<T>), "^=");
|
||||||
|
m->add(fun(&detail::assign_bitwise_or_pod<T>), "|=");
|
||||||
|
m->add(fun(&detail::assign_left_shift_pod<T>), "<<=");
|
||||||
|
m->add(fun(&detail::assign_remainder_pod<T>), "%=");
|
||||||
|
m->add(fun(&detail::assign_right_shift_pod<T>), ">>=");
|
||||||
|
|
||||||
|
opers_integer_arithmetic<T>(m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all common functions for a POD type. All operators, and
|
||||||
|
* common conversions
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr bootstrap_float_type(const std::string &name, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
bootstrap_pod_type<T>(name, m);
|
||||||
|
opers_float_arithmetic<T>(m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "clone" function for a shared_ptr type. This is used in the case
|
* "clone" function for a shared_ptr type. This is used in the case
|
||||||
* where you do not want to make a deep copy of an object during cloning
|
* where you do not want to make a deep copy of an object during cloning
|
||||||
@@ -558,7 +385,7 @@ namespace chaiscript
|
|||||||
template<typename Type>
|
template<typename Type>
|
||||||
Boxed_Value ptr_assign(Boxed_Value lhs, const boost::shared_ptr<typename boost::add_const<Type>::type> &rhs)
|
Boxed_Value ptr_assign(Boxed_Value lhs, const boost::shared_ptr<typename boost::add_const<Type>::type> &rhs)
|
||||||
{
|
{
|
||||||
if (lhs.is_unknown()
|
if (lhs.is_undef()
|
||||||
|| (!lhs.get_type_info().is_const() && lhs.get_type_info().bare_equal(chaiscript::detail::Get_Type_Info<Type>::get())))
|
|| (!lhs.get_type_info().is_const() && lhs.get_type_info().bare_equal(chaiscript::detail::Get_Type_Info<Type>::get())))
|
||||||
{
|
{
|
||||||
lhs.assign(Boxed_Value(rhs));
|
lhs.assign(Boxed_Value(rhs));
|
||||||
@@ -580,7 +407,7 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs)
|
static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs)
|
||||||
{
|
{
|
||||||
if (lhs.is_unknown())
|
if (lhs.is_undef())
|
||||||
{
|
{
|
||||||
return (lhs.assign(rhs));
|
return (lhs.assign(rhs));
|
||||||
} else {
|
} else {
|
||||||
@@ -598,28 +425,21 @@ namespace chaiscript
|
|||||||
std::cout << s << std::endl;
|
std::cout << s << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add all comparison operators for POD types
|
|
||||||
*/
|
|
||||||
static void opers_comparison_pod(ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(&detail::equals<Boxed_POD_Value, Boxed_POD_Value>), "==");
|
|
||||||
m->add(fun(&detail::not_equals<Boxed_POD_Value, Boxed_POD_Value>), "!=");
|
|
||||||
m->add(fun(&detail::less_than<Boxed_POD_Value, Boxed_POD_Value>), "<");
|
|
||||||
m->add(fun(&detail::greater_than<Boxed_POD_Value, Boxed_POD_Value>), ">");
|
|
||||||
m->add(fun(&detail::less_than_equals<Boxed_POD_Value, Boxed_POD_Value>), "<=");
|
|
||||||
m->add(fun(&detail::greater_than_equals<Boxed_POD_Value, Boxed_POD_Value>), ">=");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add all arithmetic operators for PODs
|
* Add all arithmetic operators for PODs
|
||||||
*/
|
*/
|
||||||
static void opers_arithmetic_pod(ModulePtr m = ModulePtr(new Module()))
|
static void opers_arithmetic_pod(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&detail::add<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "+");
|
m->add(fun(&operators::addition<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "+");
|
||||||
m->add(fun(&detail::subtract<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "-");
|
m->add(fun(&operators::subtraction<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "-");
|
||||||
m->add(fun(&detail::divide<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "/");
|
m->add(fun(&operators::bitwise_and<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "&");
|
||||||
m->add(fun(&detail::multiply<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "*");
|
m->add(fun(&operators::bitwise_xor<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "^");
|
||||||
|
m->add(fun(&operators::bitwise_or<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "|");
|
||||||
|
m->add(fun(&operators::division<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "/");
|
||||||
|
m->add(fun(&operators::left_shift<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "<<");
|
||||||
|
m->add(fun(&operators::multiplication<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "*");
|
||||||
|
m->add(fun(&operators::remainder<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), "%");
|
||||||
|
m->add(fun(&operators::right_shift<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>), ">>");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -708,10 +528,31 @@ namespace chaiscript
|
|||||||
m->add(fun(&Dynamic_Object::get_attr), "get_attr");
|
m->add(fun(&Dynamic_Object::get_attr), "get_attr");
|
||||||
m->eval("def Dynamic_Object::clone() { var new_o := Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }");
|
m->eval("def Dynamic_Object::clone() { var new_o := Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }");
|
||||||
|
|
||||||
|
m->add(fun(&Boxed_Value::is_undef), "is_var_undef");
|
||||||
|
m->add(fun(&Boxed_Value::is_null), "is_var_null");
|
||||||
|
m->add(fun(&Boxed_Value::is_const), "is_var_const");
|
||||||
|
m->add(fun(&Boxed_Value::is_ref), "is_var_reference");
|
||||||
|
m->add(fun(&Boxed_Value::is_pointer), "is_var_pointer");
|
||||||
|
m->add(fun(&Boxed_Value::is_type), "is_type");
|
||||||
|
|
||||||
|
m->add(fun(&Boxed_Value::get_type_info), "get_type_info");
|
||||||
|
m->add(user_type<Type_Info>(), "Type_Info");
|
||||||
|
|
||||||
|
|
||||||
|
operators::equal<Type_Info>(m);
|
||||||
|
|
||||||
|
m->add(fun(&Type_Info::is_const), "is_type_const");
|
||||||
|
m->add(fun(&Type_Info::is_reference), "is_type_reference");
|
||||||
|
m->add(fun(&Type_Info::is_void), "is_type_void");
|
||||||
|
m->add(fun(&Type_Info::is_undef), "is_type_undef");
|
||||||
|
m->add(fun(&Type_Info::is_pointer), "is_type_pointer");
|
||||||
|
m->add(fun(&Type_Info::name), "cpp_name");
|
||||||
|
m->add(fun(&Type_Info::bare_name), "cpp_bare_name");
|
||||||
|
m->add(fun(&Type_Info::bare_equal), "bare_equal");
|
||||||
|
|
||||||
|
|
||||||
basic_constructors<bool>("bool", m);
|
basic_constructors<bool>("bool", m);
|
||||||
oper_assign<std::string>(m);
|
operators::assign<bool>(m);
|
||||||
oper_assign<bool>(m);
|
|
||||||
|
|
||||||
m->add(fun(&to_string<const std::string &>), "internal_to_string");
|
m->add(fun(&to_string<const std::string &>), "internal_to_string");
|
||||||
m->add(fun(&Bootstrap::bool_to_string), "internal_to_string");
|
m->add(fun(&Bootstrap::bool_to_string), "internal_to_string");
|
||||||
@@ -719,18 +560,17 @@ namespace chaiscript
|
|||||||
m->add(fun(&throw_exception), "throw");
|
m->add(fun(&throw_exception), "throw");
|
||||||
m->add(fun(&what), "what");
|
m->add(fun(&what), "what");
|
||||||
|
|
||||||
bootstrap_pod_type<double>("double", m);
|
bootstrap_float_type<double>("double", m);
|
||||||
bootstrap_pod_type<int>("int", m);
|
bootstrap_integer_type<int>("int", m);
|
||||||
bootstrap_pod_type<size_t>("size_t", m);
|
bootstrap_integer_type<size_t>("size_t", m);
|
||||||
bootstrap_pod_type<char>("char", m);
|
bootstrap_integer_type<char>("char", m);
|
||||||
bootstrap_pod_type<boost::int64_t>("int64_t", m);
|
bootstrap_integer_type<boost::int64_t>("int64_t", m);
|
||||||
|
|
||||||
opers_comparison_pod(m);
|
operators::logical_compliment<bool>(m);
|
||||||
|
|
||||||
|
opers_comparison<Boxed_POD_Value>(m);
|
||||||
opers_arithmetic_pod(m);
|
opers_arithmetic_pod(m);
|
||||||
|
|
||||||
m->add(fun(&detail::modulus<int, int, int>), "%");
|
|
||||||
m->add(fun(&detail::shift_left<int, int, int>), "<<");
|
|
||||||
m->add(fun(&detail::shift_right<int, int, int>), ">>");
|
|
||||||
|
|
||||||
m->add(fun(&print), "print_string");
|
m->add(fun(&print), "print_string");
|
||||||
m->add(fun(&println), "println_string");
|
m->add(fun(&println), "println_string");
|
||||||
|
@@ -122,24 +122,13 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add reversible_container concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/ReversibleContainer.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr reversible_container_type(const std::string &, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add random_access_container concept to the given ContainerType
|
* Add random_access_container concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
* http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
||||||
*/
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr random_access_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
reversible_container_type<ContainerType>(type, m);
|
|
||||||
typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t);
|
typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t);
|
||||||
|
|
||||||
//In the interest of runtime safety for the m, we prefer the at() method for [] access,
|
//In the interest of runtime safety for the m, we prefer the at() method for [] access,
|
||||||
@@ -158,7 +147,7 @@ namespace chaiscript
|
|||||||
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
basic_constructors<ContainerType>(type, m);
|
basic_constructors<ContainerType>(type, m);
|
||||||
oper_assign<ContainerType>(m);
|
operators::assign<ContainerType>(m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,30 +156,15 @@ namespace chaiscript
|
|||||||
* http://www.sgi.com/tech/stl/Container.html
|
* http://www.sgi.com/tech/stl/Container.html
|
||||||
*/
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
assignable_type<ContainerType>(type, m);
|
m->add(fun(boost::function<int (const ContainerType *)>(&ContainerType::size)), "size");
|
||||||
|
|
||||||
m->add(fun<size_t (ContainerType::*)() const>(&ContainerType::size), "size");
|
|
||||||
m->add(fun<bool (ContainerType::*)() const>(&ContainerType::empty), "empty");
|
m->add(fun<bool (ContainerType::*)() const>(&ContainerType::empty), "empty");
|
||||||
m->add(fun<void (ContainerType::*)()>(&ContainerType::clear), "clear");
|
m->add(fun<void (ContainerType::*)()>(&ContainerType::clear), "clear");
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add forward container concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/ForwardContainer.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr forward_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
input_range_type<ContainerType>(type, m);
|
|
||||||
container_type<ContainerType>(type, m);
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add default constructable concept to the given Type
|
* Add default constructable concept to the given Type
|
||||||
* http://www.sgi.com/tech/stl/DefaultConstructible.html
|
* http://www.sgi.com/tech/stl/DefaultConstructible.html
|
||||||
@@ -243,11 +217,8 @@ namespace chaiscript
|
|||||||
* http://www.sgi.com/tech/stl/Sequence.html
|
* http://www.sgi.com/tech/stl/Sequence.html
|
||||||
*/
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
forward_container_type<ContainerType>(type, m);
|
|
||||||
default_constructible_type<ContainerType>(type, m);
|
|
||||||
|
|
||||||
std::string insert_name;
|
std::string insert_name;
|
||||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value))
|
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value))
|
||||||
{
|
{
|
||||||
@@ -267,11 +238,8 @@ namespace chaiscript
|
|||||||
* http://www.sgi.com/tech/stl/BackInsertionSequence.html
|
* http://www.sgi.com/tech/stl/BackInsertionSequence.html
|
||||||
*/
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr back_insertion_sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr back_insertion_sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
sequence_type<ContainerType>(type, m);
|
|
||||||
|
|
||||||
|
|
||||||
typedef typename ContainerType::reference (ContainerType::*backptr)();
|
typedef typename ContainerType::reference (ContainerType::*backptr)();
|
||||||
|
|
||||||
m->add(fun(static_cast<backptr>(&ContainerType::back)), "back");
|
m->add(fun(static_cast<backptr>(&ContainerType::back)), "back");
|
||||||
@@ -297,8 +265,6 @@ namespace chaiscript
|
|||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr front_insertion_sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr front_insertion_sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
sequence_type<ContainerType>(type, m);
|
|
||||||
|
|
||||||
typedef typename ContainerType::reference (ContainerType::*frontptr)();
|
typedef typename ContainerType::reference (ContainerType::*frontptr)();
|
||||||
|
|
||||||
m->add(fun(static_cast<frontptr>(&ContainerType::front)), "front");
|
m->add(fun(static_cast<frontptr>(&ContainerType::front)), "front");
|
||||||
@@ -315,44 +281,6 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* hopefully working List type
|
|
||||||
* http://www.sgi.com/tech/stl/List.html
|
|
||||||
*/
|
|
||||||
template<typename ListType>
|
|
||||||
ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(user_type<ListType>(), type);
|
|
||||||
front_insertion_sequence_type<ListType>(type, m);
|
|
||||||
back_insertion_sequence_type<ListType>(type, m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a vector type with associated concepts
|
|
||||||
* http://www.sgi.com/tech/stl/Vector.html
|
|
||||||
*/
|
|
||||||
template<typename VectorType>
|
|
||||||
ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(user_type<VectorType>(), type);
|
|
||||||
random_access_container_type<VectorType>(type, m);
|
|
||||||
back_insertion_sequence_type<VectorType>(type, m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a vector type with associated concepts
|
|
||||||
* http://www.sgi.com/tech/stl/Vector.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
forward_container_type<ContainerType>(type, m);
|
|
||||||
default_constructible_type<ContainerType>(type, m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bootstrap a given PairType
|
* bootstrap a given PairType
|
||||||
* http://www.sgi.com/tech/stl/pair.html
|
* http://www.sgi.com/tech/stl/pair.html
|
||||||
@@ -379,7 +307,6 @@ namespace chaiscript
|
|||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
associative_container_type<ContainerType>(type, m);
|
|
||||||
pair_type<typename ContainerType::value_type>(type + "_Pair", m);
|
pair_type<typename ContainerType::value_type>(type + "_Pair", m);
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
@@ -390,39 +317,10 @@ namespace chaiscript
|
|||||||
* http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
* http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
||||||
*/
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr unique_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
associative_container_type<ContainerType>(type, m);
|
// m->add(fun<size_t (ContainerType::*)(const typename ContainerType::key_type &) const>(&ContainerType::count), "count");
|
||||||
m->add(fun<size_t (ContainerType::*)(const typename ContainerType::key_type &) const>(&ContainerType::count), "count");
|
m->add(fun(boost::function<int (const ContainerType *, const typename ContainerType::key_type &)>(&ContainerType::count)), "count");
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add sorted associative container concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/SortedAssociativeContainer.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr sorted_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
typedef std::pair<typename ContainerType::iterator, typename ContainerType::iterator>
|
|
||||||
(ContainerType::*eq_range)(const typename ContainerType::key_type &);
|
|
||||||
|
|
||||||
reversible_container_type<ContainerType>(type, m);
|
|
||||||
associative_container_type<ContainerType>(type, m);
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add unique sorted associative container concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/UniqueSortedAssociativeContainer.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr unique_sorted_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
sorted_associative_container_type<ContainerType>(type, m);
|
|
||||||
unique_associative_container_type<ContainerType>(type, m);
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@@ -436,12 +334,57 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
m->add(user_type<MapType>(), type);
|
m->add(user_type<MapType>(), type);
|
||||||
m->add(fun(&MapType::operator[]), "[]");
|
m->add(fun(&MapType::operator[]), "[]");
|
||||||
unique_sorted_associative_container_type<MapType>(type, m);
|
|
||||||
|
container_type<MapType>(type, m);
|
||||||
|
assignable_type<MapType>(type, m);
|
||||||
|
unique_associative_container_type<MapType>(type, m);
|
||||||
pair_associative_container_type<MapType>(type, m);
|
pair_associative_container_type<MapType>(type, m);
|
||||||
|
input_range_type<MapType>(type, m);
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hopefully working List type
|
||||||
|
* http://www.sgi.com/tech/stl/List.html
|
||||||
|
*/
|
||||||
|
template<typename ListType>
|
||||||
|
ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(user_type<ListType>(), type);
|
||||||
|
|
||||||
|
front_insertion_sequence_type<ListType>(type, m);
|
||||||
|
back_insertion_sequence_type<ListType>(type, m);
|
||||||
|
sequence_type<ListType>(type, m);
|
||||||
|
container_type<ListType>(type, m);
|
||||||
|
default_constructible_type<ListType>(type, m);
|
||||||
|
assignable_type<ListType>(type, m);
|
||||||
|
input_range_type<ListType>(type, m);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a vector type with associated concepts
|
||||||
|
* http://www.sgi.com/tech/stl/Vector.html
|
||||||
|
*/
|
||||||
|
template<typename VectorType>
|
||||||
|
ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(user_type<VectorType>(), type);
|
||||||
|
|
||||||
|
back_insertion_sequence_type<VectorType>(type, m);
|
||||||
|
sequence_type<VectorType>(type, m);
|
||||||
|
random_access_container_type<VectorType>(type, m);
|
||||||
|
container_type<VectorType>(type, m);
|
||||||
|
default_constructible_type<VectorType>(type, m);
|
||||||
|
assignable_type<VectorType>(type, m);
|
||||||
|
input_range_type<VectorType>(type, m);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a String container
|
* Add a String container
|
||||||
* http://www.sgi.com/tech/stl/basic_string.html
|
* http://www.sgi.com/tech/stl/basic_string.html
|
||||||
@@ -450,11 +393,15 @@ namespace chaiscript
|
|||||||
ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(user_type<String>(), type);
|
m->add(user_type<String>(), type);
|
||||||
oper_add<String>(m);
|
operators::addition<String>(m);
|
||||||
oper_add_equals<String>(m);
|
operators::assign_sum<String>(m);
|
||||||
opers_comparison<String>(m);
|
opers_comparison<String>(m);
|
||||||
random_access_container_type<String>(type, m);
|
random_access_container_type<String>(type, m);
|
||||||
sequence_type<String>(type, m);
|
sequence_type<String>(type, m);
|
||||||
|
default_constructible_type<String>(type, m);
|
||||||
|
container_type<String>(type, m);
|
||||||
|
assignable_type<String>(type, m);
|
||||||
|
input_range_type<String>(type, m);
|
||||||
|
|
||||||
//Special case: add push_back to string (which doesn't support other back_insertion operations
|
//Special case: add push_back to string (which doesn't support other back_insertion operations
|
||||||
std::string push_back_name;
|
std::string push_back_name;
|
||||||
@@ -466,13 +413,16 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
m->add(fun(&String::push_back), push_back_name);
|
m->add(fun(&String::push_back), push_back_name);
|
||||||
|
|
||||||
typedef typename String::size_type (String::*find_func)(const String &, typename String::size_type) const;
|
typedef typename String::size_type (String::*find_func_ptr)(const String &, typename String::size_type) const;
|
||||||
m->add(fun(static_cast<find_func>(&String::find)), "find");
|
|
||||||
m->add(fun(static_cast<find_func>(&String::rfind)), "rfind");
|
typedef boost::function<int (const String *, const String &, int)> find_func;
|
||||||
m->add(fun(static_cast<find_func>(&String::find_first_of)), "find_first_of");
|
|
||||||
m->add(fun(static_cast<find_func>(&String::find_last_of)), "find_last_of");
|
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find))), "find");
|
||||||
m->add(fun(static_cast<find_func>(&String::find_first_not_of)), "find_first_not_of");
|
m->add(fun(find_func(static_cast<find_func_ptr>(&String::rfind))), "rfind");
|
||||||
m->add(fun(static_cast<find_func>(&String::find_last_not_of)), "find_last_not_of");
|
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_first_of))), "find_first_of");
|
||||||
|
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_last_of))), "find_last_of");
|
||||||
|
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_first_not_of))), "find_first_not_of");
|
||||||
|
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_last_not_of))), "find_last_not_of");
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@@ -42,49 +42,27 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* used to provide type-erased access to the internal boost::shared_ptr
|
|
||||||
* reference count information
|
|
||||||
*/
|
|
||||||
struct Shared_Ptr_Proxy
|
|
||||||
{
|
|
||||||
virtual ~Shared_Ptr_Proxy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool unique(boost::any *) = 0;
|
|
||||||
virtual long use_count(boost::any *) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Typed implementation of the Shared_Ptr_Proxy
|
|
||||||
*/
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Shared_Ptr_Proxy_Impl : Shared_Ptr_Proxy
|
static bool unique(boost::any *a)
|
||||||
{
|
|
||||||
virtual ~Shared_Ptr_Proxy_Impl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool unique(boost::any *a)
|
|
||||||
{
|
{
|
||||||
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(a);
|
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(a);
|
||||||
return ptr->unique();
|
return ptr->unique();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual long use_count(boost::any *a)
|
template<typename T>
|
||||||
|
static bool is_null(boost::any *a)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(a);
|
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(a);
|
||||||
return ptr->use_count();
|
return ptr->get() == 0;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Data(const Type_Info &ti,
|
Data(const Type_Info &ti,
|
||||||
const boost::any &to,
|
const boost::any &to,
|
||||||
bool tr,
|
bool tr,
|
||||||
const boost::shared_ptr<Shared_Ptr_Proxy> &t_proxy = boost::shared_ptr<Shared_Ptr_Proxy>())
|
const boost::function<bool (boost::any*)> &t_unique = boost::function<bool (boost::any*)>(),
|
||||||
|
const boost::function<bool (boost::any*)> &t_is_null = boost::function<bool (boost::any*)>())
|
||||||
: m_type_info(ti), m_obj(to),
|
: m_type_info(ti), m_obj(to),
|
||||||
m_is_ref(tr), m_ptr_proxy(t_proxy)
|
m_is_ref(tr), m_unique(t_unique), m_is_null(t_is_null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +71,8 @@ namespace chaiscript
|
|||||||
m_type_info = rhs.m_type_info;
|
m_type_info = rhs.m_type_info;
|
||||||
m_obj = rhs.m_obj;
|
m_obj = rhs.m_obj;
|
||||||
m_is_ref = rhs.m_is_ref;
|
m_is_ref = rhs.m_is_ref;
|
||||||
m_ptr_proxy = rhs.m_ptr_proxy;
|
m_unique = rhs.m_unique;
|
||||||
|
m_is_null = rhs.m_is_null;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -101,7 +80,8 @@ namespace chaiscript
|
|||||||
Type_Info m_type_info;
|
Type_Info m_type_info;
|
||||||
boost::any m_obj;
|
boost::any m_obj;
|
||||||
bool m_is_ref;
|
bool m_is_ref;
|
||||||
boost::shared_ptr<Shared_Ptr_Proxy> m_ptr_proxy;
|
boost::function<bool (boost::any*)> m_unique;
|
||||||
|
boost::function<bool (boost::any*)> m_is_null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +121,8 @@ namespace chaiscript
|
|||||||
detail::Get_Type_Info<T>::get(),
|
detail::Get_Type_Info<T>::get(),
|
||||||
boost::any(obj),
|
boost::any(obj),
|
||||||
false,
|
false,
|
||||||
boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>()))
|
&Data::unique<T>,
|
||||||
|
&Data::is_null<T>)
|
||||||
);
|
);
|
||||||
|
|
||||||
std::map<std::pair<const void *, bool>, Data>::iterator itr
|
std::map<std::pair<const void *, bool>, Data>::iterator itr
|
||||||
@@ -200,7 +181,8 @@ namespace chaiscript
|
|||||||
detail::Get_Type_Info<T>::get(),
|
detail::Get_Type_Info<T>::get(),
|
||||||
boost::any(boost::shared_ptr<T>(new T(t))),
|
boost::any(boost::shared_ptr<T>(new T(t))),
|
||||||
false,
|
false,
|
||||||
boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>()))
|
&Data::unique<T>,
|
||||||
|
&Data::is_null<T>)
|
||||||
);
|
);
|
||||||
|
|
||||||
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(&data->m_obj);
|
boost::shared_ptr<T> *ptr = boost::any_cast<boost::shared_ptr<T> >(&data->m_obj);
|
||||||
@@ -226,7 +208,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
|
|
||||||
++m_cullcount;
|
++m_cullcount;
|
||||||
if (force || m_cullcount % 10 != 0)
|
if (force || m_cullcount % 20 != 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -236,7 +218,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
while (itr != m_ptrs.end())
|
while (itr != m_ptrs.end())
|
||||||
{
|
{
|
||||||
if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1)
|
if (itr->second.m_unique(&itr->second.m_obj))
|
||||||
{
|
{
|
||||||
std::map<std::pair<const void *, bool>, Data >::iterator todel = itr;
|
std::map<std::pair<const void *, bool>, Data >::iterator todel = itr;
|
||||||
++itr;
|
++itr;
|
||||||
@@ -247,7 +229,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::pair<const void *, bool>, Data > m_ptrs;
|
std::map<std::pair<const void *, bool>, Data> m_ptrs;
|
||||||
int m_cullcount;
|
int m_cullcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -282,6 +264,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void swap(Boxed_Value &rhs)
|
||||||
|
{
|
||||||
|
std::swap(m_data, rhs.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a reference to the static global Object_Cache
|
* Return a reference to the static global Object_Cache
|
||||||
*/
|
*/
|
||||||
@@ -311,7 +298,8 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
Boxed_Value &operator=(const Boxed_Value &rhs)
|
Boxed_Value &operator=(const Boxed_Value &rhs)
|
||||||
{
|
{
|
||||||
m_data = rhs.m_data;
|
Boxed_Value temp(rhs);
|
||||||
|
swap(temp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,9 +311,29 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* return true if the object is uninitialized
|
* return true if the object is uninitialized
|
||||||
*/
|
*/
|
||||||
bool is_unknown() const
|
bool is_undef() const
|
||||||
{
|
{
|
||||||
return m_data->m_type_info.is_unknown();
|
return m_data->m_type_info.is_undef();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_const() const
|
||||||
|
{
|
||||||
|
return m_data->m_type_info.is_const();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_type(const Type_Info &ti) const
|
||||||
|
{
|
||||||
|
return m_data->m_type_info.bare_equal(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const
|
||||||
|
{
|
||||||
|
if (m_data->m_is_null)
|
||||||
|
{
|
||||||
|
return m_data->m_is_null(&m_data->m_obj);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::any get() const
|
boost::any get() const
|
||||||
@@ -338,6 +346,12 @@ namespace chaiscript
|
|||||||
return m_data->m_is_ref;
|
return m_data->m_is_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_pointer() const
|
||||||
|
{
|
||||||
|
return !is_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<Data> m_data;
|
boost::shared_ptr<Data> m_data;
|
||||||
};
|
};
|
||||||
@@ -624,7 +638,7 @@ namespace chaiscript
|
|||||||
Boxed_POD_Value(const Boxed_Value &v)
|
Boxed_POD_Value(const Boxed_Value &v)
|
||||||
: d(0), i(0), m_isfloat(false)
|
: d(0), i(0), m_isfloat(false)
|
||||||
{
|
{
|
||||||
if (v.get_type_info().is_unknown())
|
if (v.get_type_info().is_undef())
|
||||||
{
|
{
|
||||||
throw boost::bad_any_cast();
|
throw boost::bad_any_cast();
|
||||||
}
|
}
|
||||||
@@ -703,42 +717,117 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
if (!m_isfloat && !r.m_isfloat)
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
{
|
{
|
||||||
return Boxed_Value(i + r.i);
|
return smart_size(i + r.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i));
|
return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i));
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Value operator*(const Boxed_POD_Value &r) const
|
|
||||||
{
|
|
||||||
if (!m_isfloat && !r.m_isfloat)
|
|
||||||
{
|
|
||||||
return Boxed_Value(i * r.i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i));
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Value operator/(const Boxed_POD_Value &r) const
|
|
||||||
{
|
|
||||||
if (!m_isfloat && !r.m_isfloat)
|
|
||||||
{
|
|
||||||
return Boxed_Value(i / r.i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i));
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Value operator-(const Boxed_POD_Value &r) const
|
Boxed_Value operator-(const Boxed_POD_Value &r) const
|
||||||
{
|
{
|
||||||
if (!m_isfloat && !r.m_isfloat)
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
{
|
{
|
||||||
return Boxed_Value(i - r.i);
|
return smart_size(i - r.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i));
|
return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Boxed_Value operator&(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return Boxed_Value(i & r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("& only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value operator^(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return Boxed_Value(i ^ r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("^ only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value operator|(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return Boxed_Value(i | r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("| only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value operator/(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return smart_size(i / r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i));
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value operator<<(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return smart_size(i << r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("<< only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Boxed_Value operator*(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return smart_size(i * r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Boxed_Value operator%(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return smart_size(i % r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast("% only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value operator>>(const Boxed_POD_Value &r) const
|
||||||
|
{
|
||||||
|
if (!m_isfloat && !r.m_isfloat)
|
||||||
|
{
|
||||||
|
return smart_size(i >> r.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw bad_boxed_cast(">> only valid for integer types");
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value smart_size(boost::int64_t i) const
|
||||||
|
{
|
||||||
|
if (i < std::numeric_limits<int>::min()
|
||||||
|
|| i > std::numeric_limits<int>::max())
|
||||||
|
{
|
||||||
|
return Boxed_Value(i);
|
||||||
|
} else {
|
||||||
|
return Boxed_Value(static_cast<int>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double d;
|
double d;
|
||||||
boost::int64_t i;
|
boost::int64_t i;
|
||||||
|
|
||||||
@@ -755,6 +844,20 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef Boxed_POD_Value Result_Type;
|
typedef Boxed_POD_Value Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
return Boxed_POD_Value(ob);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for converting from Boxed_Value to Boxed_POD_Value
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Cast_Helper<const Boxed_POD_Value &>
|
||||||
|
{
|
||||||
|
typedef Boxed_POD_Value Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
{
|
{
|
||||||
return Boxed_POD_Value(ob);
|
return Boxed_POD_Value(ob);
|
||||||
@@ -799,7 +902,14 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
return l.get_type_info() == r.get_type_info();
|
return l.get_type_info() == r.get_type_info();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<> void swap(chaiscript::Boxed_Value &lhs, chaiscript::Boxed_Value &rhs)
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -43,6 +43,7 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Add a bit of chaiscript to eval during module implementation
|
//Add a bit of chaiscript to eval during module implementation
|
||||||
Module &eval(const std::string &str)
|
Module &eval(const std::string &str)
|
||||||
{
|
{
|
||||||
@@ -50,6 +51,11 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Module &add(const boost::shared_ptr<Module> &m)
|
||||||
|
{
|
||||||
|
m->apply(*this, *this);
|
||||||
|
return *m;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Eval, typename Engine>
|
template<typename Eval, typename Engine>
|
||||||
void apply(Eval &t_eval, Engine &t_engine) const
|
void apply(Eval &t_eval, Engine &t_engine) const
|
||||||
@@ -166,6 +172,19 @@ namespace chaiscript
|
|||||||
virtual ~reserved_word_error() throw() {}
|
virtual ~reserved_word_error() throw() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown in the case that a non-const object was added as a shared object
|
||||||
|
*/
|
||||||
|
struct global_non_const : std::runtime_error
|
||||||
|
{
|
||||||
|
global_non_const() throw()
|
||||||
|
: std::runtime_error("a global object must be const")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~global_non_const() throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class for the dispatchkit. Handles management
|
* Main class for the dispatchkit. Handles management
|
||||||
@@ -179,6 +198,14 @@ namespace chaiscript
|
|||||||
typedef boost::tuples::tuple<std::map<std::string, Boxed_Value>, std::deque<Scope>, bool> StackData;
|
typedef boost::tuples::tuple<std::map<std::string, Boxed_Value>, std::deque<Scope>, bool> StackData;
|
||||||
typedef boost::shared_ptr<StackData> Stack;
|
typedef boost::shared_ptr<StackData> Stack;
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
std::multimap<std::string, Proxy_Function> m_functions;
|
||||||
|
std::map<std::string, Boxed_Value> m_global_objects;
|
||||||
|
Type_Name_Map m_types;
|
||||||
|
std::set<std::string> m_reserved_words;
|
||||||
|
};
|
||||||
|
|
||||||
Dispatch_Engine()
|
Dispatch_Engine()
|
||||||
: m_place_holder(boost::shared_ptr<Placeholder_Object>(new Placeholder_Object()))
|
: m_place_holder(boost::shared_ptr<Placeholder_Object>(new Placeholder_Object()))
|
||||||
{
|
{
|
||||||
@@ -238,19 +265,24 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new shared object, between all the threads
|
* Adds a new global shared object, between all the threads
|
||||||
*/
|
*/
|
||||||
void add_shared_object(const Boxed_Value &obj, const std::string &name)
|
void add_global_const(const Boxed_Value &obj, const std::string &name)
|
||||||
{
|
{
|
||||||
StackData &stack = get_stack_data();
|
StackData &stack = get_stack_data();
|
||||||
validate_object_name(name);
|
validate_object_name(name);
|
||||||
|
if (!obj.is_const())
|
||||||
|
{
|
||||||
|
throw global_non_const();
|
||||||
|
}
|
||||||
|
|
||||||
stack.get<0>().erase(name);
|
stack.get<0>().erase(name);
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::unique_lock<boost::shared_mutex> l(m_shared_object_mutex);
|
boost::unique_lock<boost::shared_mutex> l(m_global_object_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_shared_objects[name] = obj;
|
m_state.m_global_objects[name] = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -316,7 +348,7 @@ namespace chaiscript
|
|||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
get_function_cache() = m_functions;
|
get_function_cache() = m_state.m_functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -353,15 +385,14 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we in the 0th stack and should check the shared objects?
|
// Is the value we are looking for a global?
|
||||||
if (stack.get<2>())
|
|
||||||
{
|
{
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::shared_lock<boost::shared_mutex> l(m_shared_object_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_global_object_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
itr = m_shared_objects.find(name);
|
itr = m_state.m_global_objects.find(name);
|
||||||
if (itr != m_shared_objects.end())
|
if (itr != m_state.m_global_objects.end())
|
||||||
{
|
{
|
||||||
cache[name] = itr->second;
|
cache[name] = itr->second;
|
||||||
return itr->second;
|
return itr->second;
|
||||||
@@ -386,11 +417,13 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void add(const Type_Info &ti, const std::string &name)
|
void add(const Type_Info &ti, const std::string &name)
|
||||||
{
|
{
|
||||||
|
add_global_const(const_var(ti), name + "_type");
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_types.insert(std::make_pair(name, ti));
|
m_state.m_types.insert(std::make_pair(name, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -402,9 +435,9 @@ namespace chaiscript
|
|||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Type_Name_Map::const_iterator itr = m_types.find(name);
|
Type_Name_Map::const_iterator itr = m_state.m_types.find(name);
|
||||||
|
|
||||||
if (itr != m_types.end())
|
if (itr != m_state.m_types.end())
|
||||||
{
|
{
|
||||||
return itr->second;
|
return itr->second;
|
||||||
}
|
}
|
||||||
@@ -423,8 +456,8 @@ namespace chaiscript
|
|||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (Type_Name_Map::const_iterator itr = m_types.begin();
|
for (Type_Name_Map::const_iterator itr = m_state.m_types.begin();
|
||||||
itr != m_types.end();
|
itr != m_state.m_types.end();
|
||||||
++itr)
|
++itr)
|
||||||
{
|
{
|
||||||
if (itr->second.bare_equal(ti))
|
if (itr->second.bare_equal(ti))
|
||||||
@@ -445,7 +478,7 @@ namespace chaiscript
|
|||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return std::vector<std::pair<std::string, Type_Info> >(m_types.begin(), m_types.end());
|
return std::vector<std::pair<std::string, Type_Info> >(m_state.m_types.begin(), m_state.m_types.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -484,7 +517,7 @@ namespace chaiscript
|
|||||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_reserved_words.insert(name);
|
m_state.m_reserved_words.insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Value call_function(const std::string &t_name, const std::vector<Boxed_Value> ¶ms) const
|
Boxed_Value call_function(const std::string &t_name, const std::vector<Boxed_Value> ¶ms) const
|
||||||
@@ -493,7 +526,27 @@ namespace chaiscript
|
|||||||
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
||||||
= functions.equal_range(t_name);
|
= functions.equal_range(t_name);
|
||||||
|
|
||||||
return dispatch(range.first, range.second, params);
|
return dispatch(range.first, range.second, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value call_function(const std::string &t_name) const
|
||||||
|
{
|
||||||
|
return call_function(t_name, std::vector<Boxed_Value>());
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1) const
|
||||||
|
{
|
||||||
|
std::vector<Boxed_Value> params;
|
||||||
|
params.push_back(p1);
|
||||||
|
return call_function(t_name, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1, const Boxed_Value &p2) const
|
||||||
|
{
|
||||||
|
std::vector<Boxed_Value> params;
|
||||||
|
params.push_back(p1);
|
||||||
|
params.push_back(p2);
|
||||||
|
return call_function(t_name, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -599,6 +652,26 @@ namespace chaiscript
|
|||||||
return get_type_name(obj.get_type_info());
|
return get_type_name(obj.get_type_info());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
State get_state()
|
||||||
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
|
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
boost::unique_lock<boost::shared_mutex> l2(m_global_object_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_state(const State &t_state)
|
||||||
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
|
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
boost::unique_lock<boost::shared_mutex> l2(m_global_object_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_state = t_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@@ -625,7 +698,7 @@ namespace chaiscript
|
|||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_reserved_words.find(name) != m_reserved_words.end())
|
if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end())
|
||||||
{
|
{
|
||||||
throw reserved_word_error(name);
|
throw reserved_word_error(name);
|
||||||
}
|
}
|
||||||
@@ -643,7 +716,7 @@ namespace chaiscript
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
||||||
= m_functions.equal_range(t_name);
|
= m_state.m_functions.equal_range(t_name);
|
||||||
|
|
||||||
while (range.first != range.second)
|
while (range.first != range.second)
|
||||||
{
|
{
|
||||||
@@ -654,7 +727,7 @@ namespace chaiscript
|
|||||||
++range.first;
|
++range.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_functions.insert(std::make_pair(t_name, f));
|
m_state.m_functions.insert(std::make_pair(t_name, f));
|
||||||
get_function_cache().insert(std::make_pair(t_name, f));
|
get_function_cache().insert(std::make_pair(t_name, f));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -662,7 +735,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
mutable boost::shared_mutex m_mutex;
|
mutable boost::shared_mutex m_mutex;
|
||||||
mutable boost::shared_mutex m_shared_object_mutex;
|
mutable boost::shared_mutex m_global_object_mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Stack_Holder
|
struct Stack_Holder
|
||||||
@@ -681,13 +754,9 @@ namespace chaiscript
|
|||||||
chaiscript::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
chaiscript::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
||||||
|
|
||||||
|
|
||||||
std::multimap<std::string, Proxy_Function> m_functions;
|
State m_state;
|
||||||
std::map<std::string, Boxed_Value> m_shared_objects;
|
|
||||||
|
|
||||||
Type_Name_Map m_types;
|
|
||||||
Boxed_Value m_place_holder;
|
Boxed_Value m_place_holder;
|
||||||
|
|
||||||
std::set<std::string> m_reserved_words;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,16 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return<const Ret &>
|
||||||
|
{
|
||||||
|
static Boxed_Value handle(const Ret &r)
|
||||||
|
{
|
||||||
|
return Boxed_Value(boost::cref(r));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
*/
|
*/
|
||||||
@@ -57,6 +67,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
return Boxed_Value(boost::ref(r));
|
return Boxed_Value(boost::ref(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Boxed_Value handle(const Ret &r)
|
||||||
|
{
|
||||||
|
return Boxed_Value(boost::cref(r));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +98,19 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Handle_Return<const Boxed_Value &>
|
||||||
|
{
|
||||||
|
static Boxed_Value handle(const Boxed_Value &r)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
*/
|
*/
|
||||||
|
442
include/chaiscript/dispatchkit/operators.hpp
Normal file
442
include/chaiscript/dispatchkit/operators.hpp
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
#ifndef __CHAISCRIPT_OPERATORS_HPP__
|
||||||
|
#define __CHAISCRIPT_OPERATORS_HPP__
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
namespace operators
|
||||||
|
{
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign(L l, R r)
|
||||||
|
{
|
||||||
|
return (l = r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_bitwise_and(L l, R r)
|
||||||
|
{
|
||||||
|
return (l &= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_xor(L l, R r)
|
||||||
|
{
|
||||||
|
return (l ^= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_bitwise_or(L l, R r)
|
||||||
|
{
|
||||||
|
return (l |= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_difference(L l, R r)
|
||||||
|
{
|
||||||
|
return (l -= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_left_shift(L l, R r)
|
||||||
|
{
|
||||||
|
return (l <<= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_product(L l, R r)
|
||||||
|
{
|
||||||
|
return (l *= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_quotient(L l, R r)
|
||||||
|
{
|
||||||
|
return (l /= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_remainder(L l, R r)
|
||||||
|
{
|
||||||
|
return (l %= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_right_shift(L l, R r)
|
||||||
|
{
|
||||||
|
return (l >>= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret assign_sum(L l, R r)
|
||||||
|
{
|
||||||
|
return (l += r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L>
|
||||||
|
Ret prefix_decrement(L l)
|
||||||
|
{
|
||||||
|
return (--l);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L>
|
||||||
|
Ret prefix_increment(L l)
|
||||||
|
{
|
||||||
|
return (++l);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret equal(L l, R r)
|
||||||
|
{
|
||||||
|
return (l == r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret greater_than(L l, R r)
|
||||||
|
{
|
||||||
|
return (l > r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret greater_than_equal(L l, R r)
|
||||||
|
{
|
||||||
|
return (l >= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret less_than(L l, R r)
|
||||||
|
{
|
||||||
|
return (l < r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret less_than_equal(L l, R r)
|
||||||
|
{
|
||||||
|
return (l <= r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L>
|
||||||
|
Ret logical_compliment(L l)
|
||||||
|
{
|
||||||
|
return (!l);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret not_equal(L l, R r)
|
||||||
|
{
|
||||||
|
return (l != r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret addition(L l, R r)
|
||||||
|
{
|
||||||
|
return (l + r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L>
|
||||||
|
Ret unary_plus(L l)
|
||||||
|
{
|
||||||
|
return (+l);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret subtraction(L l, R r)
|
||||||
|
{
|
||||||
|
return (l - r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L>
|
||||||
|
Ret unary_minus(L l)
|
||||||
|
{
|
||||||
|
return (-l);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret bitwise_and(L l, R r)
|
||||||
|
{
|
||||||
|
return (l & r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L>
|
||||||
|
Ret bitwise_compliment(L l)
|
||||||
|
{
|
||||||
|
return (~l);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret bitwise_xor(L l, R r)
|
||||||
|
{
|
||||||
|
return (l ^ r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret bitwise_or(L l, R r)
|
||||||
|
{
|
||||||
|
return (l | r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret division(L l, R r)
|
||||||
|
{
|
||||||
|
return (l / r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret left_shift(L l, R r)
|
||||||
|
{
|
||||||
|
return l << r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret multiplication(L l, R r)
|
||||||
|
{
|
||||||
|
return l * r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret remainder(L l, R r)
|
||||||
|
{
|
||||||
|
return (l % r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename L, typename R>
|
||||||
|
Ret right_shift(L l, R r)
|
||||||
|
{
|
||||||
|
return (l >> r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign<T &, T &, const T&>), "=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_bitwise_and(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_bitwise_and<T &, T &, const T&>), "&=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_xor(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_xor<T &, T &, const T&>), "^=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_bitwise_or(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_bitwise_or<T &, T &, const T&>), "|=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_difference(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_difference<T &, T &, const T&>), "-=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_left_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_left_shift<T &, T &, const T&>), "<<=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_product(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_product<T &, T &, const T&>), "*=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_quotient(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_quotient<T &, T &, const T&>), "/=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_remainder(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_remainder<T &, T &, const T&>), "%=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_right_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_right_shift<T &, T &, const T&>), ">>=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr assign_sum(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&assign_sum<T &, T &, const T&>), "+=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr prefix_decrement(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&prefix_decrement<T &, T &>), "--");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr prefix_increment(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&prefix_increment<T &, T &>), "++");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&equal<bool, const T&, const T&>), "==");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr greater_than(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&greater_than<bool, const T&, const T&>), ">");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr greater_than_equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&greater_than_equal<bool, const T&, const T&>), ">=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr less_than(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&less_than<bool, const T&, const T&>), "<");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr less_than_equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&less_than_equal<bool, const T&, const T&>), "<=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr logical_compliment(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&logical_compliment<bool, const T &>), "!");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr not_equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(¬_equal<bool, const T &, const T &>), "!=");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr addition(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&addition<T, const T &, const T &>), "+");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr unary_plus(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&unary_plus<T, const T &>), "+");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr subtraction(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&subtraction<T, const T &, const T &>), "-");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr unary_minus(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&unary_minus<T, const T &>), "-");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr bitwise_and(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&bitwise_and<T, const T &, const T &>), "&");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr bitwise_compliment(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&bitwise_compliment<T, const T &>), "~");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr bitwise_xor(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&bitwise_xor<T, const T &, const T &>), "^");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr bitwise_or(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&bitwise_or<T, const T &, const T &>), "|");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr division(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&division<T, const T &, const T &>), "/");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr left_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&left_shift<T, const T &, const T &>), "<<");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr multiplication(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&multiplication<T, const T &, const T &>), "*");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr remainder(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&remainder<T, const T &, const T &>), "%");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ModulePtr right_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(fun(&right_shift<T, const T &, const T &>), ">>");
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -13,6 +13,7 @@
|
|||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/type_traits/add_reference.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "proxy_functions_detail.hpp"
|
#include "proxy_functions_detail.hpp"
|
||||||
@@ -92,7 +93,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
const Type_Info &ti = types[1];
|
const Type_Info &ti = types[1];
|
||||||
|
|
||||||
if (ti.is_unknown() || vals[0].get_type_info().is_unknown()
|
|
||||||
|
if (ti.is_undef() || vals[0].get_type_info().is_undef()
|
||||||
|| ti.bare_equal(user_type<Boxed_Value>())
|
|| ti.bare_equal(user_type<Boxed_Value>())
|
||||||
|| ti.bare_equal(user_type<Boxed_POD_Value>())
|
|| ti.bare_equal(user_type<Boxed_POD_Value>())
|
||||||
|| ti.bare_equal(vals[0].get_type_info()))
|
|| ti.bare_equal(vals[0].get_type_info()))
|
||||||
@@ -407,6 +409,81 @@ namespace chaiscript
|
|||||||
Func *m_dummy_func;
|
Func *m_dummy_func;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute getter Proxy_Function implementation
|
||||||
|
*/
|
||||||
|
template<typename T, typename Class>
|
||||||
|
class Attribute_Access : public Proxy_Function_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Attribute_Access(T Class::* t_attr)
|
||||||
|
: Proxy_Function_Base(param_types()),
|
||||||
|
m_attr(t_attr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Attribute_Access() {}
|
||||||
|
|
||||||
|
virtual bool operator==(const Proxy_Function_Base &t_func) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const Attribute_Access<T, Class> &aa
|
||||||
|
= dynamic_cast<const Attribute_Access<T, Class> &>(t_func);
|
||||||
|
return m_attr == aa.m_attr;
|
||||||
|
} catch (const std::bad_cast &) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||||
|
{
|
||||||
|
if (params.size() == 1)
|
||||||
|
{
|
||||||
|
const Boxed_Value &bv = params[0];
|
||||||
|
if (bv.is_const())
|
||||||
|
{
|
||||||
|
const Class *o = boxed_cast<const Class *>(bv);
|
||||||
|
return Handle_Return<const typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||||
|
} else {
|
||||||
|
Class *o = boxed_cast<Class *>(bv);
|
||||||
|
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw arity_error(params.size(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
|
{
|
||||||
|
if (vals.size() != 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vals[0].get_type_info().bare_equal(user_type<Class>());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string annotation() const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::vector<Type_Info> param_types()
|
||||||
|
{
|
||||||
|
std::vector<Type_Info> v;
|
||||||
|
v.push_back(user_type<T>());
|
||||||
|
v.push_back(user_type<Class>());
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
T Class::* m_attr;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown in the case that a multi method dispatch fails
|
* Exception thrown in the case that a multi method dispatch fails
|
||||||
* because no matching function was found
|
* because no matching function was found
|
||||||
@@ -420,6 +497,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch_error(bool is_const) throw()
|
||||||
|
: std::runtime_error(std::string("No matching function to dispatch to") + (is_const?", parameter is const":""))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~dispatch_error() throw() {}
|
virtual ~dispatch_error() throw() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -450,7 +532,7 @@ namespace chaiscript
|
|||||||
++begin;
|
++begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw dispatch_error();
|
throw dispatch_error(plist.empty()?false:plist[0].is_const());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -13,74 +13,61 @@
|
|||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/function_types/components.hpp>
|
#include <boost/function_types/components.hpp>
|
||||||
#include <boost/function_types/function_type.hpp>
|
#include <boost/function_types/function_type.hpp>
|
||||||
|
#include <boost/function_types/is_member_object_pointer.hpp>
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/**
|
template<bool Object>
|
||||||
* Helper function for register_member function
|
struct Fun_Helper
|
||||||
*/
|
|
||||||
template<typename T, typename Class>
|
|
||||||
T &get_member(T Class::* m, Class *obj)
|
|
||||||
{
|
{
|
||||||
return (obj->*m);
|
template<typename T>
|
||||||
}
|
static Proxy_Function go(T t)
|
||||||
|
{
|
||||||
|
return Proxy_Function(
|
||||||
|
new Proxy_Function_Impl<
|
||||||
|
typename boost::function_types::function_type<boost::function_types::components<T> >::type> (
|
||||||
|
boost::function<
|
||||||
|
typename boost::function_types::function_type<boost::function_types::components<T> >::type
|
||||||
|
>(t)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<>
|
||||||
boost::function<T> mk_boost_fun(const boost::function<T> &f)
|
struct Fun_Helper<true>
|
||||||
{
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
boost::function<
|
|
||||||
typename boost::function_types::function_type<boost::function_types::components<T> >::type
|
|
||||||
> mk_boost_fun(T t)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
boost::function<
|
|
||||||
typename boost::function_types::function_type<boost::function_types::components<T> >::type
|
|
||||||
>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename Class>
|
|
||||||
Proxy_Function fun_helper(T Class::* m)
|
|
||||||
{
|
{
|
||||||
return fun_helper(boost::function<T& (Class *)>(boost::bind(&detail::get_member<T, Class>, m, _1)));
|
template<typename T, typename Class>
|
||||||
}
|
static Proxy_Function go(T Class::* m)
|
||||||
|
{
|
||||||
|
return Proxy_Function(new Attribute_Access<T, Class>(m));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Proxy_Function fun_helper(const boost::function<T> &f)
|
|
||||||
{
|
|
||||||
return Proxy_Function(new Proxy_Function_Impl<T>(f));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function fun(const boost::function<T> &f)
|
Proxy_Function fun(const boost::function<T> &f)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(f);
|
return Proxy_Function(new Proxy_Function_Impl<T>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function fun(T t)
|
Proxy_Function fun(T t)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(detail::mk_boost_fun(t));
|
return detail::Fun_Helper<boost::function_types::is_member_object_pointer<T>::value>::go(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename Q>
|
template<typename T, typename Q>
|
||||||
Proxy_Function fun(T t, const Q &q)
|
Proxy_Function fun(T t, const Q &q)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(bind_first(t, q));
|
return fun(bind_first(t, q));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Q, typename R>
|
template<typename T, typename Q, typename R>
|
||||||
Proxy_Function fun(T t, const Q &q, const R &r)
|
Proxy_Function fun(T t, const Q &q, const R &r)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(bind_first(bind_first(t, q), r));
|
return fun(bind_first(bind_first(t, q), r));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -29,14 +29,14 @@ namespace chaiscript
|
|||||||
: m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
|
: 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_type_info(t_ti), m_bare_type_info(t_bareti),
|
m_type_info(t_ti), m_bare_type_info(t_bareti),
|
||||||
m_is_unknown(false)
|
m_is_undef(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Type_Info()
|
Type_Info()
|
||||||
: m_is_const(false), m_is_reference(false), m_is_pointer(false),
|
: 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_type_info(0), m_bare_type_info(0),
|
||||||
m_is_unknown(true)
|
m_is_undef(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ namespace chaiscript
|
|||||||
m_is_pointer(ti.m_is_pointer),
|
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_type_info(ti.m_type_info),
|
||||||
m_bare_type_info(ti.m_bare_type_info),
|
m_bare_type_info(ti.m_bare_type_info),
|
||||||
m_is_unknown(ti.m_is_unknown)
|
m_is_undef(ti.m_is_undef)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ namespace chaiscript
|
|||||||
m_is_void = ti.m_is_void;
|
m_is_void = ti.m_is_void;
|
||||||
m_type_info = ti.m_type_info;
|
m_type_info = ti.m_type_info;
|
||||||
m_bare_type_info = ti.m_bare_type_info;
|
m_bare_type_info = ti.m_bare_type_info;
|
||||||
m_is_unknown = ti.m_is_unknown;
|
m_is_undef = ti.m_is_undef;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,18 @@ namespace chaiscript
|
|||||||
bool is_const() const { return m_is_const; }
|
bool is_const() const { return m_is_const; }
|
||||||
bool is_reference() const { return m_is_reference; }
|
bool is_reference() const { return m_is_reference; }
|
||||||
bool is_void() const { return m_is_void; }
|
bool is_void() const { return m_is_void; }
|
||||||
bool is_unknown() const { return m_is_unknown || m_bare_type_info == 0; }
|
bool is_undef() const { return m_is_undef || m_bare_type_info == 0; }
|
||||||
|
bool is_pointer() const { return m_is_pointer; }
|
||||||
|
|
||||||
|
std::string name() const
|
||||||
|
{
|
||||||
|
if (m_type_info)
|
||||||
|
{
|
||||||
|
return m_type_info->name();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string bare_name() const
|
std::string bare_name() const
|
||||||
{
|
{
|
||||||
@@ -105,7 +116,7 @@ namespace chaiscript
|
|||||||
bool m_is_void;
|
bool m_is_void;
|
||||||
const std::type_info *m_type_info;
|
const std::type_info *m_type_info;
|
||||||
const std::type_info *m_bare_type_info;
|
const std::type_info *m_bare_type_info;
|
||||||
bool m_is_unknown;
|
bool m_is_undef;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
|
@@ -22,9 +22,10 @@ namespace chaiscript
|
|||||||
* Types of AST nodes available to the parser and eval
|
* Types of AST nodes available to the parser and eval
|
||||||
*/
|
*/
|
||||||
class Token_Type { public: enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl,
|
class Token_Type { public: enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl,
|
||||||
Expression, Comparison, Additive, Multiplicative, Negate, Not, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String,
|
Comparison, Additive, Multiplicative, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String,
|
||||||
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Map_Pair, Value_Range,
|
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Map_Pair, Value_Range,
|
||||||
Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift }; };
|
Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or,
|
||||||
|
Logical_And, Logical_Or}; };
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -33,9 +34,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
const char *token_type_to_string(int tokentype) {
|
const char *token_type_to_string(int tokentype) {
|
||||||
const char *token_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl",
|
const char *token_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl",
|
||||||
"Expression", "Comparison", "Additive", "Multiplicative", "Negate", "Not", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String",
|
"Comparison", "Additive", "Multiplicative", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String",
|
||||||
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Map_Pair", "Value_Range",
|
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Map_Pair", "Value_Range",
|
||||||
"Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift"};
|
"Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or",
|
||||||
|
"Logical_And", "Logical_Or"};
|
||||||
|
|
||||||
return token_types[tokentype];
|
return token_types[tokentype];
|
||||||
}
|
}
|
||||||
|
@@ -78,17 +78,14 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
||||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name)
|
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
||||||
|
m_moduleptr(m_func.m_symbol())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ModulePtr get()
|
|
||||||
{
|
|
||||||
return m_func.m_symbol();
|
|
||||||
}
|
|
||||||
|
|
||||||
DLModule m_dlmodule;
|
DLModule m_dlmodule;
|
||||||
DLSym<Create_Module_Func> m_func;
|
DLSym<Create_Module_Func> m_func;
|
||||||
|
ModulePtr m_moduleptr;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -188,17 +185,14 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
||||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name)
|
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
||||||
|
m_moduleptr(m_func.m_symbol());
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ModulePtr get()
|
|
||||||
{
|
|
||||||
return m_func.m_symbol();
|
|
||||||
}
|
|
||||||
|
|
||||||
DLModule m_dlmodule;
|
DLModule m_dlmodule;
|
||||||
DLSym<Create_Module_Func> m_func;
|
DLSym<Create_Module_Func> m_func;
|
||||||
|
ModulePtr m_moduleptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -229,6 +223,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
std::set<std::string> loaded_files;
|
std::set<std::string> loaded_files;
|
||||||
std::map<std::string, Loadable_Module_Ptr> loaded_modules;
|
std::map<std::string, Loadable_Module_Ptr> loaded_modules;
|
||||||
|
std::set<std::string> active_loaded_modules;
|
||||||
|
|
||||||
Eval_Engine engine;
|
Eval_Engine engine;
|
||||||
|
|
||||||
@@ -333,12 +328,53 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* Adds a shared object, that can be used by all threads, to the system
|
* Adds a shared object, that can be used by all threads, to the system
|
||||||
*/
|
*/
|
||||||
ChaiScript_System &add_shared_object(const Boxed_Value &bv, const std::string &name)
|
ChaiScript_System &add_global_const(const Boxed_Value &bv, const std::string &name)
|
||||||
{
|
{
|
||||||
engine.add_shared_object(bv, name);
|
engine.add_global_const(bv, name);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
std::set<std::string> loaded_files;
|
||||||
|
typename Eval_Engine::State engine_state;
|
||||||
|
std::set<std::string> active_loaded_modules;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a state object that represents the current
|
||||||
|
* set of loaded files, the set of global variables and
|
||||||
|
* the set of initialized functions
|
||||||
|
*/
|
||||||
|
State get_state()
|
||||||
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
|
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
|
||||||
|
boost::shared_lock<boost::shared_mutex> l2(mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
State s;
|
||||||
|
s.loaded_files = loaded_files;
|
||||||
|
s.engine_state = engine.get_state();
|
||||||
|
s.active_loaded_modules = active_loaded_modules;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the state from a saved State object.
|
||||||
|
*/
|
||||||
|
void set_state(const State &t_state)
|
||||||
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
|
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
|
||||||
|
boost::shared_lock<boost::shared_mutex> l2(mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
loaded_files = t_state.loaded_files;
|
||||||
|
active_loaded_modules = t_state.active_loaded_modules;
|
||||||
|
engine.set_state(t_state.engine_state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an object to the system: type, function, object
|
* Adds an object to the system: type, function, object
|
||||||
*/
|
*/
|
||||||
@@ -402,7 +438,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
Loadable_Module_Ptr lm(new Loadable_Module(t_module_name, t_filename));
|
Loadable_Module_Ptr lm(new Loadable_Module(t_module_name, t_filename));
|
||||||
loaded_modules[t_module_name] = lm;
|
loaded_modules[t_module_name] = lm;
|
||||||
add(lm->get());
|
active_loaded_modules.insert(t_module_name);
|
||||||
|
add(lm->m_moduleptr);
|
||||||
|
} else if (active_loaded_modules.count(t_module_name) == 0) {
|
||||||
|
active_loaded_modules.insert(t_module_name);
|
||||||
|
add(loaded_modules[t_module_name]->m_moduleptr);
|
||||||
} else {
|
} else {
|
||||||
engine.sync_cache();
|
engine.sync_cache();
|
||||||
}
|
}
|
||||||
@@ -499,6 +539,8 @@ namespace chaiscript
|
|||||||
engine.add(fun(&Eval_Engine::type_name, boost::ref(engine)), "type_name");
|
engine.add(fun(&Eval_Engine::type_name, boost::ref(engine)), "type_name");
|
||||||
engine.add(fun(&Eval_Engine::function_exists, boost::ref(engine)), "function_exists");
|
engine.add(fun(&Eval_Engine::function_exists, boost::ref(engine)), "function_exists");
|
||||||
|
|
||||||
|
engine.add(fun(&Eval_Engine::get_type_name, boost::ref(engine)), "name");
|
||||||
|
|
||||||
|
|
||||||
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_1)(const std::string&);
|
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_1)(const std::string&);
|
||||||
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_2)(const std::string&, const std::string&);
|
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_2)(const std::string&, const std::string&);
|
||||||
|
@@ -42,12 +42,15 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_file(Eval_System &ss, const TokenPtr &node) {
|
Boxed_Value eval_file(Eval_System &ss, const TokenPtr &node) {
|
||||||
Boxed_Value retval;
|
const unsigned int size = node->children.size();
|
||||||
unsigned int i;
|
for (unsigned int i = 0; i < size; ++i) {
|
||||||
for (i = 0; i < node->children.size(); ++i) {
|
const Boxed_Value &retval = eval_token(ss, node->children[i]);
|
||||||
retval = eval_token(ss, node->children[i]);
|
if (i + 1 == size)
|
||||||
|
{
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return retval;
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
@@ -171,18 +174,16 @@ namespace chaiscript
|
|||||||
Boxed_Value lhs = eval_token(ss, node->children[i]);
|
Boxed_Value lhs = eval_token(ss, node->children[i]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (lhs.is_unknown())
|
if (lhs.is_undef())
|
||||||
{
|
{
|
||||||
retval = ss.call_function("clone", Param_List_Builder() << retval);
|
retval = ss.call_function("clone", retval);
|
||||||
}
|
}
|
||||||
Param_List_Builder plb;
|
|
||||||
plb << lhs;
|
|
||||||
plb << retval;
|
|
||||||
try {
|
try {
|
||||||
retval = ss.call_function(node->children[i+1]->text, plb);
|
retval = ss.call_function(node->children[i+1]->text, lhs, retval);
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &){
|
catch(const dispatch_error &){
|
||||||
throw Eval_Error("Mismatched types in equation", node->children[i+1]);
|
throw Eval_Error(std::string("Mismatched types in equation") + (lhs.is_const()?", lhs is const.":"."), node->children[i+1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &){
|
catch(const dispatch_error &){
|
||||||
@@ -191,7 +192,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
else if (node->children[i+1]->text == ":=") {
|
else if (node->children[i+1]->text == ":=") {
|
||||||
Boxed_Value lhs = eval_token(ss, node->children[i]);
|
Boxed_Value lhs = eval_token(ss, node->children[i]);
|
||||||
if (lhs.is_unknown() || type_match(lhs, retval)) {
|
if (lhs.is_undef() || type_match(lhs, retval)) {
|
||||||
lhs.assign(retval);
|
lhs.assign(retval);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -199,11 +200,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Param_List_Builder plb;
|
|
||||||
plb << eval_token(ss, node->children[i]);
|
|
||||||
plb << retval;
|
|
||||||
try {
|
try {
|
||||||
retval = ss.call_function(node->children[i+1]->text, plb);
|
retval = ss.call_function(node->children[i+1]->text, eval_token(ss, node->children[i]), retval);
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &){
|
catch(const dispatch_error &){
|
||||||
throw Eval_Error("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]);
|
throw Eval_Error("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]);
|
||||||
@@ -248,15 +246,15 @@ namespace chaiscript
|
|||||||
* Evaluates binary boolean operators. Respects short-circuiting rules.
|
* Evaluates binary boolean operators. Respects short-circuiting rules.
|
||||||
*/
|
*/
|
||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_expression(Eval_System &ss, const TokenPtr &node) {
|
Boxed_Value eval_logical(Eval_System &ss, const TokenPtr &node) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
Boxed_Value retval(eval_token(ss, node->children[0]));
|
||||||
if (node->children.size() > 1) {
|
if (node->children.size() > 1) {
|
||||||
for (i = 1; i < node->children.size(); i += 2) {
|
for (i = 1; i < node->children.size(); i += 2) {
|
||||||
bool lhs;
|
bool lhs;
|
||||||
try {
|
try {
|
||||||
lhs = boxed_cast<bool &>(retval);
|
lhs = boxed_cast<bool>(retval);
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const bad_boxed_cast &) {
|
||||||
throw Eval_Error("Condition not boolean", node);
|
throw Eval_Error("Condition not boolean", node);
|
||||||
@@ -290,18 +288,12 @@ namespace chaiscript
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||||
if (node->children.size() > 1) {
|
for (i = 1; i < node->children.size(); i += 2) {
|
||||||
for (i = 1; i < node->children.size(); i += 2) {
|
try {
|
||||||
Param_List_Builder plb;
|
retval = ss.call_function(node->children[i]->text, retval, eval_token(ss, node->children[i + 1]));
|
||||||
plb << retval;
|
}
|
||||||
plb << eval_token(ss, node->children[i + 1]);
|
catch(const dispatch_error &){
|
||||||
|
throw Eval_Error("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]);
|
||||||
try {
|
|
||||||
retval = ss.call_function(node->children[i]->text, plb);
|
|
||||||
}
|
|
||||||
catch(const dispatch_error &){
|
|
||||||
throw Eval_Error("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,11 +309,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||||
for (i = 1; i < node->children.size(); ++i) {
|
for (i = 1; i < node->children.size(); ++i) {
|
||||||
Param_List_Builder plb;
|
|
||||||
plb << retval;
|
|
||||||
plb << eval_token(ss, node->children[i]);
|
|
||||||
try {
|
try {
|
||||||
retval = ss.call_function("[]", plb);
|
retval = ss.call_function("[]", retval, eval_token(ss, node->children[i]));
|
||||||
}
|
}
|
||||||
catch(std::out_of_range &) {
|
catch(std::out_of_range &) {
|
||||||
throw Eval_Error("Out of bounds exception", node);
|
throw Eval_Error("Out of bounds exception", node);
|
||||||
@@ -334,50 +323,16 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates a unary negation
|
|
||||||
*/
|
|
||||||
template <typename Eval_System>
|
|
||||||
Boxed_Value eval_negate(Eval_System &ss, const TokenPtr &node) {
|
|
||||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
|
||||||
Param_List_Builder plb;
|
|
||||||
plb << retval;
|
|
||||||
plb << Boxed_Value(-1.0);
|
|
||||||
|
|
||||||
try {
|
|
||||||
return ss.call_function("*", plb);
|
|
||||||
}
|
|
||||||
catch(std::exception &){
|
|
||||||
throw Eval_Error("Can not find appropriate negation", node->children[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates a unary boolean not
|
|
||||||
*/
|
|
||||||
template <typename Eval_System>
|
|
||||||
Boxed_Value eval_not(Eval_System &ss, const TokenPtr &node) {
|
|
||||||
try {
|
|
||||||
return Boxed_Value(!boxed_cast<bool>(eval_token(ss, node->children[0])));
|
|
||||||
}
|
|
||||||
catch (const bad_boxed_cast &) {
|
|
||||||
throw Eval_Error("Boolean not('!') condition not boolean", node->children[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates any unary prefix
|
* Evaluates any unary prefix
|
||||||
*/
|
*/
|
||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_prefix(Eval_System &ss, const TokenPtr &node) {
|
Boxed_Value eval_prefix(Eval_System &ss, const TokenPtr &node) {
|
||||||
Param_List_Builder plb;
|
|
||||||
plb << eval_token(ss, node->children[1]);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return ss.call_function(node->children[0]->text, plb);
|
return ss.call_function(node->children[0]->text, eval_token(ss, node->children[1]));
|
||||||
}
|
}
|
||||||
catch(std::exception &){
|
catch(std::exception &){
|
||||||
throw Eval_Error("Can not find appropriate prefix", node->children[0]);
|
throw Eval_Error("Can not find appropriate unary '" + node->children[0]->text + "'", node->children[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,16 +344,13 @@ namespace chaiscript
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Boxed_Value retval = ss.call_function("Vector", Param_List_Builder());
|
Boxed_Value retval = ss.call_function("Vector");
|
||||||
if (node->children.size() > 0) {
|
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
try {
|
||||||
try {
|
ss.call_function("push_back", retval, eval_token(ss, node->children[0]->children[i]));
|
||||||
Boxed_Value tmp = eval_token(ss, node->children[0]->children[i]);
|
}
|
||||||
ss.call_function("push_back", Param_List_Builder() << retval << tmp);
|
catch (const dispatch_error &) {
|
||||||
}
|
throw Eval_Error("Can not find appropriate 'push_back'", node->children[0]->children[i]);
|
||||||
catch (const dispatch_error &) {
|
|
||||||
throw Eval_Error("Can not find appropriate 'push_back'", node->children[0]->children[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,9 +368,9 @@ namespace chaiscript
|
|||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_inline_range(Eval_System &ss, const TokenPtr &node) {
|
Boxed_Value eval_inline_range(Eval_System &ss, const TokenPtr &node) {
|
||||||
try {
|
try {
|
||||||
return ss.call_function("generate_range", Param_List_Builder()
|
return ss.call_function("generate_range",
|
||||||
<< eval_token(ss, node->children[0]->children[0]->children[0])
|
eval_token(ss, node->children[0]->children[0]->children[0]),
|
||||||
<< eval_token(ss, node->children[0]->children[0]->children[1]));
|
eval_token(ss, node->children[0]->children[0]->children[1]));
|
||||||
}
|
}
|
||||||
catch (const dispatch_error &) {
|
catch (const dispatch_error &) {
|
||||||
throw Eval_Error("Unable to generate range vector", node);
|
throw Eval_Error("Unable to generate range vector", node);
|
||||||
@@ -433,12 +385,12 @@ namespace chaiscript
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Boxed_Value retval = ss.call_function("Map", Param_List_Builder());
|
Boxed_Value retval = ss.call_function("Map");
|
||||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||||
try {
|
try {
|
||||||
Boxed_Value key = eval_token(ss, node->children[0]->children[i]->children[0]);
|
Boxed_Value slot
|
||||||
Boxed_Value slot = ss.call_function("[]", Param_List_Builder() << retval << key);
|
= ss.call_function("[]", retval, eval_token(ss, node->children[0]->children[i]->children[0]));
|
||||||
ss.call_function("=", Param_List_Builder() << slot << eval_token(ss, node->children[0]->children[i]->children[1]));
|
ss.call_function("=", slot, eval_token(ss, node->children[0]->children[i]->children[1]));
|
||||||
}
|
}
|
||||||
catch (const dispatch_error &) {
|
catch (const dispatch_error &) {
|
||||||
throw Eval_Error("Can not find appropriate '=' for map init", node->children[0]->children[i]);
|
throw Eval_Error("Can not find appropriate '=' for map init", node->children[0]->children[i]);
|
||||||
@@ -472,7 +424,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ss.set_stack(new_stack);
|
ss.set_stack(new_stack);
|
||||||
Boxed_Value retval = (*boxed_cast<Const_Proxy_Function>(fn))(plb);
|
const Boxed_Value &retval = (*boxed_cast<Const_Proxy_Function>(fn))(plb);
|
||||||
ss.set_stack(prev_stack);
|
ss.set_stack(prev_stack);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -514,8 +466,7 @@ namespace chaiscript
|
|||||||
Boxed_Value fn = eval_token(ss, node->children[0]);
|
Boxed_Value fn = eval_token(ss, node->children[0]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Boxed_Value retval = (*boxed_cast<Const_Proxy_Function >(fn))(plb);
|
return (*boxed_cast<Const_Proxy_Function >(fn))(plb);
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &e){
|
catch(const dispatch_error &e){
|
||||||
throw Eval_Error(std::string(e.what()) + " with function '" + node->children[0]->text + "'", node->children[0]);
|
throw Eval_Error(std::string(e.what()) + " with function '" + node->children[0]->text + "'", node->children[0]);
|
||||||
@@ -544,9 +495,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
//todo: Please extract a single way of doing function calls between this and eval_fun_call
|
//todo: Please extract a single way of doing function calls between this and eval_fun_call
|
||||||
|
|
||||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
Boxed_Value retval(eval_token(ss, node->children[0]));
|
||||||
if (node->children.size() > 1) {
|
if (node->children.size() > 1) {
|
||||||
for (i = 1; i < node->children.size(); ++i) {
|
for (i = 2; i < node->children.size(); i+=2) {
|
||||||
Param_List_Builder plb;
|
Param_List_Builder plb;
|
||||||
plb << retval;
|
plb << retval;
|
||||||
|
|
||||||
@@ -601,7 +552,6 @@ namespace chaiscript
|
|||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_try(Eval_System &ss, const TokenPtr &node) {
|
Boxed_Value eval_try(Eval_System &ss, const TokenPtr &node) {
|
||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
retval = Boxed_Value();
|
|
||||||
|
|
||||||
ss.new_scope();
|
ss.new_scope();
|
||||||
try {
|
try {
|
||||||
@@ -714,6 +664,7 @@ namespace chaiscript
|
|||||||
ss.pop_scope();
|
ss.pop_scope();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->children.back()->identifier == Token_Type::Finally) {
|
if (node->children.back()->identifier == Token_Type::Finally) {
|
||||||
retval = eval_token(ss, node->children.back()->children[0]);
|
retval = eval_token(ss, node->children.back()->children[0]);
|
||||||
}
|
}
|
||||||
@@ -730,35 +681,32 @@ namespace chaiscript
|
|||||||
Boxed_Value eval_if(Eval_System &ss, const TokenPtr &node) {
|
Boxed_Value eval_if(Eval_System &ss, const TokenPtr &node) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
|
||||||
bool cond;
|
bool cond;
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(retval);
|
cond = boxed_cast<bool>(eval_token(ss, node->children[0]));
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const bad_boxed_cast &) {
|
||||||
throw Eval_Error("If condition not boolean", node->children[0]);
|
throw Eval_Error("If condition not boolean", node->children[0]);
|
||||||
}
|
}
|
||||||
if (cond) {
|
if (cond) {
|
||||||
retval = eval_token(ss, node->children[1]);
|
return eval_token(ss, node->children[1]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (node->children.size() > 2) {
|
if (node->children.size() > 2) {
|
||||||
i = 2;
|
i = 2;
|
||||||
while ((!cond) && (i < node->children.size())) {
|
while ((!cond) && (i < node->children.size())) {
|
||||||
if (node->children[i]->text == "else") {
|
if (node->children[i]->text == "else") {
|
||||||
retval = eval_token(ss, node->children[i+1]);
|
return eval_token(ss, node->children[i+1]);
|
||||||
cond = true;
|
|
||||||
}
|
}
|
||||||
else if (node->children[i]->text == "else if") {
|
else if (node->children[i]->text == "else if") {
|
||||||
retval = eval_token(ss, node->children[i+1]);
|
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(retval);
|
cond = boxed_cast<bool>(eval_token(ss, node->children[i+1]));
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const bad_boxed_cast &) {
|
||||||
throw Eval_Error("'else if' condition not boolean", node->children[i+1]);
|
throw Eval_Error("'else if' condition not boolean", node->children[i+1]);
|
||||||
}
|
}
|
||||||
if (cond) {
|
if (cond) {
|
||||||
retval = eval_token(ss, node->children[i+2]);
|
return eval_token(ss, node->children[i+2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = i + 3;
|
i = i + 3;
|
||||||
@@ -766,7 +714,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return Boxed_Value(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1011,17 +959,22 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_block(Eval_System &ss, const TokenPtr &node) {
|
Boxed_Value eval_block(Eval_System &ss, const TokenPtr &node) {
|
||||||
Boxed_Value retval;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
unsigned int num_children = node->children.size();
|
||||||
|
|
||||||
ss.new_scope();
|
ss.new_scope();
|
||||||
for (i = 0; i < node->children.size(); ++i) {
|
for (i = 0; i < num_children; ++i) {
|
||||||
try {
|
try {
|
||||||
retval = eval_token(ss, node->children[i]);
|
const Boxed_Value &retval = eval_token(ss, node->children[i]);
|
||||||
|
|
||||||
|
if (i + 1 == num_children)
|
||||||
|
{
|
||||||
|
ss.pop_scope();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const chaiscript::Return_Value &rv) {
|
catch (const chaiscript::Return_Value &rv) {
|
||||||
ss.pop_scope();
|
ss.pop_scope();
|
||||||
retval = rv.retval;
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
@@ -1029,9 +982,9 @@ namespace chaiscript
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ss.pop_scope();
|
|
||||||
|
|
||||||
return retval;
|
ss.pop_scope();
|
||||||
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1093,11 +1046,16 @@ namespace chaiscript
|
|||||||
return eval_var_decl(ss, node);
|
return eval_var_decl(ss, node);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (Token_Type::Expression) :
|
case (Token_Type::Logical_And) :
|
||||||
return eval_expression(ss, node);
|
case (Token_Type::Logical_Or) :
|
||||||
|
return eval_logical(ss, node);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case (Token_Type::Bitwise_And) :
|
||||||
|
case (Token_Type::Bitwise_Xor) :
|
||||||
|
case (Token_Type::Bitwise_Or) :
|
||||||
case (Token_Type::Comparison) :
|
case (Token_Type::Comparison) :
|
||||||
|
case (Token_Type::Equality) :
|
||||||
case (Token_Type::Additive) :
|
case (Token_Type::Additive) :
|
||||||
case (Token_Type::Multiplicative) :
|
case (Token_Type::Multiplicative) :
|
||||||
case (Token_Type::Shift) :
|
case (Token_Type::Shift) :
|
||||||
@@ -1108,14 +1066,6 @@ namespace chaiscript
|
|||||||
return eval_array_call(ss, node);
|
return eval_array_call(ss, node);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (Token_Type::Negate) :
|
|
||||||
return eval_negate(ss, node);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (Token_Type::Not) :
|
|
||||||
return eval_not(ss, node);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (Token_Type::Prefix) :
|
case (Token_Type::Prefix) :
|
||||||
return eval_prefix(ss, node);
|
return eval_prefix(ss, node);
|
||||||
break;
|
break;
|
||||||
|
@@ -7,11 +7,14 @@
|
|||||||
#ifndef CHAISCRIPT_PARSER_HPP_
|
#ifndef CHAISCRIPT_PARSER_HPP_
|
||||||
#define CHAISCRIPT_PARSER_HPP_
|
#define CHAISCRIPT_PARSER_HPP_
|
||||||
|
|
||||||
|
#include <boost/assign/std/vector.hpp>
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "chaiscript_prelude.hpp"
|
#include "chaiscript_prelude.hpp"
|
||||||
|
#include "chaiscript_common.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -24,16 +27,79 @@ namespace chaiscript
|
|||||||
const char *filename;
|
const char *filename;
|
||||||
std::vector<TokenPtr> match_stack;
|
std::vector<TokenPtr> match_stack;
|
||||||
|
|
||||||
|
std::vector<std::vector<std::string> > operator_matches;
|
||||||
|
std::vector<Token_Type::Type> operators;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChaiScript_Parser() {
|
ChaiScript_Parser() {
|
||||||
multiline_comment_begin = "/*";
|
multiline_comment_begin = "/*";
|
||||||
multiline_comment_end = "*/";
|
multiline_comment_end = "*/";
|
||||||
singleline_comment = "//";
|
singleline_comment = "//";
|
||||||
|
|
||||||
|
setup_operators();
|
||||||
}
|
}
|
||||||
|
|
||||||
ChaiScript_Parser(const ChaiScript_Parser &); // explicitly unimplemented copy constructor
|
ChaiScript_Parser(const ChaiScript_Parser &); // explicitly unimplemented copy constructor
|
||||||
ChaiScript_Parser &operator=(const ChaiScript_Parser &); // explicitly unimplemented assignment operator
|
ChaiScript_Parser &operator=(const ChaiScript_Parser &); // explicitly unimplemented assignment operator
|
||||||
|
|
||||||
|
void setup_operators() {
|
||||||
|
using namespace boost::assign;
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Logical_Or);
|
||||||
|
std::vector<std::string> logical_or;
|
||||||
|
logical_or += "||";
|
||||||
|
operator_matches.push_back(logical_or);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Logical_And);
|
||||||
|
std::vector<std::string> logical_and;
|
||||||
|
logical_and += "&&";
|
||||||
|
operator_matches.push_back(logical_and);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Bitwise_Or);
|
||||||
|
std::vector<std::string> bitwise_or;
|
||||||
|
bitwise_or += "|";
|
||||||
|
operator_matches.push_back(bitwise_or);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Bitwise_Xor);
|
||||||
|
std::vector<std::string> bitwise_xor;
|
||||||
|
bitwise_xor += "^";
|
||||||
|
operator_matches.push_back(bitwise_xor);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Bitwise_And);
|
||||||
|
std::vector<std::string> bitwise_and;
|
||||||
|
bitwise_and += "&";
|
||||||
|
operator_matches.push_back(bitwise_and);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Equality);
|
||||||
|
std::vector<std::string> equality;
|
||||||
|
equality += "==", "!=";
|
||||||
|
operator_matches.push_back(equality);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Comparison);
|
||||||
|
std::vector<std::string> comparison;
|
||||||
|
comparison += "<", "<=", ">", ">=";
|
||||||
|
operator_matches.push_back(comparison);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Shift);
|
||||||
|
std::vector<std::string> shift;
|
||||||
|
shift += "<<", ">>";
|
||||||
|
operator_matches.push_back(shift);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Additive);
|
||||||
|
std::vector<std::string> additive;
|
||||||
|
additive += "+", "-";
|
||||||
|
operator_matches.push_back(additive);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Multiplicative);
|
||||||
|
std::vector<std::string> multiplicative;
|
||||||
|
multiplicative += "*", "/", "%";
|
||||||
|
operator_matches.push_back(multiplicative);
|
||||||
|
|
||||||
|
operators.push_back(Token_Type::Dot_Access);
|
||||||
|
std::vector<std::string> dot_access;
|
||||||
|
dot_access += ".";
|
||||||
|
operator_matches.push_back(dot_access);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Prints the parsed tokens as a tree
|
* Prints the parsed tokens as a tree
|
||||||
*/
|
*/
|
||||||
@@ -105,7 +171,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
else if (Symbol_(singleline_comment.c_str())) {
|
else if (Symbol_(singleline_comment.c_str())) {
|
||||||
while (input_pos != input_end) {
|
while (input_pos != input_end) {
|
||||||
if (Eol_()) {
|
if (Symbol_("\r\n") || Char_('\n')) {
|
||||||
|
++line;
|
||||||
|
col = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -797,7 +865,8 @@ namespace chaiscript
|
|||||||
bool retval = Symbol_(s);
|
bool retval = Symbol_(s);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
//todo: fix this. Hacky workaround for preventing substring matches
|
//todo: fix this. Hacky workaround for preventing substring matches
|
||||||
if ((input_pos != input_end) && (disallow_prevention == false) && ((*input_pos == '+') || (*input_pos == '-') || (*input_pos == '*') || (*input_pos == '/') || (*input_pos == '=') || (*input_pos == '.'))) {
|
if ((input_pos != input_end) && (disallow_prevention == false) && ((*input_pos == '+') || (*input_pos == '-') || (*input_pos == '*') || (*input_pos == '/')
|
||||||
|
|| (*input_pos == '|') || (*input_pos == '&') || (*input_pos == '^') || (*input_pos == '=') || (*input_pos == '.') || (*input_pos == '<') || (*input_pos == '>'))) {
|
||||||
input_pos = start;
|
input_pos = start;
|
||||||
col = prev_col;
|
col = prev_col;
|
||||||
line = prev_line;
|
line = prev_line;
|
||||||
@@ -815,7 +884,8 @@ namespace chaiscript
|
|||||||
int prev_line = line;
|
int prev_line = line;
|
||||||
if (Symbol_(s)) {
|
if (Symbol_(s)) {
|
||||||
//todo: fix this. Hacky workaround for preventing substring matches
|
//todo: fix this. Hacky workaround for preventing substring matches
|
||||||
if ((input_pos != input_end) && (disallow_prevention == false) && ((*input_pos == '+') || (*input_pos == '-') || (*input_pos == '*') || (*input_pos == '/') || (*input_pos == '=') || (*input_pos == '.'))) {
|
if ((input_pos != input_end) && (disallow_prevention == false) && ((*input_pos == '+') || (*input_pos == '-') || (*input_pos == '*') || (*input_pos == '/')
|
||||||
|
|| (*input_pos == '|') || (*input_pos == '&') || (*input_pos == '^') || (*input_pos == '=') || (*input_pos == '.') || (*input_pos == '<') || (*input_pos == '>'))) {
|
||||||
input_pos = start;
|
input_pos = start;
|
||||||
col = prev_col;
|
col = prev_col;
|
||||||
line = prev_line;
|
line = prev_line;
|
||||||
@@ -1006,7 +1076,7 @@ namespace chaiscript
|
|||||||
while (Eol());
|
while (Eol());
|
||||||
|
|
||||||
if (Char(':')) {
|
if (Char(':')) {
|
||||||
if (!Expression()) {
|
if (!Operator()) {
|
||||||
throw Eval_Error("Missing guard expression for function", File_Position(line, col), filename);
|
throw Eval_Error("Missing guard expression for function", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1059,7 +1129,7 @@ namespace chaiscript
|
|||||||
throw Eval_Error("Incomplete 'catch' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete 'catch' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
if (Char(':')) {
|
if (Char(':')) {
|
||||||
if (!Expression()) {
|
if (!Operator()) {
|
||||||
throw Eval_Error("Missing guard expression for catch", File_Position(line, col), filename);
|
throw Eval_Error("Missing guard expression for catch", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1177,7 @@ namespace chaiscript
|
|||||||
throw Eval_Error("Incomplete 'if' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete 'if' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(Expression() && Char(')'))) {
|
if (!(Operator() && Char(')'))) {
|
||||||
throw Eval_Error("Incomplete 'if' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete 'if' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1128,7 +1198,7 @@ namespace chaiscript
|
|||||||
throw Eval_Error("Incomplete 'else if' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete 'else if' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(Expression() && Char(')'))) {
|
if (!(Operator() && Char(')'))) {
|
||||||
throw Eval_Error("Incomplete 'else if' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete 'else if' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1171,7 +1241,7 @@ namespace chaiscript
|
|||||||
throw Eval_Error("Incomplete 'while' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete 'while' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(Expression() && Char(')'))) {
|
if (!(Operator() && Char(')'))) {
|
||||||
throw Eval_Error("Incomplete 'while' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete 'while' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1193,7 +1263,7 @@ namespace chaiscript
|
|||||||
bool For_Guards() {
|
bool For_Guards() {
|
||||||
Equation();
|
Equation();
|
||||||
|
|
||||||
if (Char(';') && Expression() && Char(';') && Equation()) {
|
if (Char(';') && Operator() && Char(';') && Equation()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1265,7 +1335,7 @@ namespace chaiscript
|
|||||||
if (Keyword("return")) {
|
if (Keyword("return")) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
Expression();
|
Operator();
|
||||||
build_match(Token_Type::Return, prev_stack_top);
|
build_match(Token_Type::Return, prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1317,7 +1387,7 @@ namespace chaiscript
|
|||||||
else if (Char('[')) {
|
else if (Char('[')) {
|
||||||
has_more = true;
|
has_more = true;
|
||||||
|
|
||||||
if (!(Expression() && Char(']'))) {
|
if (!(Operator() && Char(']'))) {
|
||||||
throw Eval_Error("Incomplete array access", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete array access", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1374,7 +1444,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (Char('(')) {
|
if (Char('(')) {
|
||||||
retval = true;
|
retval = true;
|
||||||
if (!Expression()) {
|
if (!Operator()) {
|
||||||
throw Eval_Error("Incomplete expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
if (!Char(')')) {
|
if (!Char(')')) {
|
||||||
@@ -1428,7 +1498,7 @@ namespace chaiscript
|
|||||||
if (Symbol("++", true)) {
|
if (Symbol("++", true)) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
if (!Dot_Access()) {
|
if (!Operator(operators.size()-1)) {
|
||||||
throw Eval_Error("Incomplete '++' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete '++' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1437,29 +1507,47 @@ namespace chaiscript
|
|||||||
else if (Symbol("--", true)) {
|
else if (Symbol("--", true)) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
if (!Dot_Access()) {
|
if (!Operator(operators.size()-1)) {
|
||||||
throw Eval_Error("Incomplete '--' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete '--' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match(Token_Type::Prefix, prev_stack_top);
|
build_match(Token_Type::Prefix, prev_stack_top);
|
||||||
}
|
}
|
||||||
else if (Char('-')) {
|
else if (Char('-', true)) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
if (!Dot_Access()) {
|
if (!Operator(operators.size()-1)) {
|
||||||
throw Eval_Error("Incomplete negation expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete unary '-' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match(Token_Type::Negate, prev_stack_top);
|
build_match(Token_Type::Prefix, prev_stack_top);
|
||||||
}
|
}
|
||||||
else if (Char('!')) {
|
else if (Char('+', true)) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
if (!Dot_Access()) {
|
if (!Operator(operators.size()-1)) {
|
||||||
|
throw Eval_Error("Incomplete unary '+' expression", File_Position(line, col), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
build_match(Token_Type::Prefix, prev_stack_top);
|
||||||
|
}
|
||||||
|
else if (Char('!', true)) {
|
||||||
|
retval = true;
|
||||||
|
|
||||||
|
if (!Operator(operators.size()-1)) {
|
||||||
throw Eval_Error("Incomplete '!' expression", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete '!' expression", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match(Token_Type::Not, prev_stack_top);
|
build_match(Token_Type::Prefix, prev_stack_top);
|
||||||
|
}
|
||||||
|
else if (Char('~', true)) {
|
||||||
|
retval = true;
|
||||||
|
|
||||||
|
if (!Operator(operators.size()-1)) {
|
||||||
|
throw Eval_Error("Incomplete '~' expression", File_Position(line, col), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
build_match(Token_Type::Prefix, prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@@ -1478,145 +1566,37 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bool Operator_Helper(int precedence) {
|
||||||
* Reads a string of binary comparisons from input
|
for (unsigned int i = 0; i < operator_matches[precedence].size(); ++i) {
|
||||||
*/
|
if (Symbol(operator_matches[precedence][i].c_str(), true)) {
|
||||||
bool Comparison() {
|
return true;
|
||||||
bool retval = false;
|
|
||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
|
||||||
|
|
||||||
if (Shift()) {
|
|
||||||
retval = true;
|
|
||||||
if (Symbol(">=", true) || Symbol(">", true) || Symbol("<=", true) || Symbol("<", true) || Symbol("==", true) || Symbol("!=", true)) {
|
|
||||||
do {
|
|
||||||
if (!Shift()) {
|
|
||||||
throw Eval_Error("Incomplete comparison expression", File_Position(line, col), filename);
|
|
||||||
}
|
|
||||||
} while (retval && (Symbol(">=", true) || Symbol(">", true) || Symbol("<=", true) || Symbol("<", true) || Symbol("==", true) || Symbol("!=", true)));
|
|
||||||
|
|
||||||
build_match(Token_Type::Comparison, prev_stack_top);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bool Operator(unsigned int precedence = 0) {
|
||||||
* Reads a string of binary additions/subtractions from input
|
|
||||||
*/
|
|
||||||
bool Additive() {
|
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
int prev_stack_top = match_stack.size();
|
||||||
|
|
||||||
if (Multiplicative()) {
|
if (precedence < operators.size()) {
|
||||||
retval = true;
|
if (Operator(precedence+1)) {
|
||||||
if (Symbol("+", true) || Symbol("-", true)) {
|
retval = true;
|
||||||
do {
|
if (Operator_Helper(precedence)) {
|
||||||
if (!Multiplicative()) {
|
do {
|
||||||
throw Eval_Error("Incomplete math expression", File_Position(line, col), filename);
|
if (!Operator(precedence+1)) {
|
||||||
}
|
throw Eval_Error("Incomplete " + std::string(token_type_to_string(operators[precedence])) + " expression",
|
||||||
} while (retval && (Symbol("+", true) || Symbol("-", true)));
|
File_Position(line, col), filename);
|
||||||
|
}
|
||||||
|
} while (Operator_Helper(precedence));
|
||||||
|
|
||||||
build_match(Token_Type::Additive, prev_stack_top);
|
build_match(operators[precedence], prev_stack_top);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return retval;
|
return Value();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a string of multiplication/division/modulus from input
|
|
||||||
*/
|
|
||||||
bool Multiplicative() {
|
|
||||||
bool retval = false;
|
|
||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
|
||||||
|
|
||||||
if (Dot_Access()) {
|
|
||||||
retval = true;
|
|
||||||
if (Symbol("*", true) || Symbol("/", true) || Symbol("%", true)) {
|
|
||||||
do {
|
|
||||||
if (!Dot_Access()) {
|
|
||||||
throw Eval_Error("Incomplete math expression", File_Position(line, col), filename);
|
|
||||||
}
|
|
||||||
} while (retval && (Symbol("*", true) || Symbol("/", true) || Symbol("%", true)));
|
|
||||||
|
|
||||||
build_match(Token_Type::Multiplicative, prev_stack_top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a string of dot-notation accesses from input
|
|
||||||
*/
|
|
||||||
bool Dot_Access() {
|
|
||||||
bool retval = false;
|
|
||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
|
||||||
|
|
||||||
if (Value()) {
|
|
||||||
retval = true;
|
|
||||||
if (Symbol(".")) {
|
|
||||||
do {
|
|
||||||
if (!Value()) {
|
|
||||||
throw Eval_Error("Incomplete dot notation", File_Position(line, col), filename);
|
|
||||||
}
|
|
||||||
} while (retval && Symbol("."));
|
|
||||||
|
|
||||||
build_match(Token_Type::Dot_Access, prev_stack_top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Top-level expression, parses a string of binary boolean operators from input
|
|
||||||
*/
|
|
||||||
bool Shift() {
|
|
||||||
bool retval = false;
|
|
||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
|
||||||
|
|
||||||
if (Additive()) {
|
|
||||||
retval = true;
|
|
||||||
if (Symbol("<<", true) || Symbol(">>", true)) {
|
|
||||||
do {
|
|
||||||
if (!Additive()) {
|
|
||||||
throw Eval_Error("Incomplete shift expression", File_Position(line, col), filename);
|
|
||||||
}
|
|
||||||
} while (retval && (Symbol("<<", true) || Symbol(">>", true)));
|
|
||||||
|
|
||||||
build_match(Token_Type::Shift, prev_stack_top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Top-level expression, parses a string of binary boolean operators from input
|
|
||||||
*/
|
|
||||||
bool Expression() {
|
|
||||||
bool retval = false;
|
|
||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
|
||||||
|
|
||||||
if (Comparison()) {
|
|
||||||
retval = true;
|
|
||||||
if (Symbol("&&", true) || Symbol("||", true)) {
|
|
||||||
do {
|
|
||||||
if (!Comparison()) {
|
|
||||||
throw Eval_Error("Incomplete expression", File_Position(line, col), filename);
|
|
||||||
}
|
|
||||||
} while (retval && (Symbol("&&", true) || Symbol("||", true)));
|
|
||||||
|
|
||||||
build_match(Token_Type::Expression, prev_stack_top);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@@ -1630,11 +1610,11 @@ namespace chaiscript
|
|||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
int prev_stack_top = match_stack.size();
|
||||||
|
|
||||||
if (Expression()) {
|
if (Operator()) {
|
||||||
retval = true;
|
retval = true;
|
||||||
if (Symbol(":")) {
|
if (Symbol(":")) {
|
||||||
do {
|
do {
|
||||||
if (!Expression()) {
|
if (!Operator()) {
|
||||||
throw Eval_Error("Incomplete map pair", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete map pair", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
} while (retval && Symbol(":"));
|
} while (retval && Symbol(":"));
|
||||||
@@ -1656,10 +1636,10 @@ namespace chaiscript
|
|||||||
std::string::iterator prev_pos = input_pos;
|
std::string::iterator prev_pos = input_pos;
|
||||||
int prev_col = col;
|
int prev_col = col;
|
||||||
|
|
||||||
if (Expression()) {
|
if (Operator()) {
|
||||||
if (Symbol("..")) {
|
if (Symbol("..")) {
|
||||||
retval = true;
|
retval = true;
|
||||||
if (!Expression()) {
|
if (!Operator()) {
|
||||||
throw Eval_Error("Incomplete value range", File_Position(line, col), filename);
|
throw Eval_Error("Incomplete value range", File_Position(line, col), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1685,10 +1665,12 @@ namespace chaiscript
|
|||||||
|
|
||||||
int prev_stack_top = match_stack.size();
|
int prev_stack_top = match_stack.size();
|
||||||
|
|
||||||
if (Expression()) {
|
if (Operator()) {
|
||||||
retval = true;
|
retval = true;
|
||||||
if (Symbol("=", true, true) || Symbol(":=", true, true) || Symbol("+=", true, true) ||
|
if (Symbol("=", true, true) || Symbol(":=", true, true) || Symbol("+=", true, true) ||
|
||||||
Symbol("-=", true, true) || Symbol("*=", true, true) || Symbol("/=", true, true)) {
|
Symbol("-=", true, true) || Symbol("*=", true, true) || Symbol("/=", true, true) ||
|
||||||
|
Symbol("%=", true, true) || Symbol("<<=", true, true) || Symbol(">>=", true, true) ||
|
||||||
|
Symbol("&=", true, true) || Symbol("^=", true, true) || Symbol("|=", true, true)) {
|
||||||
if (!Equation()) {
|
if (!Equation()) {
|
||||||
throw Eval_Error("Incomplete equation", match_stack.back());
|
throw Eval_Error("Incomplete equation", match_stack.back());
|
||||||
}
|
}
|
||||||
|
@@ -282,27 +282,27 @@ def zip(x, y) { \n\
|
|||||||
}\n\
|
}\n\
|
||||||
# Returns the position of the second value string in the first value string\n\
|
# Returns the position of the second value string in the first value string\n\
|
||||||
def string::find(substr) : is_type(substr, "string") { \n\
|
def string::find(substr) : is_type(substr, "string") { \n\
|
||||||
int(find(this, substr, size_t(0))); \n\
|
int(find(this, substr, 0)); \n\
|
||||||
} \n\
|
} \n\
|
||||||
# Returns the position of last match of the second value string in the first value string\n\
|
# Returns the position of last match of the second value string in the first value string\n\
|
||||||
def string::rfind(substr) : is_type(substr, "string") { \n\
|
def string::rfind(substr) : is_type(substr, "string") { \n\
|
||||||
int(rfind(this, substr, size_t(-1))); \n\
|
int(rfind(this, substr, -1)); \n\
|
||||||
} \n\
|
} \n\
|
||||||
# Returns the position of the first match of elements in the second value string in the first value string\n\
|
# Returns the position of the first match of elements in the second value string in the first value string\n\
|
||||||
def string::find_first_of(list) : is_type(list, "string") { \n\
|
def string::find_first_of(list) : is_type(list, "string") { \n\
|
||||||
int(find_first_of(this, list, size_t(0))); \n\
|
int(find_first_of(this, list, 0)); \n\
|
||||||
} \n\
|
} \n\
|
||||||
# Returns the position of the last match of elements in the second value string in the first value string\n\
|
# Returns the position of the last match of elements in the second value string in the first value string\n\
|
||||||
def string::find_last_of(list) : is_type(list, "string") { \n\
|
def string::find_last_of(list) : is_type(list, "string") { \n\
|
||||||
int(find_last_of(this, list, size_t(-1))); \n\
|
int(find_last_of(this, list, -1)); \n\
|
||||||
} \n\
|
} \n\
|
||||||
# Returns the position of the first non-matching element in the second value string in the first value string\n\
|
# Returns the position of the first non-matching element in the second value string in the first value string\n\
|
||||||
def string::find_first_not_of(list) : is_type(list, "string") { \n\
|
def string::find_first_not_of(list) : is_type(list, "string") { \n\
|
||||||
int(find_first_not_of(this, list, size_t(0))); \n\
|
int(find_first_not_of(this, list, 0)); \n\
|
||||||
} \n\
|
} \n\
|
||||||
# Returns the position of the last non-matching element in the second value string in the first value string\n\
|
# Returns the position of the last non-matching element in the second value string in the first value string\n\
|
||||||
def string::find_last_not_of(list) : is_type(list, "string") { \n\
|
def string::find_last_not_of(list) : is_type(list, "string") { \n\
|
||||||
int(find_last_not_of(this, list, size_t(-1))); \n\
|
int(find_last_not_of(this, list, -1)); \n\
|
||||||
} \n\
|
} \n\
|
||||||
def string::ltrim() { \n\
|
def string::ltrim() { \n\
|
||||||
drop_while(this, fun(x) { x == ' ' || x == '\t' }); \n\
|
drop_while(this, fun(x) { x == ' ' || x == '\t' }); \n\
|
||||||
|
@@ -14,6 +14,6 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalLibraryDirectories="C:\Boost\lib"
|
AdditionalLibraryDirectories="C:\Boost\lib;C:\Programming\Boost\lib"
|
||||||
/>
|
/>
|
||||||
</VisualStudioPropertySheet>
|
</VisualStudioPropertySheet>
|
||||||
|
@@ -189,6 +189,10 @@
|
|||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\chaiscript\dispatchkit\bind_first.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\chaiscript\dispatchkit\bootstrap.hpp"
|
RelativePath="..\..\include\chaiscript\dispatchkit\bootstrap.hpp"
|
||||||
>
|
>
|
||||||
@@ -245,6 +249,10 @@
|
|||||||
RelativePath="..\..\include\chaiscript\dispatchkit\handle_return.hpp"
|
RelativePath="..\..\include\chaiscript\dispatchkit\handle_return.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\chaiscript\dispatchkit\operators.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\chaiscript\dispatchkit\proxy_constructors.hpp"
|
RelativePath="..\..\include\chaiscript\dispatchkit\proxy_constructors.hpp"
|
||||||
>
|
>
|
||||||
|
@@ -1,3 +1,2 @@
|
|||||||
var i = 1
|
var i = 1
|
||||||
var j = eval("5 + 4")
|
var j = eval("5 + 4")
|
||||||
print(j)
|
|
||||||
|
@@ -2,11 +2,11 @@ for (var i = 0; i < 10; ++i) {
|
|||||||
print(i)
|
print(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 10; i >= 0; i -= 2) {
|
for (var i = 10; i >= 0; i -= 2) {
|
||||||
print(i)
|
print(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0
|
var i = 0
|
||||||
|
|
||||||
for (; i < 5; ++i) {
|
for (; i < 5; ++i) {
|
||||||
print(i)
|
print(i)
|
||||||
|
@@ -110,7 +110,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
//Finally, it is possible to register any boost::function as a system function, in this
|
//Finally, it is possible to register any boost::function as a system function, in this
|
||||||
//way, we can, for instance add a bound member function to the system
|
//way, we can, for instance add a bound member function to the system
|
||||||
chai.add(fun(&System::do_callbacks, boost::ref(system), "Bound Test"), "do_callbacks");
|
chai.add(fun(&System::do_callbacks, boost::ref(system), std::string("Bound Test")), "do_callbacks");
|
||||||
|
|
||||||
//Call bound version of do_callbacks
|
//Call bound version of do_callbacks
|
||||||
chai("do_callbacks()");
|
chai("do_callbacks()");
|
||||||
@@ -143,6 +143,14 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
log("Functor test output", boost::lexical_cast<std::string>(x));
|
log("Functor test output", boost::lexical_cast<std::string>(x));
|
||||||
|
|
||||||
|
chai.add(var(boost::shared_ptr<int>()), "nullvar");
|
||||||
|
chai("print(\"This should be true.\"); print(nullvar.is_null())");
|
||||||
|
|
||||||
|
// test the global const action
|
||||||
|
chai.add_global_const(const_var(1), "constvar");
|
||||||
|
chai("def getvar() { return constvar; }");
|
||||||
|
chai("print( getvar() )");
|
||||||
|
|
||||||
|
|
||||||
//Ability to create our own container types when needed. std::vector and std::map are
|
//Ability to create our own container types when needed. std::vector and std::map are
|
||||||
//mostly supported currently
|
//mostly supported currently
|
||||||
|
7
unittests/classification.chai
Normal file
7
unittests/classification.chai
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
print(1.is_var_const());
|
||||||
|
print(1.is_var_reference());
|
||||||
|
print(1.is_var_pointer());
|
||||||
|
print(1.is_var_null());
|
||||||
|
print(1.is_var_undef());
|
||||||
|
var i;
|
||||||
|
print(i.is_var_undef());
|
6
unittests/classification.txt
Normal file
6
unittests/classification.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
true
|
||||||
|
false
|
||||||
|
true
|
||||||
|
false
|
||||||
|
false
|
||||||
|
true
|
@@ -1 +1 @@
|
|||||||
Error: "Mismatched types in equation" in 'unittests/invalid_function_assignment.chai' at (1, 7)
|
Error: "Mismatched types in equation, lhs is const." in 'unittests/invalid_function_assignment.chai' at (1, 7)
|
||||||
|
@@ -1 +1 @@
|
|||||||
Error: "Mismatched types in equation" in 'unittests/invalid_function_reassignment.chai' at (2, 3)
|
Error: "Mismatched types in equation." in 'unittests/invalid_function_reassignment.chai' at (2, 3)
|
||||||
|
4
unittests/is_undef.chai
Normal file
4
unittests/is_undef.chai
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var i;
|
||||||
|
print(i.is_var_undef());
|
||||||
|
i = 5;
|
||||||
|
print(i.is_var_undef());
|
2
unittests/is_undef.txt
Normal file
2
unittests/is_undef.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
true
|
||||||
|
false
|
15
unittests/operators_float.chai
Normal file
15
unittests/operators_float.chai
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
var i = 1.0;
|
||||||
|
var j = 2.0;
|
||||||
|
var k = 3.0;
|
||||||
|
|
||||||
|
print(i + j);
|
||||||
|
print(+i);
|
||||||
|
print(i - j);
|
||||||
|
print(-i);
|
||||||
|
print(k / j);
|
||||||
|
print(j * k);
|
||||||
|
|
||||||
|
print(i -= 1);
|
||||||
|
print(j *= 1.5);
|
||||||
|
print(j /= 2);
|
||||||
|
print(j += 1);
|
10
unittests/operators_float.txt
Normal file
10
unittests/operators_float.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
3
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
1.5
|
||||||
|
6
|
||||||
|
0
|
||||||
|
3
|
||||||
|
1.5
|
||||||
|
2.5
|
32
unittests/operators_int.chai
Normal file
32
unittests/operators_int.chai
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
var i = 1;
|
||||||
|
var j = 2;
|
||||||
|
var k = 3;
|
||||||
|
|
||||||
|
print(i + j);
|
||||||
|
print(+i);
|
||||||
|
print(i - j);
|
||||||
|
print(-i);
|
||||||
|
print(j & k);
|
||||||
|
print(~j);
|
||||||
|
print(j ^ k);
|
||||||
|
print(i | j);
|
||||||
|
print(j / i);
|
||||||
|
print(i << j);
|
||||||
|
print(j * k);
|
||||||
|
print(k % j);
|
||||||
|
print(j >> i);
|
||||||
|
|
||||||
|
print(i &= 2);
|
||||||
|
print(j ^= 3);
|
||||||
|
print(j |= 2);
|
||||||
|
print(i -= 1);
|
||||||
|
print(j <<= 1);
|
||||||
|
print(j *= 2);
|
||||||
|
print(j /= 2);
|
||||||
|
print(j %= 4);
|
||||||
|
print(j >>= 1);
|
||||||
|
print(j += 1);
|
||||||
|
print(--j);
|
||||||
|
print(++j);
|
||||||
|
|
||||||
|
|
25
unittests/operators_int.txt
Normal file
25
unittests/operators_int.txt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
3
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
2
|
||||||
|
-3
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
4
|
||||||
|
6
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
3
|
||||||
|
-1
|
||||||
|
6
|
||||||
|
12
|
||||||
|
6
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
10
unittests/type_info.chai
Normal file
10
unittests/type_info.chai
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
print(string_type.name());
|
||||||
|
print(string_type.is_type_const());
|
||||||
|
print(string_type.is_type_reference());
|
||||||
|
print(string_type.is_type_void());
|
||||||
|
print(string_type.is_type_undef());
|
||||||
|
print(string_type.is_type_pointer());
|
||||||
|
print("string".get_type_info().name());
|
||||||
|
print(string_type.bare_equal("string".get_type_info()));
|
||||||
|
|
||||||
|
print("bob".is_type(string_type));
|
9
unittests/type_info.txt
Normal file
9
unittests/type_info.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
string
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
string
|
||||||
|
true
|
||||||
|
true
|
Reference in New Issue
Block a user