Add support for function binding and cut down on some includes
This commit is contained in:
parent
96f3033a42
commit
46859b1918
@ -431,6 +431,19 @@ namespace dispatchkit
|
|||||||
register_function(s, &multiply<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>, "*");
|
register_function(s, &multiply<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>, "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Boxed_Value bind_function(const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
if (params.size() < 2)
|
||||||
|
{
|
||||||
|
throw arity_error(params.size(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Proxy_Function> f = boxed_cast<boost::shared_ptr<Proxy_Function> >(params[0]);
|
||||||
|
|
||||||
|
return Boxed_Value(boost::shared_ptr<Proxy_Function>(new Bound_Function(f,
|
||||||
|
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
|
||||||
|
}
|
||||||
|
|
||||||
static void bootstrap(Dispatch_Engine &s)
|
static void bootstrap(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
s.register_type<void>("void");
|
s.register_type<void>("void");
|
||||||
@ -441,6 +454,7 @@ namespace dispatchkit
|
|||||||
add_basic_constructors<std::string>(s, "string");
|
add_basic_constructors<std::string>(s, "string");
|
||||||
add_oper_assign<std::string>(s);
|
add_oper_assign<std::string>(s);
|
||||||
|
|
||||||
|
|
||||||
register_function(s, &to_string<const std::string &>, "to_string");
|
register_function(s, &to_string<const std::string &>, "to_string");
|
||||||
register_function(s, &to_string<bool>, "to_string");
|
register_function(s, &to_string<bool>, "to_string");
|
||||||
register_function(s, &unknown_assign, "=");
|
register_function(s, &unknown_assign, "=");
|
||||||
@ -466,6 +480,9 @@ namespace dispatchkit
|
|||||||
s.register_function(boost::function<void ()>(boost::bind(&dump_system, boost::ref(s))), "dump_system");
|
s.register_function(boost::function<void ()>(boost::bind(&dump_system, boost::ref(s))), "dump_system");
|
||||||
s.register_function(boost::function<void (Boxed_Value)>(boost::bind(&dump_object, _1)), "dump_object");
|
s.register_function(boost::function<void (Boxed_Value)>(boost::bind(&dump_object, _1)), "dump_object");
|
||||||
|
|
||||||
|
s.register_function(boost::shared_ptr<Proxy_Function>(new Dynamic_Proxy_Function(boost::bind(&bind_function, _1))),
|
||||||
|
"bind");
|
||||||
|
|
||||||
register_function(s, &bool_and<bool, bool>, "&&");
|
register_function(s, &bool_and<bool, bool>, "&&");
|
||||||
register_function(s, &bool_or<bool, bool>, "||");
|
register_function(s, &bool_or<bool, bool>, "||");
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/ref.hpp>
|
#include <boost/ref.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/type_traits/add_const.hpp>
|
||||||
|
|
||||||
namespace dispatchkit
|
namespace dispatchkit
|
||||||
{
|
{
|
||||||
|
@ -158,6 +158,69 @@ namespace dispatchkit
|
|||||||
int m_arity;
|
int m_arity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Bound_Function : public Proxy_Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Bound_Function(const boost::shared_ptr<Proxy_Function> &t_f,
|
||||||
|
const std::vector<Boxed_Value> &t_args)
|
||||||
|
: m_f(t_f), m_args(t_args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const Proxy_Function &f) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Bound_Function() {}
|
||||||
|
|
||||||
|
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
typedef std::vector<Boxed_Value>::const_iterator pitr;
|
||||||
|
|
||||||
|
pitr parg = params.begin();
|
||||||
|
pitr barg = m_args.begin();
|
||||||
|
|
||||||
|
std::vector<Boxed_Value> args;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
while (barg != m_args.end() && !barg->is_unknown())
|
||||||
|
{
|
||||||
|
args.push_back(*barg);
|
||||||
|
++barg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parg != params.end())
|
||||||
|
{
|
||||||
|
args.push_back(*parg);
|
||||||
|
++parg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (barg != m_args.end() && barg->is_unknown())
|
||||||
|
{
|
||||||
|
++barg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parg == params.end() && barg == m_args.end())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*m_f)(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::vector<Type_Info> get_param_types()
|
||||||
|
{
|
||||||
|
return std::vector<Type_Info>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::shared_ptr<Proxy_Function> m_f;
|
||||||
|
std::vector<Boxed_Value> m_args;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
class Proxy_Function_Impl : public Proxy_Function
|
class Proxy_Function_Impl : public Proxy_Function
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
#ifndef __type_info_hpp__
|
#ifndef __type_info_hpp__
|
||||||
#define __type_info_hpp__
|
#define __type_info_hpp__
|
||||||
|
|
||||||
#include <boost/type_traits.hpp>
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#include <boost/type_traits/is_void.hpp>
|
||||||
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
|
#include <boost/type_traits/is_pointer.hpp>
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
#include <boost/type_traits/remove_pointer.hpp>
|
||||||
#include <boost/ref.hpp>
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
namespace dispatchkit
|
namespace dispatchkit
|
||||||
|
30
samples/bind.chai
Normal file
30
samples/bind.chai
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
//This is a cheater function. The entire point of it is to return a variable
|
||||||
|
// with an unspecified type.
|
||||||
|
// The bind function will substitute any unknown object with those passed in
|
||||||
|
def _()
|
||||||
|
{
|
||||||
|
var i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
def add(x, y)
|
||||||
|
{
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = bind(add, 2, _());
|
||||||
|
var c = bind(b, 3);
|
||||||
|
|
||||||
|
print(b(4));
|
||||||
|
print(c());
|
||||||
|
|
||||||
|
|
||||||
|
def concat(a,b,c,d)
|
||||||
|
{
|
||||||
|
return to_string(a) + to_string(b) + to_string(c) + to_string(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
var d = bind(concat, _(), " Hello ", _(), " World ");
|
||||||
|
print(d(1, 3));
|
||||||
|
print(d(1, 3, 4));
|
Loading…
x
Reference in New Issue
Block a user