Compare commits
20 Commits
v1.1.0
...
Release-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3a951cea99 | ||
![]() |
8620f4eaf9 | ||
![]() |
59ecf32f9b | ||
![]() |
541e453098 | ||
![]() |
0b780593a6 | ||
![]() |
2e7c5f413e | ||
![]() |
7e5b7cbd7a | ||
![]() |
c539e0b458 | ||
![]() |
1f011f3d5b | ||
![]() |
a136236179 | ||
![]() |
8840f06053 | ||
![]() |
00e4de774f | ||
![]() |
bc3a17b3b7 | ||
![]() |
4a57efde25 | ||
![]() |
cf94817869 | ||
![]() |
6775863415 | ||
![]() |
a3d4b6698a | ||
![]() |
0ff107a818 | ||
![]() |
ba6b392174 | ||
![]() |
5b424be4ed |
@@ -19,5 +19,7 @@ if (Boost_FOUND)
|
|||||||
#add_executable(dispatchkit_test contrib/test/dispatchkit_test.cpp)
|
#add_executable(dispatchkit_test contrib/test/dispatchkit_test.cpp)
|
||||||
target_link_libraries(chaiscript_eval ${Boost_LIBRARIES})
|
target_link_libraries(chaiscript_eval ${Boost_LIBRARIES})
|
||||||
install(TARGETS chaiscript_eval DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin)
|
install(TARGETS chaiscript_eval DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin)
|
||||||
|
else(Boost_FOUND)
|
||||||
|
message(FATAL_ERROR "Can not find Boost")
|
||||||
endif(Boost_FOUND)
|
endif(Boost_FOUND)
|
||||||
|
|
||||||
|
@@ -87,7 +87,8 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
struct Eval_Error : public std::runtime_error {
|
struct Eval_Error : public std::runtime_error {
|
||||||
std::string reason;
|
std::string reason;
|
||||||
File_Position position;
|
File_Position start_position;
|
||||||
|
File_Position end_position;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
|
||||||
Eval_Error(const std::string &why, const File_Position &where, const char *fname) :
|
Eval_Error(const std::string &why, const File_Position &where, const char *fname) :
|
||||||
@@ -95,7 +96,7 @@ namespace chaiscript
|
|||||||
(std::string(fname) != "__EVAL__" ? ("in '" + std::string(fname) + "' ") : "during evaluation ") +
|
(std::string(fname) != "__EVAL__" ? ("in '" + std::string(fname) + "' ") : "during evaluation ") +
|
||||||
+ "at (" + boost::lexical_cast<std::string>(where.line) + ", " +
|
+ "at (" + boost::lexical_cast<std::string>(where.line) + ", " +
|
||||||
boost::lexical_cast<std::string>(where.column) + ")"),
|
boost::lexical_cast<std::string>(where.column) + ")"),
|
||||||
reason(why), position(where), filename(fname)
|
reason(why), start_position(where), end_position(where), filename(fname)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Eval_Error(const std::string &why, const TokenPtr &where)
|
Eval_Error(const std::string &why, const TokenPtr &where)
|
||||||
@@ -103,7 +104,7 @@ namespace chaiscript
|
|||||||
(std::string(where->filename) != "__EVAL__" ? ("in '" + std::string(where->filename) + "' ") : "during evaluation ") +
|
(std::string(where->filename) != "__EVAL__" ? ("in '" + std::string(where->filename) + "' ") : "during evaluation ") +
|
||||||
"at (" + boost::lexical_cast<std::string>(where->start.line) + ", " +
|
"at (" + boost::lexical_cast<std::string>(where->start.line) + ", " +
|
||||||
boost::lexical_cast<std::string>(where->start.column) + ")"),
|
boost::lexical_cast<std::string>(where->start.column) + ")"),
|
||||||
reason(why), position(where->start), filename(where->filename) {
|
reason(why), start_position(where->start), end_position(where->end), filename(where->filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Eval_Error() throw() {}
|
virtual ~Eval_Error() throw() {}
|
||||||
|
@@ -635,7 +635,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
Proxy_Function f = boxed_cast<Proxy_Function >(params[0]);
|
Proxy_Function f = boxed_cast<Proxy_Function >(params[0]);
|
||||||
|
|
||||||
return Boxed_Value(f->types_match(std::vector<Boxed_Value>(params.begin() + 1, params.end())));
|
return Boxed_Value(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end())));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::shared_ptr<Dispatch_Engine> bootstrap2(boost::shared_ptr<Dispatch_Engine> e = boost::shared_ptr<Dispatch_Engine> (new Dispatch_Engine()))
|
static boost::shared_ptr<Dispatch_Engine> bootstrap2(boost::shared_ptr<Dispatch_Engine> e = boost::shared_ptr<Dispatch_Engine> (new Dispatch_Engine()))
|
||||||
|
@@ -203,10 +203,10 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
assignable_type<ContainerType>(type, m);
|
assignable_type<ContainerType>(type, m);
|
||||||
|
|
||||||
m->add(fun(&ContainerType::size), "size");
|
m->add(fun<size_t (ContainerType::*)() const>(&ContainerType::size), "size");
|
||||||
m->add(fun(&ContainerType::max_size), "max_size");
|
m->add(fun<size_t (ContainerType::*)() const>(&ContainerType::max_size), "max_size");
|
||||||
m->add(fun(&ContainerType::empty), "empty");
|
m->add(fun<bool (ContainerType::*)() const>(&ContainerType::empty), "empty");
|
||||||
m->add(fun(&ContainerType::clear), "clear");
|
m->add(fun<void (ContainerType::*)()>(&ContainerType::clear), "clear");
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ namespace chaiscript
|
|||||||
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);
|
associative_container_type<ContainerType>(type, m);
|
||||||
m->add(fun(&ContainerType::count), "count");
|
m->add(fun<size_t (ContainerType::*)(const typename ContainerType::key_type &) const>(&ContainerType::count), "count");
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@@ -97,11 +97,6 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_false()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -116,10 +111,15 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
struct Object_Cache
|
struct Object_Cache
|
||||||
{
|
{
|
||||||
|
Object_Cache()
|
||||||
|
: m_cullcount(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Data> get(Boxed_Value::Void_Type)
|
boost::shared_ptr<Data> get(Boxed_Value::Void_Type)
|
||||||
{
|
{
|
||||||
return boost::shared_ptr<Data> (new Data(
|
return boost::shared_ptr<Data> (new Data(
|
||||||
Get_Type_Info<void>::get(),
|
detail::Get_Type_Info<void>::get(),
|
||||||
boost::any(),
|
boost::any(),
|
||||||
false)
|
false)
|
||||||
);
|
);
|
||||||
@@ -135,7 +135,7 @@ namespace chaiscript
|
|||||||
boost::shared_ptr<Data> get(const boost::shared_ptr<T> &obj)
|
boost::shared_ptr<Data> get(const boost::shared_ptr<T> &obj)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Data> data(new Data(
|
boost::shared_ptr<Data> data(new Data(
|
||||||
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>()))
|
boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>()))
|
||||||
@@ -164,7 +164,7 @@ namespace chaiscript
|
|||||||
boost::shared_ptr<Data> get(boost::reference_wrapper<T> obj)
|
boost::shared_ptr<Data> get(boost::reference_wrapper<T> obj)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Data> data(new Data(
|
boost::shared_ptr<Data> data(new Data(
|
||||||
Get_Type_Info<T>::get(),
|
detail::Get_Type_Info<T>::get(),
|
||||||
boost::any(obj),
|
boost::any(obj),
|
||||||
true)
|
true)
|
||||||
);
|
);
|
||||||
@@ -192,7 +192,7 @@ namespace chaiscript
|
|||||||
boost::shared_ptr<Data> get(const T& t)
|
boost::shared_ptr<Data> get(const T& t)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Data> data(new Data(
|
boost::shared_ptr<Data> data(new Data(
|
||||||
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>()))
|
boost::shared_ptr<Data::Shared_Ptr_Proxy>(new Data::Shared_Ptr_Proxy_Impl<T>()))
|
||||||
@@ -219,6 +219,12 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void cull()
|
void cull()
|
||||||
{
|
{
|
||||||
|
++m_cullcount;
|
||||||
|
if (m_cullcount % 10 != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<const void *, Data >::iterator itr = m_ptrs.begin();
|
std::map<const void *, Data >::iterator itr = m_ptrs.begin();
|
||||||
|
|
||||||
while (itr != m_ptrs.end())
|
while (itr != m_ptrs.end())
|
||||||
@@ -235,6 +241,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::map<const void *, Data > m_ptrs;
|
std::map<const void *, Data > m_ptrs;
|
||||||
|
int m_cullcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -324,175 +331,178 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Cast_Helper helper classes
|
namespace detail
|
||||||
|
{
|
||||||
|
// Cast_Helper helper classes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic Cast_Helper, for casting to any type
|
* Generic Cast_Helper, for casting to any type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper
|
struct Cast_Helper
|
||||||
{
|
|
||||||
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().m_is_const)
|
if (ob.is_ref())
|
||||||
{
|
{
|
||||||
return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
|
if (!ob.get_type_info().m_is_const)
|
||||||
|
{
|
||||||
|
return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
|
||||||
|
} else {
|
||||||
|
return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get());
|
return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a const & type
|
* Cast_Helper for casting to a const & type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const Result &>
|
struct Cast_Helper<const Result &>
|
||||||
{
|
|
||||||
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().m_is_const)
|
if (ob.is_ref())
|
||||||
{
|
{
|
||||||
return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
|
if (!ob.get_type_info().m_is_const)
|
||||||
|
{
|
||||||
|
return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
|
||||||
|
} else {
|
||||||
|
return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get());
|
return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a const * type
|
* Cast_Helper for casting to a const * type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const Result *>
|
struct Cast_Helper<const Result *>
|
||||||
{
|
|
||||||
typedef const Result * Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
typedef const Result * Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().m_is_const)
|
if (ob.is_ref())
|
||||||
|
{
|
||||||
|
if (!ob.get_type_info().m_is_const)
|
||||||
|
{
|
||||||
|
return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
|
||||||
|
} else {
|
||||||
|
return (boost::any_cast<boost::reference_wrapper<const Result> >(ob.get())).get_pointer();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a * type
|
||||||
|
*/
|
||||||
|
template<typename Result>
|
||||||
|
struct Cast_Helper<Result *>
|
||||||
|
{
|
||||||
|
typedef Result * Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
if (ob.is_ref())
|
||||||
{
|
{
|
||||||
return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
|
return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
|
||||||
} else {
|
} else {
|
||||||
return (boost::any_cast<boost::reference_wrapper<const Result> >(ob.get())).get_pointer();
|
return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a * type
|
* Cast_Helper for casting to a & type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<Result *>
|
struct Cast_Helper<Result &>
|
||||||
{
|
|
||||||
typedef Result * Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
typedef typename boost::reference_wrapper<Result> Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
{
|
{
|
||||||
return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
|
if (ob.is_ref())
|
||||||
} else {
|
{
|
||||||
return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
|
return boost::any_cast<boost::reference_wrapper<Result> >(ob.get());
|
||||||
|
} else {
|
||||||
|
return boost::ref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a & type
|
* Cast_Helper for casting to a boost::shared_ptr<> type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<Result &>
|
struct Cast_Helper<typename boost::shared_ptr<Result> >
|
||||||
{
|
|
||||||
typedef typename boost::reference_wrapper<Result> Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
typedef typename boost::shared_ptr<Result> Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
{
|
{
|
||||||
return boost::any_cast<boost::reference_wrapper<Result> >(ob.get());
|
return boost::any_cast<boost::shared_ptr<Result> >(ob.get());
|
||||||
} else {
|
|
||||||
return boost::ref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a boost::shared_ptr<> type
|
* Cast_Helper for casting to a boost::shared_ptr<> type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<typename boost::shared_ptr<Result> >
|
struct Cast_Helper<const boost::shared_ptr<Result> &>
|
||||||
{
|
|
||||||
typedef typename boost::shared_ptr<Result> Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
return boost::any_cast<boost::shared_ptr<Result> >(ob.get());
|
typedef typename boost::shared_ptr<Result> Result_Type;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
* Cast_Helper for casting to a boost::shared_ptr<> type
|
{
|
||||||
*/
|
return boost::any_cast<boost::shared_ptr<Result> >(ob.get());
|
||||||
template<typename Result>
|
}
|
||||||
struct Cast_Helper<const boost::shared_ptr<Result> &>
|
};
|
||||||
{
|
|
||||||
typedef typename boost::shared_ptr<Result> Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a Boxed_Value type
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Cast_Helper<Boxed_Value>
|
||||||
{
|
{
|
||||||
return boost::any_cast<boost::shared_ptr<Result> >(ob.get());
|
typedef const Boxed_Value & Result_Type;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
return ob;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* Cast_Helper for casting to a const Boxed_Value & type
|
||||||
* Cast_Helper for casting to a Boxed_Value type
|
*/
|
||||||
*/
|
template<>
|
||||||
template<>
|
struct Cast_Helper<const Boxed_Value &>
|
||||||
struct Cast_Helper<Boxed_Value>
|
|
||||||
{
|
|
||||||
typedef Boxed_Value Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
return ob;
|
typedef const Boxed_Value & Result_Type;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
* Cast_Helper for casting to a const Boxed_Value & type
|
{
|
||||||
*/
|
return ob;
|
||||||
template<>
|
}
|
||||||
struct Cast_Helper<const Boxed_Value &>
|
};
|
||||||
{
|
}
|
||||||
typedef Boxed_Value Result_Type;
|
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
|
||||||
return ob;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class that is thrown in the event of a bad_boxed_cast. That is,
|
* class that is thrown in the event of a bad_boxed_cast. That is,
|
||||||
@@ -530,10 +540,10 @@ namespace chaiscript
|
|||||||
* int &i = boxed_cast<int &>(boxedvalue);
|
* int &i = boxed_cast<int &>(boxedvalue);
|
||||||
*/
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
typename Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv)
|
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return Cast_Helper<Type>::cast(bv);
|
return detail::Cast_Helper<Type>::cast(bv);
|
||||||
} catch (const boost::bad_any_cast &) {
|
} catch (const boost::bad_any_cast &) {
|
||||||
throw bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
throw bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||||
}
|
}
|
||||||
@@ -669,19 +679,22 @@ namespace chaiscript
|
|||||||
bool m_isfloat;
|
bool m_isfloat;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
namespace detail
|
||||||
* Cast_Helper for converting from Boxed_Value to Boxed_POD_Value
|
{
|
||||||
*/
|
/**
|
||||||
template<>
|
* Cast_Helper for converting from Boxed_Value to Boxed_POD_Value
|
||||||
struct Cast_Helper<Boxed_POD_Value>
|
*/
|
||||||
{
|
template<>
|
||||||
typedef Boxed_POD_Value Result_Type;
|
struct Cast_Helper<Boxed_POD_Value>
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
|
||||||
{
|
{
|
||||||
return Boxed_POD_Value(ob);
|
typedef Boxed_POD_Value Result_Type;
|
||||||
}
|
|
||||||
};
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
return Boxed_POD_Value(ob);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Boxed_Value var(T t)
|
Boxed_Value var(T t)
|
||||||
@@ -690,7 +703,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the two Boxed_Value's share the same internal type
|
* Return true if the two Boxed_Values share the same internal type
|
||||||
*/
|
*/
|
||||||
static bool type_match(Boxed_Value l, Boxed_Value r)
|
static bool type_match(Boxed_Value l, Boxed_Value r)
|
||||||
{
|
{
|
||||||
|
@@ -94,7 +94,12 @@ namespace chaiscript
|
|||||||
return std::vector<Type_Info>();
|
return std::vector<Type_Info>();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool types_match(const std::vector<Boxed_Value> &types) const
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
{
|
{
|
||||||
typedef std::vector<std::pair<std::string, Proxy_Function > > function_vec;
|
typedef std::vector<std::pair<std::string, Proxy_Function > > function_vec;
|
||||||
|
|
||||||
@@ -103,7 +108,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
if (begin->second->types_match(types))
|
if (begin->second->call_match(vals))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -124,6 +129,23 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown in the case that a multi method dispatch fails
|
||||||
|
* because no matching function was found
|
||||||
|
* at runtime due to either an arity_error, a guard_error or a bad_boxed_cast
|
||||||
|
* exception
|
||||||
|
*/
|
||||||
|
struct reserved_word_error : std::runtime_error
|
||||||
|
{
|
||||||
|
reserved_word_error(const std::string &word) throw()
|
||||||
|
: std::runtime_error("Reserved word not allowed in object name: " + word)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~reserved_word_error() throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class for the dispatchkit. Handles management
|
* Main class for the dispatchkit. Handles management
|
||||||
* of the object stack, functions and registered types.
|
* of the object stack, functions and registered types.
|
||||||
@@ -133,12 +155,13 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
typedef std::map<std::string, chaiscript::Type_Info> Type_Name_Map;
|
typedef std::map<std::string, chaiscript::Type_Info> Type_Name_Map;
|
||||||
typedef std::map<std::string, Boxed_Value> Scope;
|
typedef std::map<std::string, Boxed_Value> Scope;
|
||||||
typedef std::deque<Scope> Stack;
|
typedef boost::shared_ptr<std::deque<Scope> > Stack;
|
||||||
|
|
||||||
Dispatch_Engine()
|
Dispatch_Engine()
|
||||||
: m_place_holder(boost::shared_ptr<Placeholder_Object>(new Placeholder_Object()))
|
: m_scopes(new Stack::element_type()),
|
||||||
|
m_place_holder(boost::shared_ptr<Placeholder_Object>(new Placeholder_Object()))
|
||||||
{
|
{
|
||||||
m_scopes.push_back(Scope());
|
m_scopes->push_back(Scope());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -146,6 +169,7 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool add(const Proxy_Function &f, const std::string &name)
|
bool add(const Proxy_Function &f, const std::string &name)
|
||||||
{
|
{
|
||||||
|
validate_object_name(name);
|
||||||
return add_function(f, name);
|
return add_function(f, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,12 +187,13 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void add(const Boxed_Value &obj, const std::string &name)
|
void add(const Boxed_Value &obj, const std::string &name)
|
||||||
{
|
{
|
||||||
for (int i = m_scopes.size()-1; i >= 0; --i)
|
validate_object_name(name);
|
||||||
|
for (int i = m_scopes->size()-1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
|
std::map<std::string, Boxed_Value>::const_iterator itr = (*m_scopes)[i].find(name);
|
||||||
if (itr != m_scopes[i].end())
|
if (itr != (*m_scopes)[i].end())
|
||||||
{
|
{
|
||||||
m_scopes[i][name] = Boxed_Value(obj);
|
(*m_scopes)[i][name] = Boxed_Value(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +206,8 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void add_object(const std::string &name, const Boxed_Value &obj)
|
void add_object(const std::string &name, const Boxed_Value &obj)
|
||||||
{
|
{
|
||||||
m_scopes.back()[name] = Boxed_Value(obj);
|
validate_object_name(name);
|
||||||
|
m_scopes->back()[name] = Boxed_Value(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,7 +215,7 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void new_scope()
|
void new_scope()
|
||||||
{
|
{
|
||||||
m_scopes.push_back(Scope());
|
m_scopes->push_back(Scope());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,9 +223,9 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void pop_scope()
|
void pop_scope()
|
||||||
{
|
{
|
||||||
if (m_scopes.size() > 1)
|
if (m_scopes->size() > 1)
|
||||||
{
|
{
|
||||||
m_scopes.pop_back();
|
m_scopes->pop_back();
|
||||||
} else {
|
} else {
|
||||||
throw std::range_error("Unable to pop global stack");
|
throw std::range_error("Unable to pop global stack");
|
||||||
}
|
}
|
||||||
@@ -218,10 +244,16 @@ namespace chaiscript
|
|||||||
* \returns the old stack
|
* \returns the old stack
|
||||||
* \param[in] s The new stack
|
* \param[in] s The new stack
|
||||||
*/
|
*/
|
||||||
Stack set_stack(Stack s)
|
Stack set_stack(const Stack &s)
|
||||||
{
|
{
|
||||||
std::swap(s, m_scopes);
|
Stack old = m_scopes;
|
||||||
return s;
|
m_scopes = s;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stack new_stack()
|
||||||
|
{
|
||||||
|
return Stack(new Stack::element_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,16 +268,16 @@ namespace chaiscript
|
|||||||
return m_place_holder;
|
return m_place_holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = m_scopes.size()-1; i >= 0; --i)
|
for (int i = m_scopes->size()-1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
|
std::map<std::string, Boxed_Value>::const_iterator itr = (*m_scopes)[i].find(name);
|
||||||
if (itr != m_scopes[i].end())
|
if (itr != (*m_scopes)[i].end())
|
||||||
{
|
{
|
||||||
return itr->second;
|
return itr->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::multimap<std::string, Proxy_Function >::mapped_type> > funcs = get_function_impl(name, false);
|
std::vector<std::pair<std::string, std::multimap<std::string, Proxy_Function >::mapped_type> > funcs = get_function(name);
|
||||||
|
|
||||||
if (funcs.empty())
|
if (funcs.empty())
|
||||||
{
|
{
|
||||||
@@ -309,10 +341,21 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* Return a function by name
|
* Return a function by name
|
||||||
*/
|
*/
|
||||||
std::vector<std::pair<std::string, std::multimap<std::string, Proxy_Function >::mapped_type> >
|
std::vector<std::pair<std::string, std::multimap<std::string, Proxy_Function >::mapped_type> >
|
||||||
get_function(const std::string &t_name) const
|
get_function(const std::string &t_name) const
|
||||||
{
|
{
|
||||||
return get_function_impl(t_name, true);
|
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);
|
||||||
|
|
||||||
|
return std::vector<std::pair<std::string, std::multimap<std::string, Proxy_Function >::mapped_type> >(range.first, range.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if a function exists
|
||||||
|
*/
|
||||||
|
bool function_exists(const std::string &name) const
|
||||||
|
{
|
||||||
|
return m_functions.find(name) != m_functions.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -323,35 +366,22 @@ namespace chaiscript
|
|||||||
return std::vector<std::pair<std::string, Proxy_Function > >(m_functions.begin(), m_functions.end());
|
return std::vector<std::pair<std::string, Proxy_Function > >(m_functions.begin(), m_functions.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_reserved_word(const std::string &name)
|
||||||
|
{
|
||||||
|
m_reserved_words.insert(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Implementation detail for searching for a function by name.
|
* Throw a reserved_word exception if the name is not allowed
|
||||||
* Looks for all registered global functions and optionally for an object
|
|
||||||
* in scope with the same name
|
|
||||||
*/
|
*/
|
||||||
std::vector<std::pair<std::string, std::multimap<std::string, Proxy_Function >::mapped_type> >
|
void validate_object_name(const std::string &name)
|
||||||
get_function_impl(const std::string &t_name, bool include_objects) const
|
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, std::multimap<std::string, Proxy_Function >::mapped_type> > funcs;
|
if (m_reserved_words.find(name) != m_reserved_words.end())
|
||||||
|
|
||||||
if (include_objects)
|
|
||||||
{
|
{
|
||||||
try {
|
throw reserved_word_error(name);
|
||||||
funcs.insert(funcs.end(),
|
|
||||||
std::make_pair(
|
|
||||||
t_name,
|
|
||||||
boxed_cast<std::multimap<std::string, Proxy_Function >::mapped_type>(get_object(t_name)))
|
|
||||||
);
|
|
||||||
} catch (const bad_boxed_cast &) {
|
|
||||||
} catch (const std::range_error &) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
funcs.insert(funcs.end(), range.first, range.second);
|
|
||||||
return funcs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -377,11 +407,12 @@ namespace chaiscript
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::deque<Scope> m_scopes;
|
Stack m_scopes;
|
||||||
|
|
||||||
std::multimap<std::string, Proxy_Function > m_functions;
|
std::multimap<std::string, Proxy_Function > m_functions;
|
||||||
Type_Name_Map m_types;
|
Type_Name_Map m_types;
|
||||||
Boxed_Value m_place_holder;
|
Boxed_Value m_place_holder;
|
||||||
|
std::set<std::string> m_reserved_words;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -4,13 +4,6 @@
|
|||||||
// and Jason Turner (lefticus@gmail.com)
|
// and Jason Turner (lefticus@gmail.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#include <boost/preprocessor.hpp>
|
|
||||||
|
|
||||||
#define addparam(z,n,text) params.push_back(boost::is_reference<Param ## n>::value?Boxed_Value(boost::ref(BOOST_PP_CAT(p, n))):Boxed_Value(BOOST_PP_CAT(p, n) ));
|
|
||||||
#define curry(z,n,text) BOOST_PP_CAT(_, BOOST_PP_INC(n))
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BOOST_PP_IS_ITERATING
|
|
||||||
#ifndef __function_call_hpp__
|
#ifndef __function_call_hpp__
|
||||||
#define __function_call_hpp__
|
#define __function_call_hpp__
|
||||||
|
|
||||||
@@ -20,50 +13,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
|
#include "function_call_detail.hpp"
|
||||||
namespace chaiscript
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Internal helper class for handling the return
|
|
||||||
* value of a build_function_caller
|
|
||||||
*/
|
|
||||||
template<typename Ret>
|
|
||||||
class Function_Caller_Ret
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Function_Caller_Ret()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Ret call(const std::vector<std::pair<std::string, Proxy_Function > > &t_funcs,
|
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
|
||||||
return boxed_cast<Ret>(dispatch(t_funcs, params));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specialization for void return types
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
class Function_Caller_Ret<void>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Function_Caller_Ret()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void call(const std::vector<std::pair<std::string, Proxy_Function > > &t_funcs,
|
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
|
||||||
dispatch(t_funcs, params);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BOOST_PP_ITERATION_LIMITS ( 0, 9 )
|
|
||||||
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/function_call.hpp>
|
|
||||||
#include BOOST_PP_ITERATE()
|
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -80,7 +30,7 @@ namespace chaiscript
|
|||||||
functor(const std::vector<std::pair<std::string, Proxy_Function > > &funcs)
|
functor(const std::vector<std::pair<std::string, Proxy_Function > > &funcs)
|
||||||
{
|
{
|
||||||
FunctionType *p=0;
|
FunctionType *p=0;
|
||||||
return build_function_caller_helper(p, funcs);
|
return detail::build_function_caller_helper(p, funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,39 +68,5 @@ namespace chaiscript
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define n BOOST_PP_ITERATION()
|
|
||||||
|
|
||||||
namespace chaiscript
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* used internally for unwrapping a function call's types
|
|
||||||
*/
|
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
|
||||||
Ret function_caller(const std::vector<std::pair<std::string, Proxy_Function > > &funcs
|
|
||||||
BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
|
|
||||||
{
|
|
||||||
std::vector<Boxed_Value> params;
|
|
||||||
|
|
||||||
BOOST_PP_REPEAT(n, addparam, ~)
|
|
||||||
|
|
||||||
return Function_Caller_Ret<Ret>().call(funcs, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* used internally for unwrapping a function call's types
|
|
||||||
*/
|
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
|
||||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param)) >
|
|
||||||
build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector<std::pair<std::string, Proxy_Function> > &funcs)
|
|
||||||
{
|
|
||||||
return boost::bind(&function_caller<Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param)>, funcs
|
|
||||||
BOOST_PP_ENUM_TRAILING(n, curry, ~));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
98
include/chaiscript/dispatchkit/function_call_detail.hpp
Normal file
98
include/chaiscript/dispatchkit/function_call_detail.hpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009, Jonathan Turner (jturner@minnow-lang.org)
|
||||||
|
// and Jason Turner (lefticus@gmail.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#include <boost/preprocessor.hpp>
|
||||||
|
|
||||||
|
#define addparam(z,n,text) params.push_back(boost::is_reference<Param ## n>::value?Boxed_Value(boost::ref(BOOST_PP_CAT(p, n))):Boxed_Value(BOOST_PP_CAT(p, n) ));
|
||||||
|
#define curry(z,n,text) BOOST_PP_CAT(_, BOOST_PP_INC(n))
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BOOST_PP_IS_ITERATING
|
||||||
|
#ifndef __function_call_detail_hpp__
|
||||||
|
#define __function_call_detail_hpp__
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "proxy_functions.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Internal helper class for handling the return
|
||||||
|
* value of a build_function_caller
|
||||||
|
*/
|
||||||
|
template<typename Ret>
|
||||||
|
struct Function_Caller_Ret
|
||||||
|
{
|
||||||
|
static Ret call(const std::vector<std::pair<std::string, Proxy_Function > > &t_funcs,
|
||||||
|
const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
return boxed_cast<Ret>(dispatch(t_funcs, params));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialization for void return types
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Function_Caller_Ret<void>
|
||||||
|
{
|
||||||
|
static void call(const std::vector<std::pair<std::string, Proxy_Function > > &t_funcs,
|
||||||
|
const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
dispatch(t_funcs, params);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_PP_ITERATION_LIMITS ( 0, 9 )
|
||||||
|
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/function_call_detail.hpp>
|
||||||
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define n BOOST_PP_ITERATION()
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* used internally for unwrapping a function call's types
|
||||||
|
*/
|
||||||
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
|
Ret function_caller(const std::vector<std::pair<std::string, Proxy_Function > > &funcs
|
||||||
|
BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
|
||||||
|
{
|
||||||
|
std::vector<Boxed_Value> params;
|
||||||
|
|
||||||
|
BOOST_PP_REPEAT(n, addparam, ~)
|
||||||
|
|
||||||
|
return Function_Caller_Ret<Ret>::call(funcs, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used internally for unwrapping a function call's types
|
||||||
|
*/
|
||||||
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
|
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param)) >
|
||||||
|
build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector<std::pair<std::string, Proxy_Function> > &funcs)
|
||||||
|
{
|
||||||
|
return boost::bind(&function_caller<Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param)>, funcs
|
||||||
|
BOOST_PP_ENUM_TRAILING(n, curry, ~));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
100
include/chaiscript/dispatchkit/handle_return.hpp
Normal file
100
include/chaiscript/dispatchkit/handle_return.hpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009, Jonathan Turner (jturner@minnow-lang.org)
|
||||||
|
// and Jason Turner (lefticus@gmail.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef __handle_return_hpp__
|
||||||
|
#define __handle_return_hpp__
|
||||||
|
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return
|
||||||
|
{
|
||||||
|
static Boxed_Value call(const boost::function<Ret ()> &f)
|
||||||
|
{
|
||||||
|
return Boxed_Value(f());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return<boost::shared_ptr<Ret> &>
|
||||||
|
{
|
||||||
|
static Boxed_Value call(const boost::function<boost::shared_ptr<Ret> & ()> &f)
|
||||||
|
{
|
||||||
|
return Boxed_Value(f());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return<const boost::shared_ptr<Ret> &>
|
||||||
|
{
|
||||||
|
static Boxed_Value call(const boost::function<const boost::shared_ptr<Ret> & ()> &f)
|
||||||
|
{
|
||||||
|
return Boxed_Value(f());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return<Ret &>
|
||||||
|
{
|
||||||
|
static Boxed_Value call(const boost::function<Ret &()> &f)
|
||||||
|
{
|
||||||
|
return Boxed_Value(boost::ref(f()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Handle_Return<Boxed_Value>
|
||||||
|
{
|
||||||
|
static Boxed_Value call(const boost::function<Boxed_Value ()> &f)
|
||||||
|
{
|
||||||
|
return f();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Handle_Return<Boxed_Value &>
|
||||||
|
{
|
||||||
|
static Boxed_Value call(const boost::function<Boxed_Value &()> &f)
|
||||||
|
{
|
||||||
|
return f();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Handle_Return<void>
|
||||||
|
{
|
||||||
|
static Boxed_Value call(const boost::function<void ()> &f)
|
||||||
|
{
|
||||||
|
f();
|
||||||
|
return Boxed_Value(Boxed_Value::Void_Type());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -26,7 +26,7 @@ namespace chaiscript
|
|||||||
Proxy_Function constructor()
|
Proxy_Function constructor()
|
||||||
{
|
{
|
||||||
T *f = 0;
|
T *f = 0;
|
||||||
return (build_constructor_(f));
|
return (detail::build_constructor_(f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,28 +35,31 @@ namespace chaiscript
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
/**
|
namespace detail
|
||||||
* A constructor function, used for creating a new object
|
{
|
||||||
* of a given type with a given set of params
|
/**
|
||||||
*/
|
* A constructor function, used for creating a new object
|
||||||
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
* of a given type with a given set of params
|
||||||
boost::shared_ptr<Class> constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
|
*/
|
||||||
{
|
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
return boost::shared_ptr<Class>(new Class( BOOST_PP_ENUM_PARAMS(n, p) ));
|
boost::shared_ptr<Class> constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
|
||||||
}
|
{
|
||||||
|
return boost::shared_ptr<Class>(new Class( BOOST_PP_ENUM_PARAMS(n, p) ));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for build a constructor function
|
* Helper function for build a constructor function
|
||||||
* example:
|
* example:
|
||||||
* dispatchengine.register_function(build_constructor<MyClass, int, const std::string&>, "MyClass");
|
* dispatchengine.register_function(build_constructor<MyClass, int, const std::string&>, "MyClass");
|
||||||
* \todo See if it is possible to make this not be a variadic function
|
* \todo See if it is possible to make this not be a variadic function
|
||||||
*/
|
*/
|
||||||
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
||||||
{
|
{
|
||||||
typedef boost::shared_ptr<Class> (sig)(BOOST_PP_ENUM_PARAMS(n, Param));
|
typedef boost::shared_ptr<Class> (sig)(BOOST_PP_ENUM_PARAMS(n, Param));
|
||||||
return Proxy_Function(new Proxy_Function_Impl<sig>(boost::function<sig>(&(constructor_<Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param)>))));
|
return Proxy_Function(new Proxy_Function_Impl<sig>(boost::function<sig>(&(constructor_<Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param)>))));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4,109 +4,22 @@
|
|||||||
// and Jason Turner (lefticus@gmail.com)
|
// and Jason Turner (lefticus@gmail.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#include <boost/preprocessor.hpp>
|
|
||||||
|
|
||||||
#define gettypeinfo(z,n,text) ti.push_back(Get_Type_Info<Param ## n>::get());
|
|
||||||
#define casthelper(z,n,text) ,chaiscript::boxed_cast< Param ## n >(params[n])
|
|
||||||
#define comparetype(z,n,text) && ((Get_Type_Info<Param ## n>::get() == params[n].get_type_info()))
|
|
||||||
#define trycast(z,n,text) chaiscript::boxed_cast<Param ## n>(params[n]);
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BOOST_PP_IS_ITERATING
|
|
||||||
#ifndef __proxy_functions_hpp__
|
#ifndef __proxy_functions_hpp__
|
||||||
#define __proxy_functions_hpp__
|
#define __proxy_functions_hpp__
|
||||||
|
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include "boxed_value.hpp"
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "proxy_functions_detail.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<typename Ret>
|
|
||||||
struct Handle_Return
|
|
||||||
{
|
|
||||||
Boxed_Value operator()(const boost::function<Ret ()> &f)
|
|
||||||
{
|
|
||||||
return Boxed_Value(f());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Ret>
|
|
||||||
struct Handle_Return<boost::shared_ptr<Ret> &>
|
|
||||||
{
|
|
||||||
Boxed_Value operator()(const boost::function<boost::shared_ptr<Ret> & ()> &f)
|
|
||||||
{
|
|
||||||
return Boxed_Value(f());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Ret>
|
|
||||||
struct Handle_Return<const boost::shared_ptr<Ret> &>
|
|
||||||
{
|
|
||||||
Boxed_Value operator()(const boost::function<const boost::shared_ptr<Ret> & ()> &f)
|
|
||||||
{
|
|
||||||
return Boxed_Value(f());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<typename Ret>
|
|
||||||
struct Handle_Return<Ret &>
|
|
||||||
{
|
|
||||||
Boxed_Value operator()(const boost::function<Ret &()> &f)
|
|
||||||
{
|
|
||||||
return Boxed_Value(boost::ref(f()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
struct Handle_Return<Boxed_Value>
|
|
||||||
{
|
|
||||||
Boxed_Value operator()(const boost::function<Boxed_Value ()> &f)
|
|
||||||
{
|
|
||||||
return f();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
struct Handle_Return<Boxed_Value &>
|
|
||||||
{
|
|
||||||
Boxed_Value operator()(const boost::function<Boxed_Value &()> &f)
|
|
||||||
{
|
|
||||||
return f();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
struct Handle_Return<void>
|
|
||||||
{
|
|
||||||
Boxed_Value operator()(const boost::function<void ()> &f)
|
|
||||||
{
|
|
||||||
f();
|
|
||||||
return Boxed_Value(Boxed_Value::Void_Type());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for building a list of parameters for calling a Proxy_Function
|
* Helper for building a list of parameters for calling a Proxy_Function
|
||||||
* it does automatic conversion to Boxed_Value types via operator<<
|
* it does automatic conversion to Boxed_Value types via operator<<
|
||||||
@@ -138,30 +51,6 @@ namespace chaiscript
|
|||||||
std::vector<Boxed_Value> objects;
|
std::vector<Boxed_Value> objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when there is a mismatch in number of
|
|
||||||
* parameters during Proxy_Function execution
|
|
||||||
*/
|
|
||||||
struct arity_error : std::range_error
|
|
||||||
{
|
|
||||||
arity_error(int t_got, int t_expected)
|
|
||||||
: std::range_error("Function dispatch arity mismatch"),
|
|
||||||
got(t_got), expected(t_expected)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~arity_error() throw() {}
|
|
||||||
int got;
|
|
||||||
int expected;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
|
||||||
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/proxy_functions.hpp>
|
|
||||||
#include BOOST_PP_ITERATE()
|
|
||||||
|
|
||||||
namespace chaiscript
|
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Pure virtual base class for all Proxy_Function implementations
|
* Pure virtual base class for all Proxy_Function implementations
|
||||||
* Proxy_Functions are a type erasure of type safe C++
|
* Proxy_Functions are a type erasure of type safe C++
|
||||||
@@ -177,7 +66,48 @@ namespace chaiscript
|
|||||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) = 0;
|
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) = 0;
|
||||||
virtual std::vector<Type_Info> get_param_types() const = 0;
|
virtual std::vector<Type_Info> get_param_types() const = 0;
|
||||||
virtual bool operator==(const Proxy_Function_Base &) const = 0;
|
virtual bool operator==(const Proxy_Function_Base &) const = 0;
|
||||||
virtual bool types_match(const std::vector<Boxed_Value> &types) const = 0;
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const = 0;
|
||||||
|
|
||||||
|
//! Return true if the function is a possible match
|
||||||
|
//! to the passed in values
|
||||||
|
bool filter(const std::vector<Boxed_Value> &vals) const
|
||||||
|
{
|
||||||
|
int arity = get_arity();
|
||||||
|
|
||||||
|
if (arity < 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
} else if (size_t(arity) == vals.size()) {
|
||||||
|
if (arity == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
const std::vector<Type_Info> &types = get_param_types();
|
||||||
|
|
||||||
|
if (types.size() < 2)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type_Info &ti = types[1];
|
||||||
|
|
||||||
|
if (!ti.m_bare_type_info || !(vals[0].get_type_info().m_bare_type_info)
|
||||||
|
|| (*ti.m_bare_type_info) == (*user_type<Boxed_Value>().m_bare_type_info)
|
||||||
|
|| (*ti.m_bare_type_info) == (*user_type<Boxed_POD_Value>().m_bare_type_info)
|
||||||
|
|| (*vals[0].get_type_info().m_bare_type_info) == (*ti.m_bare_type_info))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const = 0;
|
||||||
|
|
||||||
virtual std::string annotation() const = 0;
|
virtual std::string annotation() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -209,7 +139,8 @@ namespace chaiscript
|
|||||||
int t_arity=-1,
|
int t_arity=-1,
|
||||||
const std::string &t_description = "",
|
const std::string &t_description = "",
|
||||||
const Proxy_Function &t_guard = Proxy_Function())
|
const Proxy_Function &t_guard = Proxy_Function())
|
||||||
: m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard)
|
: m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard),
|
||||||
|
m_types(build_param_type_list(t_arity))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,10 +149,10 @@ namespace chaiscript
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool types_match(const std::vector<Boxed_Value> &types) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
{
|
{
|
||||||
return (m_arity < 0 || types.size() == size_t(m_arity))
|
return (m_arity < 0 || vals.size() == size_t(m_arity))
|
||||||
&& test_guard(types);
|
&& test_guard(vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dynamic_Proxy_Function() {}
|
virtual ~Dynamic_Proxy_Function() {}
|
||||||
@@ -243,23 +174,14 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return m_arity;
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::vector<Type_Info> get_param_types() const
|
virtual std::vector<Type_Info> get_param_types() const
|
||||||
{
|
{
|
||||||
std::vector<Type_Info> types;
|
return m_types;
|
||||||
|
|
||||||
types.push_back(Get_Type_Info<Boxed_Value>::get());
|
|
||||||
|
|
||||||
if (m_arity >= 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_arity; ++i)
|
|
||||||
{
|
|
||||||
types.push_back(Get_Type_Info<Boxed_Value>::get());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
types.push_back(Get_Type_Info<std::vector<Boxed_Value> >::get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return types;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const
|
||||||
@@ -284,10 +206,30 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<Type_Info> build_param_type_list(int arity)
|
||||||
|
{
|
||||||
|
std::vector<Type_Info> types;
|
||||||
|
|
||||||
|
types.push_back(detail::Get_Type_Info<Boxed_Value>::get());
|
||||||
|
|
||||||
|
if (arity >= 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < arity; ++i)
|
||||||
|
{
|
||||||
|
types.push_back(detail::Get_Type_Info<Boxed_Value>::get());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
types.push_back(detail::Get_Type_Info<std::vector<Boxed_Value> >::get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> m_f;
|
boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> m_f;
|
||||||
int m_arity;
|
int m_arity;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
Proxy_Function m_guard;
|
Proxy_Function m_guard;
|
||||||
|
std::vector<Type_Info> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,7 +251,7 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
Bound_Function(const Proxy_Function &t_f,
|
Bound_Function(const Proxy_Function &t_f,
|
||||||
const std::vector<Boxed_Value> &t_args)
|
const std::vector<Boxed_Value> &t_args)
|
||||||
: m_f(t_f), m_args(t_args)
|
: m_f(t_f), m_args(t_args), m_arity(m_f->get_arity()<0?-1:(m_f->get_arity() - m_args.size()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,10 +262,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual ~Bound_Function() {}
|
virtual ~Bound_Function() {}
|
||||||
|
|
||||||
virtual bool types_match(const std::vector<Boxed_Value> &types) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
{
|
{
|
||||||
std::vector<Boxed_Value> params = build_param_list(types);
|
return m_f->call_match(build_param_list(vals));
|
||||||
return m_f->types_match(params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
|
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
|
||||||
@@ -343,7 +284,7 @@ namespace chaiscript
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
while (barg != m_args.end()
|
while (barg != m_args.end()
|
||||||
&& !(barg->get_type_info() == Get_Type_Info<Placeholder_Object>::get()))
|
&& !(barg->get_type_info() == detail::Get_Type_Info<Placeholder_Object>::get()))
|
||||||
{
|
{
|
||||||
args.push_back(*barg);
|
args.push_back(*barg);
|
||||||
++barg;
|
++barg;
|
||||||
@@ -356,7 +297,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (barg != m_args.end()
|
if (barg != m_args.end()
|
||||||
&& barg->get_type_info() == Get_Type_Info<Placeholder_Object>::get())
|
&& barg->get_type_info() == detail::Get_Type_Info<Placeholder_Object>::get())
|
||||||
{
|
{
|
||||||
++barg;
|
++barg;
|
||||||
}
|
}
|
||||||
@@ -374,6 +315,11 @@ namespace chaiscript
|
|||||||
return std::vector<Type_Info>();
|
return std::vector<Type_Info>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return m_arity;
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
@@ -382,6 +328,7 @@ namespace chaiscript
|
|||||||
private:
|
private:
|
||||||
Proxy_Function m_f;
|
Proxy_Function m_f;
|
||||||
std::vector<Boxed_Value> m_args;
|
std::vector<Boxed_Value> m_args;
|
||||||
|
int m_arity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -394,7 +341,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Proxy_Function_Impl(const boost::function<Func> &f)
|
Proxy_Function_Impl(const boost::function<Func> &f)
|
||||||
: m_f(f)
|
: m_f(f), m_dummy_func(0), m_types(build_param_type_list(m_dummy_func))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,14 +364,18 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual std::vector<Type_Info> get_param_types() const
|
virtual std::vector<Type_Info> get_param_types() const
|
||||||
{
|
{
|
||||||
Func *f = 0;
|
return m_types;
|
||||||
return build_param_type_list(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool types_match(const std::vector<Boxed_Value> &types) const
|
virtual int get_arity() const
|
||||||
{
|
{
|
||||||
Func *f = 0;
|
return m_types.size() - 1;
|
||||||
return compare_types(f, types);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
|
{
|
||||||
|
return compare_types(m_dummy_func, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const
|
||||||
@@ -434,6 +385,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
boost::function<Func> m_f;
|
boost::function<Func> m_f;
|
||||||
|
Func *m_dummy_func;
|
||||||
|
std::vector<Type_Info> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -465,7 +418,10 @@ namespace chaiscript
|
|||||||
++itr)
|
++itr)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return (*itr->second)(plist);
|
if (itr->second->filter(plist))
|
||||||
|
{
|
||||||
|
return (*itr->second)(plist);
|
||||||
|
}
|
||||||
} catch (const bad_boxed_cast &) {
|
} catch (const bad_boxed_cast &) {
|
||||||
//parameter failed to cast, try again
|
//parameter failed to cast, try again
|
||||||
} catch (const arity_error &) {
|
} catch (const arity_error &) {
|
||||||
@@ -479,70 +435,5 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define n BOOST_PP_ITERATION()
|
|
||||||
|
|
||||||
namespace chaiscript
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to return a list of all param types
|
|
||||||
* it contains.
|
|
||||||
*/
|
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
|
||||||
std::vector<Type_Info> build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
|
||||||
{
|
|
||||||
std::vector<Type_Info> ti;
|
|
||||||
ti.push_back(Get_Type_Info<Ret>::get());
|
|
||||||
|
|
||||||
BOOST_PP_REPEAT(n, gettypeinfo, ~)
|
|
||||||
|
|
||||||
return ti;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
|
|
||||||
* The function attempts to unbox each paramter to the expected type.
|
|
||||||
* if any unboxing fails the execution of the function fails and
|
|
||||||
* the bad_boxed_cast is passed up to the caller.
|
|
||||||
*/
|
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
|
||||||
Boxed_Value call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
|
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != n)
|
|
||||||
{
|
|
||||||
throw arity_error(params.size(), n);
|
|
||||||
} else {
|
|
||||||
return Handle_Return<Ret>()(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
|
||||||
* Proxy_Function_Impl object. This function is primarly used to prevent
|
|
||||||
* registration of two functions with the exact same signatures
|
|
||||||
*/
|
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
|
||||||
bool compare_types(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)),
|
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != n)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
bool val = true BOOST_PP_REPEAT(n, comparetype, ~);
|
|
||||||
if (val) return true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
BOOST_PP_REPEAT(n, trycast, ~);
|
|
||||||
} catch (const bad_boxed_cast &) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
121
include/chaiscript/dispatchkit/proxy_functions_detail.hpp
Normal file
121
include/chaiscript/dispatchkit/proxy_functions_detail.hpp
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009, Jonathan Turner (jturner@minnow-lang.org)
|
||||||
|
// and Jason Turner (lefticus@gmail.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#include <boost/preprocessor.hpp>
|
||||||
|
|
||||||
|
#define gettypeinfo(z,n,text) ti.push_back(detail::Get_Type_Info<Param ## n>::get());
|
||||||
|
#define casthelper(z,n,text) ,chaiscript::boxed_cast< Param ## n >(params[n])
|
||||||
|
#define comparetype(z,n,text) && ((detail::Get_Type_Info<Param ## n>::get() == params[n].get_type_info()))
|
||||||
|
#define trycast(z,n,text) chaiscript::boxed_cast<Param ## n>(params[n]);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BOOST_PP_IS_ITERATING
|
||||||
|
#ifndef __proxy_functions_detail_hpp__
|
||||||
|
#define __proxy_functions_detail_hpp__
|
||||||
|
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
#include "handle_return.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Exception thrown when there is a mismatch in number of
|
||||||
|
* parameters during Proxy_Function execution
|
||||||
|
*/
|
||||||
|
struct arity_error : std::range_error
|
||||||
|
{
|
||||||
|
arity_error(int t_got, int t_expected)
|
||||||
|
: std::range_error("Function dispatch arity mismatch"),
|
||||||
|
got(t_got), expected(t_expected)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~arity_error() throw() {}
|
||||||
|
int got;
|
||||||
|
int expected;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
||||||
|
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/proxy_functions_detail.hpp>
|
||||||
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define n BOOST_PP_ITERATION()
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Used by Proxy_Function_Impl to return a list of all param types
|
||||||
|
* it contains.
|
||||||
|
*/
|
||||||
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
|
std::vector<Type_Info> build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
||||||
|
{
|
||||||
|
std::vector<Type_Info> ti;
|
||||||
|
ti.push_back(detail::Get_Type_Info<Ret>::get());
|
||||||
|
|
||||||
|
BOOST_PP_REPEAT(n, gettypeinfo, ~)
|
||||||
|
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
|
||||||
|
* The function attempts to unbox each paramter to the expected type.
|
||||||
|
* if any unboxing fails the execution of the function fails and
|
||||||
|
* the bad_boxed_cast is passed up to the caller.
|
||||||
|
*/
|
||||||
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||||
|
Boxed_Value call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
|
||||||
|
const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
if (params.size() != n)
|
||||||
|
{
|
||||||
|
throw arity_error(params.size(), n);
|
||||||
|
} else {
|
||||||
|
return Handle_Return<Ret>::call(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
||||||
|
* Proxy_Function_Impl object. This function is primarly used to prevent
|
||||||
|
* registration of two functions with the exact same signatures
|
||||||
|
*/
|
||||||
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||||
|
bool compare_types(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)),
|
||||||
|
const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
if (params.size() != n)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
bool val = true BOOST_PP_REPEAT(n, comparetype, ~);
|
||||||
|
if (val) return true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
BOOST_PP_REPEAT(n, trycast, ~);
|
||||||
|
} catch (const bad_boxed_cast &) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -16,71 +16,86 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
template<typename T>
|
namespace detail
|
||||||
Proxy_Function fun(const boost::function<T> &f)
|
{
|
||||||
{
|
/**
|
||||||
return Proxy_Function(new Proxy_Function_Impl<T>(f));
|
* Helper function for register_member function
|
||||||
}
|
*/
|
||||||
|
template<typename T, typename Class>
|
||||||
|
T &get_member(T Class::* m, Class *obj)
|
||||||
|
{
|
||||||
|
return (obj->*m);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Proxy_Function fun_helper(const boost::function<T> &f)
|
||||||
|
{
|
||||||
|
return Proxy_Function(new Proxy_Function_Impl<T>(f));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for register_member function
|
* Automatically create a get_member helper function for an object
|
||||||
*/
|
* to allow for runtime dispatched access to public data members
|
||||||
template<typename T, typename Class>
|
* for example, the case of std::pair<>::first and std::pair<>::second
|
||||||
T &get_member(T Class::* m, Class *obj)
|
*/
|
||||||
{
|
template<typename T, typename Class>
|
||||||
return (obj->*m);
|
Proxy_Function fun_helper(T Class::* m)
|
||||||
}
|
{
|
||||||
|
return fun_helper(boost::function<T& (Class *)>(boost::bind(&detail::get_member<T, Class>, m, _1)));
|
||||||
/**
|
}
|
||||||
* Automatically create a get_member helper function for an object
|
}
|
||||||
* to allow for runtime dispatched access to public data members
|
|
||||||
* for example, the case of std::pair<>::first and std::pair<>::second
|
|
||||||
*/
|
|
||||||
template<typename T, typename Class>
|
|
||||||
Proxy_Function fun(T Class::* m)
|
|
||||||
{
|
|
||||||
return fun(boost::function<T& (Class *)>(boost::bind(&get_member<T, Class>, m, _1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
||||||
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/register_function.hpp>
|
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/register_function.hpp>
|
||||||
#include BOOST_PP_ITERATE()
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
Proxy_Function fun(T t)
|
||||||
|
{
|
||||||
|
return detail::fun_helper(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define n BOOST_PP_ITERATION()
|
# define n BOOST_PP_ITERATION()
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
/**
|
namespace detail
|
||||||
* Register a global function of n parameters with name
|
{
|
||||||
*/
|
/**
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
* Register a global function of n parameters with name
|
||||||
Proxy_Function fun(Ret (*f)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
*/
|
||||||
{
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||||
return fun(boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>(f));
|
Proxy_Function fun_helper(Ret (*f)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
||||||
}
|
{
|
||||||
|
return fun_helper(boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>(f));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a class method of n parameters with name
|
* Register a class method of n parameters with name
|
||||||
*/
|
*/
|
||||||
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||||
Proxy_Function fun(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
Proxy_Function fun_helper(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
||||||
{
|
{
|
||||||
return fun(boost::function<Ret (Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f));
|
return fun_helper(boost::function<Ret (Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a const class method of n parameters with name
|
* Register a const class method of n parameters with name
|
||||||
*/
|
*/
|
||||||
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||||
Proxy_Function fun(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const)
|
Proxy_Function fun_helper(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const)
|
||||||
{
|
{
|
||||||
return fun(boost::function<Ret (const Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f));
|
return fun_helper(boost::function<Ret (const Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -77,57 +77,71 @@ namespace chaiscript
|
|||||||
bool m_is_unknown;
|
bool m_is_unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
namespace detail
|
||||||
* Helper used to create a Type_Info object
|
{
|
||||||
*/
|
/**
|
||||||
template<typename T>
|
* Helper used to create a Type_Info object
|
||||||
struct Get_Type_Info
|
*/
|
||||||
{
|
template<typename T>
|
||||||
static Type_Info get()
|
struct Get_Type_Info
|
||||||
{
|
{
|
||||||
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
static Type_Info get()
|
||||||
boost::is_void<T>::value,
|
{
|
||||||
&typeid(T),
|
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||||
&typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
|
boost::is_void<T>::value,
|
||||||
}
|
&typeid(T),
|
||||||
};
|
&typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info<boost::shared_ptr<T> >
|
struct Get_Type_Info<boost::shared_ptr<T> >
|
||||||
{
|
|
||||||
static Type_Info get()
|
|
||||||
{
|
{
|
||||||
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
static Type_Info get()
|
||||||
boost::is_void<T>::value,
|
{
|
||||||
&typeid(boost::shared_ptr<T> ),
|
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||||
&typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
|
boost::is_void<T>::value,
|
||||||
}
|
&typeid(boost::shared_ptr<T> ),
|
||||||
};
|
&typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info<boost::reference_wrapper<T> >
|
struct Get_Type_Info<const boost::shared_ptr<T> &>
|
||||||
{
|
|
||||||
static Type_Info get()
|
|
||||||
{
|
{
|
||||||
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
static Type_Info get()
|
||||||
boost::is_void<T>::value,
|
{
|
||||||
&typeid(boost::reference_wrapper<T> ),
|
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||||
&typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
|
boost::is_void<T>::value,
|
||||||
}
|
&typeid(const boost::shared_ptr<T> &),
|
||||||
};
|
&typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Get_Type_Info<boost::reference_wrapper<T> >
|
||||||
|
{
|
||||||
|
static Type_Info get()
|
||||||
|
{
|
||||||
|
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
|
||||||
|
boost::is_void<T>::value,
|
||||||
|
&typeid(boost::reference_wrapper<T> ),
|
||||||
|
&typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Type_Info user_type(T)
|
Type_Info user_type(T)
|
||||||
{
|
{
|
||||||
return Get_Type_Info<T>::get();
|
return detail::Get_Type_Info<T>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Type_Info user_type()
|
Type_Info user_type()
|
||||||
{
|
{
|
||||||
return Get_Type_Info<T>::get();
|
return detail::Get_Type_Info<T>::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,18 +19,27 @@ namespace chaiscript
|
|||||||
template <typename Eval_Engine>
|
template <typename Eval_Engine>
|
||||||
class ChaiScript_System {
|
class ChaiScript_System {
|
||||||
Eval_Engine engine;
|
Eval_Engine engine;
|
||||||
|
|
||||||
|
std::set<std::string> loaded_files;
|
||||||
|
|
||||||
ChaiScript_Parser parser;
|
ChaiScript_Parser parser;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates the given string in by parsing it and running the results through the evaluator
|
* Evaluates the given string in by parsing it and running the results through the evaluator
|
||||||
*/
|
*/
|
||||||
Boxed_Value do_eval(const std::string &input, const char *filename = "__EVAL__") {
|
Boxed_Value do_eval(const std::string &input, const std::string &filename = "__EVAL__") {
|
||||||
//debug_print(tokens);
|
//debug_print(tokens);
|
||||||
Boxed_Value value;
|
Boxed_Value value;
|
||||||
parser.clear_match_stack();
|
parser.clear_match_stack();
|
||||||
|
|
||||||
|
// Keep a cache of all loaded filenames and use the char * from this cache to pass
|
||||||
|
// to the parser. This is so that the parser does not have the overhead of passing
|
||||||
|
// around and copying strings
|
||||||
|
loaded_files.insert(filename);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (parser.parse(input, filename)) {
|
if (parser.parse(input, loaded_files.find(filename)->c_str())) {
|
||||||
//parser.show_match_stack();
|
//parser.show_match_stack();
|
||||||
value = eval_token<Eval_Engine>(engine, parser.ast());
|
value = eval_token<Eval_Engine>(engine, parser.ast());
|
||||||
}
|
}
|
||||||
@@ -49,6 +58,14 @@ namespace chaiscript
|
|||||||
return do_eval(boxed_cast<std::string>(vals.at(0)));
|
return do_eval(boxed_cast<std::string>(vals.at(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void use(const std::string &filename)
|
||||||
|
{
|
||||||
|
if (loaded_files.count(filename) == 0)
|
||||||
|
{
|
||||||
|
eval_file(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChaiScript_System() {
|
ChaiScript_System() {
|
||||||
@@ -117,12 +134,11 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* Helper function for loading a file
|
* Helper function for loading a file
|
||||||
*/
|
*/
|
||||||
std::string load_file(const char *filename) {
|
std::string load_file(const std::string &filename) {
|
||||||
std::ifstream infile (filename, std::ios::in | std::ios::ate);
|
std::ifstream infile (filename.c_str(), std::ios::in | std::ios::ate);
|
||||||
|
|
||||||
if (!infile.is_open()) {
|
if (!infile.is_open()) {
|
||||||
std::string fname = filename;
|
throw std::runtime_error("Can not open: " + filename);
|
||||||
throw std::runtime_error("Can not open: " + fname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::streampos size = infile.tellg();
|
std::streampos size = infile.tellg();
|
||||||
@@ -141,6 +157,24 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void build_eval_system() {
|
void build_eval_system() {
|
||||||
using namespace bootstrap;
|
using namespace bootstrap;
|
||||||
|
engine.add_reserved_word("def");
|
||||||
|
engine.add_reserved_word("fun");
|
||||||
|
engine.add_reserved_word("while");
|
||||||
|
engine.add_reserved_word("for");
|
||||||
|
engine.add_reserved_word("if");
|
||||||
|
engine.add_reserved_word("else");
|
||||||
|
engine.add_reserved_word("&&");
|
||||||
|
engine.add_reserved_word("||");
|
||||||
|
engine.add_reserved_word(",");
|
||||||
|
engine.add_reserved_word(":=");
|
||||||
|
engine.add_reserved_word("var");
|
||||||
|
engine.add_reserved_word("return");
|
||||||
|
engine.add_reserved_word("break");
|
||||||
|
engine.add_reserved_word("true");
|
||||||
|
engine.add_reserved_word("false");
|
||||||
|
engine.add_reserved_word("_");
|
||||||
|
|
||||||
|
|
||||||
engine.add(Bootstrap::bootstrap());
|
engine.add(Bootstrap::bootstrap());
|
||||||
|
|
||||||
engine.add(fun(boost::function<void ()>(boost::bind(&dump_system, boost::ref(engine)))), "dump_system");
|
engine.add(fun(boost::function<void ()>(boost::bind(&dump_system, boost::ref(engine)))), "dump_system");
|
||||||
@@ -150,12 +184,16 @@ namespace chaiscript
|
|||||||
|
|
||||||
engine.add(fun(boost::function<std::string (Boxed_Value)>(boost::bind(&chaiscript::type_name, boost::ref(engine), _1))),
|
engine.add(fun(boost::function<std::string (Boxed_Value)>(boost::bind(&chaiscript::type_name, boost::ref(engine), _1))),
|
||||||
"type_name");
|
"type_name");
|
||||||
|
engine.add(fun(boost::function<bool (const std::string &)>(boost::bind(&Eval_Engine::function_exists, boost::ref(engine), _1))),
|
||||||
|
"function_exists");
|
||||||
|
|
||||||
engine.add(vector_type<std::vector<Boxed_Value> >("Vector"));
|
engine.add(vector_type<std::vector<Boxed_Value> >("Vector"));
|
||||||
engine.add(string_type<std::string>("string"));
|
engine.add(string_type<std::string>("string"));
|
||||||
engine.add(map_type<std::map<std::string, Boxed_Value> >("Map"));
|
engine.add(map_type<std::map<std::string, Boxed_Value> >("Map"));
|
||||||
engine.add(pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
|
engine.add(pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
|
||||||
|
|
||||||
|
engine.add(fun(boost::function<void (const std::string &)>(boost::bind(&ChaiScript_System<Eval_Engine>::use, this, _1))), "use");
|
||||||
|
|
||||||
engine.add(Proxy_Function(
|
engine.add(Proxy_Function(
|
||||||
new Dynamic_Proxy_Function(boost::bind(&ChaiScript_System<Eval_Engine>::internal_eval, boost::ref(*this), _1), 1)), "eval");
|
new Dynamic_Proxy_Function(boost::bind(&ChaiScript_System<Eval_Engine>::internal_eval, boost::ref(*this), _1), 1)), "eval");
|
||||||
|
|
||||||
@@ -176,7 +214,7 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* Loads the file specified by filename, evaluates it, and returns the result
|
* Loads the file specified by filename, evaluates it, and returns the result
|
||||||
*/
|
*/
|
||||||
Boxed_Value eval_file(const char *filename) {
|
Boxed_Value eval_file(const std::string &filename) {
|
||||||
return do_eval(load_file(filename), filename);
|
return do_eval(load_file(filename), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +222,7 @@ namespace chaiscript
|
|||||||
* Loads the file specified by filename, evaluates it, and returns the as the specified type
|
* Loads the file specified by filename, evaluates it, and returns the as the specified type
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T eval_file(const char *filename) {
|
T eval_file(const std::string &filename) {
|
||||||
return boxed_cast<T>(do_eval(load_file(filename), filename));
|
return boxed_cast<T>(do_eval(load_file(filename), filename));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -171,7 +171,12 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_var_decl(Eval_System &ss, TokenPtr node) {
|
Boxed_Value eval_var_decl(Eval_System &ss, TokenPtr node) {
|
||||||
ss.add_object(node->children[0]->text, Boxed_Value());
|
try {
|
||||||
|
ss.add_object(node->children[0]->text, Boxed_Value());
|
||||||
|
}
|
||||||
|
catch (reserved_word_error &rwe) {
|
||||||
|
throw Eval_Error("Reserved word used as variable '" + node->children[0]->text + "'", node);
|
||||||
|
}
|
||||||
return ss.get_object(node->children[0]->text);
|
return ss.get_object(node->children[0]->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,10 +410,10 @@ namespace chaiscript
|
|||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
Param_List_Builder plb;
|
Param_List_Builder plb;
|
||||||
Dispatch_Engine::Stack prev_stack = ss.get_stack();
|
Dispatch_Engine::Stack prev_stack = ss.get_stack();
|
||||||
Dispatch_Engine::Stack new_stack;
|
Dispatch_Engine::Stack new_stack = ss.new_stack();
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
new_stack.push_back(Dispatch_Engine::Scope());
|
new_stack->push_back(Dispatch_Engine::Scope());
|
||||||
|
|
||||||
if ((node->children.size() > 1) && (node->children[1]->identifier == Token_Type::Arg_List)) {
|
if ((node->children.size() > 1) && (node->children[1]->identifier == Token_Type::Arg_List)) {
|
||||||
for (i = 0; i < node->children[1]->children.size(); ++i) {
|
for (i = 0; i < node->children[1]->children.size(); ++i) {
|
||||||
@@ -452,10 +457,10 @@ namespace chaiscript
|
|||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
std::vector<std::pair<std::string, Proxy_Function > > fn;
|
std::vector<std::pair<std::string, Proxy_Function > > fn;
|
||||||
Dispatch_Engine::Stack prev_stack = ss.get_stack();
|
Dispatch_Engine::Stack prev_stack = ss.get_stack();
|
||||||
Dispatch_Engine::Stack new_stack;
|
Dispatch_Engine::Stack new_stack = ss.new_stack();
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
new_stack.push_back(Dispatch_Engine::Scope());
|
new_stack->push_back(Dispatch_Engine::Scope());
|
||||||
|
|
||||||
//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
|
||||||
|
|
||||||
@@ -471,23 +476,32 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fun_name;
|
//std::string fun_name;
|
||||||
if (node->children[i]->identifier == Token_Type::Fun_Call) {
|
Boxed_Value fn;
|
||||||
fun_name = node->children[i]->children[0]->text;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fun_name = node->children[i]->text;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fn = ss.get_function(fun_name);
|
if (node->children[i]->identifier == Token_Type::Fun_Call) {
|
||||||
|
//fun_name = node->children[i]->children[0]->text;
|
||||||
|
fn = eval_token(ss, node->children[i]->children[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//fun_name = node->children[i]->text;
|
||||||
|
fn = eval_token(ss, node->children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Eval_Error &ee) {
|
||||||
|
ss.set_stack(prev_stack);
|
||||||
|
throw Eval_Error(ee.reason, node->children[i]);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
//fn = ss.get_function(fun_name);
|
||||||
ss.set_stack(new_stack);
|
ss.set_stack(new_stack);
|
||||||
retval = dispatch(fn, plb);
|
//retval = dispatch(fn, plb);
|
||||||
|
retval = (*boxed_cast<Proxy_Function >(fn))(plb);
|
||||||
ss.set_stack(prev_stack);
|
ss.set_stack(prev_stack);
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &e){
|
catch(const dispatch_error &e){
|
||||||
ss.set_stack(prev_stack);
|
ss.set_stack(prev_stack);
|
||||||
throw Eval_Error(std::string(e.what()) + " with function '" + fun_name + "'", node->children[i]);
|
throw Eval_Error(std::string(e.what()), node->children[i]);
|
||||||
}
|
}
|
||||||
catch(Return_Value &rv) {
|
catch(Return_Value &rv) {
|
||||||
ss.set_stack(prev_stack);
|
ss.set_stack(prev_stack);
|
||||||
@@ -556,10 +570,14 @@ namespace chaiscript
|
|||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_while(Eval_System &ss, TokenPtr node) {
|
Boxed_Value eval_while(Eval_System &ss, TokenPtr node) {
|
||||||
bool cond;
|
bool cond;
|
||||||
|
|
||||||
|
ss.new_scope();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool &>(eval_token(ss, node->children[0]));
|
cond = boxed_cast<bool &>(eval_token(ss, node->children[0]));
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const bad_boxed_cast &) {
|
||||||
|
ss.pop_scope();
|
||||||
throw Eval_Error("While condition not boolean", node->children[0]);
|
throw Eval_Error("While condition not boolean", node->children[0]);
|
||||||
}
|
}
|
||||||
while (cond) {
|
while (cond) {
|
||||||
@@ -569,6 +587,7 @@ namespace chaiscript
|
|||||||
cond = boxed_cast<bool &>(eval_token(ss, node->children[0]));
|
cond = boxed_cast<bool &>(eval_token(ss, node->children[0]));
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const bad_boxed_cast &) {
|
||||||
|
ss.pop_scope();
|
||||||
throw Eval_Error("While condition not boolean", node->children[0]);
|
throw Eval_Error("While condition not boolean", node->children[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -576,6 +595,7 @@ namespace chaiscript
|
|||||||
cond = false;
|
cond = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ss.pop_scope();
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,6 +606,8 @@ namespace chaiscript
|
|||||||
Boxed_Value eval_for(Eval_System &ss, TokenPtr node) {
|
Boxed_Value eval_for(Eval_System &ss, TokenPtr node) {
|
||||||
bool cond;
|
bool cond;
|
||||||
|
|
||||||
|
ss.new_scope();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (node->children.size() == 4) {
|
if (node->children.size() == 4) {
|
||||||
eval_token(ss, node->children[0]);
|
eval_token(ss, node->children[0]);
|
||||||
@@ -596,6 +618,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const bad_boxed_cast &) {
|
||||||
|
ss.pop_scope();
|
||||||
throw Eval_Error("For condition not boolean", node);
|
throw Eval_Error("For condition not boolean", node);
|
||||||
}
|
}
|
||||||
while (cond) {
|
while (cond) {
|
||||||
@@ -612,12 +635,14 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const bad_boxed_cast &) {
|
||||||
|
ss.pop_scope();
|
||||||
throw Eval_Error("For condition not boolean", node);
|
throw Eval_Error("For condition not boolean", node);
|
||||||
}
|
}
|
||||||
catch (Break_Loop &) {
|
catch (Break_Loop &) {
|
||||||
cond = false;
|
cond = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ss.pop_scope();
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,12 +687,16 @@ namespace chaiscript
|
|||||||
param_names, _1), numparams));
|
param_names, _1), numparams));
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.add(Proxy_Function
|
try {
|
||||||
(new Dynamic_Proxy_Function(boost::bind(&eval_function<Eval_System>,
|
ss.add(Proxy_Function
|
||||||
|
(new Dynamic_Proxy_Function(boost::bind(&eval_function<Eval_System>,
|
||||||
boost::ref(ss), node->children.back(),
|
boost::ref(ss), node->children.back(),
|
||||||
param_names, _1), numparams,
|
param_names, _1), numparams,
|
||||||
annotation, guard)), function_name);
|
annotation, guard)), function_name);
|
||||||
|
}
|
||||||
|
catch (reserved_word_error &rwe) {
|
||||||
|
throw Eval_Error("Reserved word used as function name '" + function_name + "'", node);
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -140,7 +140,7 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Float_() {
|
bool Float_() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
if ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
|
if ((input_pos != input_end) && (((*input_pos >= '0') && (*input_pos <= '9')) || (*input_pos == '.'))) {
|
||||||
while ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
|
while ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
|
||||||
++input_pos;
|
++input_pos;
|
||||||
++col;
|
++col;
|
||||||
@@ -178,7 +178,7 @@ namespace chaiscript
|
|||||||
std::string::iterator start = input_pos;
|
std::string::iterator start = input_pos;
|
||||||
int prev_col = col;
|
int prev_col = col;
|
||||||
int prev_line = line;
|
int prev_line = line;
|
||||||
if ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
|
if ((input_pos != input_end) && (((*input_pos >= '0') && (*input_pos <= '9')) || (*input_pos == '.')) ) {
|
||||||
if (Float_()) {
|
if (Float_()) {
|
||||||
std::string match(start, input_pos);
|
std::string match(start, input_pos);
|
||||||
TokenPtr t(new Token(match, Token_Type::Float, filename, prev_line, prev_col, line, col));
|
TokenPtr t(new Token(match, Token_Type::Float, filename, prev_line, prev_col, line, col));
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#define chaiscript_prelude CODE_STRING(\
|
#define chaiscript_prelude CODE_STRING(\
|
||||||
def new(x) { eval(type_name(x))(); } \
|
def new(x) { eval(type_name(x))(); } \
|
||||||
def clone(x) { eval(type_name(x))(x); } \
|
def clone(x) : function_exists(type_name(x)) { eval(type_name(x))(x); } \
|
||||||
# to_string for Pair()\n\
|
# to_string for Pair()\n\
|
||||||
def to_string(x) : call_exists(first, x) && call_exists(second, x) { \
|
def to_string(x) : call_exists(first, x) && call_exists(second, x) { \
|
||||||
"<" + x.first.to_string() + ", " + x.second.to_string() + ">"; \
|
"<" + x.first.to_string() + ", " + x.second.to_string() + ">"; \
|
||||||
|
@@ -122,7 +122,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="3"
|
Optimization="3"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
AdditionalIncludeDirectories=""$(ProjectDir)\..\..\dispatchkit";"$(ProjectDir)\..\..\chaiscript""
|
AdditionalIncludeDirectories=""$(ProjectDir)\..\..\include""
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -229,6 +229,14 @@
|
|||||||
RelativePath="..\..\include\chaiscript\dispatchkit\function_call.hpp"
|
RelativePath="..\..\include\chaiscript\dispatchkit\function_call.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\chaiscript\dispatchkit\function_call_detail.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\chaiscript\dispatchkit\handle_return.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\chaiscript\dispatchkit\proxy_constructors.hpp"
|
RelativePath="..\..\include\chaiscript\dispatchkit\proxy_constructors.hpp"
|
||||||
>
|
>
|
||||||
@@ -237,6 +245,10 @@
|
|||||||
RelativePath="..\..\include\chaiscript\dispatchkit\proxy_functions.hpp"
|
RelativePath="..\..\include\chaiscript\dispatchkit\proxy_functions.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\chaiscript\dispatchkit\proxy_functions_detail.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\chaiscript\dispatchkit\register_function.hpp"
|
RelativePath="..\..\include\chaiscript\dispatchkit\register_function.hpp"
|
||||||
>
|
>
|
||||||
|
@@ -2,7 +2,7 @@ var i = 0
|
|||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
print("i is 0")
|
print("i is 0")
|
||||||
}
|
}
|
||||||
elseif (i == 1) {
|
else if (i == 1) {
|
||||||
print("i is 1")
|
print("i is 1")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -45,6 +45,10 @@ struct System
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void take_shared_ptr(const boost::shared_ptr<std::string> &p)
|
||||||
|
{
|
||||||
|
std::cout << *p << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
using namespace chaiscript;
|
using namespace chaiscript;
|
||||||
@@ -59,6 +63,8 @@ int main(int argc, char *argv[]) {
|
|||||||
chai.add(fun(&System::add_callback), "add_callback");
|
chai.add(fun(&System::add_callback), "add_callback");
|
||||||
chai.add(fun(&System::do_callbacks), "do_callbacks");
|
chai.add(fun(&System::do_callbacks), "do_callbacks");
|
||||||
|
|
||||||
|
chai.add(fun(&take_shared_ptr), "take_shared_ptr");
|
||||||
|
|
||||||
// Let's use chaiscript to add a new lambda callback to our system.
|
// Let's use chaiscript to add a new lambda callback to our system.
|
||||||
// The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application
|
// The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application
|
||||||
// in the "add_callback" function of struct System the chaiscript function is converted into a
|
// in the "add_callback" function of struct System the chaiscript function is converted into a
|
||||||
@@ -123,5 +129,8 @@ int main(int argc, char *argv[]) {
|
|||||||
//mostly supported currently
|
//mostly supported currently
|
||||||
chai.add(bootstrap::vector_type<std::vector<int> >("IntVector"));
|
chai.add(bootstrap::vector_type<std::vector<int> >("IntVector"));
|
||||||
|
|
||||||
|
|
||||||
|
chai("dump_system()");
|
||||||
|
chai("take_shared_ptr(\"Hello World as a shared_ptr\");");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
unittests/float.chai
Normal file
2
unittests/float.chai
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
print(1.2)
|
||||||
|
print(.5)
|
2
unittests/float.txt
Normal file
2
unittests/float.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
1.2
|
||||||
|
0.5
|
3
unittests/method_lambda.chai
Normal file
3
unittests/method_lambda.chai
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
var addit = fun(x, y) { return x+y }
|
||||||
|
|
||||||
|
print(3.addit(4))
|
1
unittests/method_lambda.txt
Normal file
1
unittests/method_lambda.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
7
|
3
unittests/use.chai
Normal file
3
unittests/use.chai
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
use("unittests/use.inc")
|
||||||
|
|
||||||
|
greet()
|
3
unittests/use.inc
Normal file
3
unittests/use.inc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
def greet {
|
||||||
|
print("hello")
|
||||||
|
}
|
1
unittests/use.txt
Normal file
1
unittests/use.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
hello
|
Reference in New Issue
Block a user