Add support for function binding and cut down on some includes

This commit is contained in:
Jason Turner 2009-06-25 22:34:00 +00:00
parent 96f3033a42
commit 46859b1918
5 changed files with 118 additions and 1 deletions

View File

@ -431,6 +431,19 @@ namespace dispatchkit
register_function(s, &multiply<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>, "*");
}
static Boxed_Value bind_function(const std::vector<Boxed_Value> &params)
{
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)
{
s.register_type<void>("void");
@ -441,6 +454,7 @@ namespace dispatchkit
add_basic_constructors<std::string>(s, "string");
add_oper_assign<std::string>(s);
register_function(s, &to_string<const std::string &>, "to_string");
register_function(s, &to_string<bool>, "to_string");
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 (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_or<bool, bool>, "||");
}

View File

@ -8,6 +8,7 @@
#include <boost/function.hpp>
#include <boost/ref.hpp>
#include <boost/bind.hpp>
#include <boost/type_traits/add_const.hpp>
namespace dispatchkit
{

View File

@ -158,6 +158,69 @@ namespace dispatchkit
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> &params)
{
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>
class Proxy_Function_Impl : public Proxy_Function
{

View File

@ -1,7 +1,13 @@
#ifndef __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>
namespace dispatchkit

30
samples/bind.chai Normal file
View 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));