Allow "Module" to contain chaiscript snippets to be executed when a module is initialized. Update dynamic_object to use the new feature to clean up some of the _prelude.hpp

This commit is contained in:
Jason Turner 2009-09-21 03:07:01 +00:00
parent 8241e46680
commit 50eace16da
5 changed files with 34 additions and 21 deletions

View File

@ -693,6 +693,7 @@ namespace chaiscript
m->add(fun(&Dynamic_Object::get_type_name), "get_type_name"); m->add(fun(&Dynamic_Object::get_type_name), "get_type_name");
m->add(fun(&Dynamic_Object::get_attrs), "get_attrs"); m->add(fun(&Dynamic_Object::get_attrs), "get_attrs");
m->add(fun(&Dynamic_Object::get_attr), "get_attr"); m->add(fun(&Dynamic_Object::get_attr), "get_attr");
m->eval("def Dynamic_Object::clone() { var new_o := Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }");
basic_constructors<bool>("bool", m); basic_constructors<bool>("bool", m);

View File

@ -42,16 +42,26 @@ namespace chaiscript
return *this; return *this;
} }
template<typename T> //Add a bit of chaiscript to eval during module implementation
void apply(T &t) const Module &eval(const std::string &str)
{
m_evals.push_back(str);
return *this;
}
template<typename Eval, typename Engine>
void apply(Eval &t_eval, Engine &t_engine) const
{ {
apply(m_typeinfos.begin(), m_typeinfos.end(), t); apply(m_typeinfos.begin(), m_typeinfos.end(), t_engine);
apply(m_funcs.begin(), m_funcs.end(), t); apply(m_funcs.begin(), m_funcs.end(), t_engine);
apply_eval(m_evals.begin(), m_evals.end(), t_eval);
} }
private: private:
std::vector<std::pair<Type_Info, std::string> > m_typeinfos; std::vector<std::pair<Type_Info, std::string> > m_typeinfos;
std::vector<std::pair<Proxy_Function, std::string> > m_funcs; std::vector<std::pair<Proxy_Function, std::string> > m_funcs;
std::vector<std::string> m_evals;
template<typename T, typename InItr> template<typename T, typename InItr>
void apply(InItr begin, InItr end, T &t) const void apply(InItr begin, InItr end, T &t) const
@ -62,6 +72,18 @@ namespace chaiscript
++begin; ++begin;
} }
} }
template<typename T, typename InItr>
void apply_eval(InItr begin, InItr end, T &t) const
{
while (begin != end)
{
t.eval(*begin);
++begin;
}
}
}; };
typedef boost::shared_ptr<Module> ModulePtr; typedef boost::shared_ptr<Module> ModulePtr;
@ -180,14 +202,6 @@ namespace chaiscript
return add_function(f, name); return add_function(f, name);
} }
/**
* Add a module's worth of registrations to the system
*/
void add(const ModulePtr &m)
{
m->apply(*this);
}
/** /**
* Set the value of an object, by name. If the object * Set the value of an object, by name. If the object
* is not available in the current scope it is created * is not available in the current scope it is created

View File

@ -52,7 +52,7 @@ namespace chaiscript
{ {
try { try {
const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bvs[0]); const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bvs[0]);
return d.get_type_name() == name; return name == "Dynamic_Object" || d.get_type_name() == name;
} catch (const std::bad_cast &) { } catch (const std::bad_cast &) {
if (ti) if (ti)
{ {

View File

@ -292,8 +292,7 @@ namespace chaiscript
*/ */
ChaiScript_System &add(const ModulePtr &p) ChaiScript_System &add(const ModulePtr &p)
{ {
engine.add(p); p->apply(*this, this->get_eval_engine());
return *this; return *this;
} }
@ -431,7 +430,7 @@ namespace chaiscript
engine.add_reserved_word("_"); engine.add_reserved_word("_");
engine.add(Bootstrap::bootstrap()); 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");
engine.add(fun(boost::function<void (Boxed_Value)>(boost::bind(&dump_object, _1, boost::ref(engine)))), "dump_object"); engine.add(fun(boost::function<void (Boxed_Value)>(boost::bind(&dump_object, _1, boost::ref(engine)))), "dump_object");
@ -454,10 +453,10 @@ namespace chaiscript
&ChaiScript_System<Eval_Engine>::load_module), boost::ref(*this), _1, _2))), &ChaiScript_System<Eval_Engine>::load_module), boost::ref(*this), _1, _2))),
"load_module"); "load_module");
engine.add(vector_type<std::vector<Boxed_Value> >("Vector")); add(vector_type<std::vector<Boxed_Value> >("Vector"));
engine.add(string_type<std::string>("string")); add(string_type<std::string>("string"));
engine.add(map_type<std::map<std::string, Boxed_Value> >("Map")); add(map_type<std::map<std::string, Boxed_Value> >("Map"));
engine.add(pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair")); 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(fun(boost::function<void (const std::string &)>(boost::bind(&ChaiScript_System<Eval_Engine>::use, this, _1))), "use");

View File

@ -13,7 +13,6 @@
#define chaiscript_prelude CODE_STRING(\ #define chaiscript_prelude CODE_STRING(\
def new(x) { eval(type_name(x))(); } \n\ def new(x) { eval(type_name(x))(); } \n\
def clone(o) : is_type(o, "Dynamic_Object") { var new_o := Dynamic_Object(o.get_type_name()); for_each(o.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; } \n\
def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x) { eval(type_name(x))(x); } \n\ def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x) { eval(type_name(x))(x); } \n\
# to_string for Pair()\n\ # to_string for Pair()\n\
def to_string(x) : call_exists(first, x) && call_exists(second, x) { \n\ def to_string(x) : call_exists(first, x) && call_exists(second, x) { \n\