#ifndef __boxedcpp_system_hpp__ #define __boxedcpp_system_hpp__ #include #include #include #include #include #include #include #include #include "boxed_value.hpp" #include "type_info.hpp" #include "proxy_functions.hpp" #include "proxy_constructors.hpp" class BoxedCPP_System { public: typedef std::multimap > Function_Map; typedef std::map Type_Name_Map; void register_function(const boost::shared_ptr &f, const std::string &name) { m_functions.insert(std::make_pair(name, f)); } template void register_function(const Function &func, const std::string &name) { m_functions.insert(std::make_pair(name, boost::shared_ptr(new Proxy_Function_Impl(func)))); } template void add_object(const std::string &name, const Class &obj) { m_objects.insert(std::make_pair(name, Boxed_Value(obj))); } Boxed_Value get_object(const std::string &name) const { std::map::const_iterator itr = m_objects.find(name); if (itr != m_objects.end()) { return itr->second; } else { throw std::range_error("Object not known: " + name); } } template void register_type(const std::string &name) { m_types.insert(std::make_pair(name, Get_Type_Info()())); } std::vector get_types() const { return std::vector(m_types.begin(), m_types.end()); } std::vector get_function(const std::string &t_name) const { std::pair range = m_functions.equal_range(t_name); return std::vector(range.first, range.second); } std::vector get_functions() const { return std::vector(m_functions.begin(), m_functions.end()); } private: std::map m_objects; Function_Map m_functions; Type_Name_Map m_types; }; void dump_type(const Type_Info &type) { std::cout << type.m_bare_type_info->name(); } void dump_function(const BoxedCPP_System::Function_Map::value_type &f) { std::vector params = f.second->get_param_types(); dump_type(params.front()); std::cout << " " << f.first << "("; for (std::vector::const_iterator itr = params.begin() + 1; itr != params.end(); ++itr) { dump_type(*itr); std::cout << ", "; } std::cout << ")" << std::endl; } void dump_system(const BoxedCPP_System &s) { std::cout << "Registered Types: " << std::endl; std::vector types = s.get_types(); for (std::vector::const_iterator itr = types.begin(); itr != types.end(); ++itr) { std::cout << itr->first << ": "; dump_type(itr->second); std::cout << std::endl; } std::cout << std::endl; std::vector funcs = s.get_functions(); std::cout << "Functions: " << std::endl; for (std::vector::const_iterator itr = funcs.begin(); itr != funcs.end(); ++itr) { dump_function(*itr); } std::cout << std::endl; } template Ret add(P1 p1, P2 p2) { return p1 + p2; } template Ret subtract(P1 p1, P2 p2) { return p1 - p2; } template Ret divide(P1 p1, P2 p2) { return p1 - p2; } template Ret multiply(P1 p1, P2 p2) { return p1 * p2; } template P1 ×equal(P1 &p1, P2 p2) { return (p1 *= p2); } template std::string to_string(Input i) { return boost::lexical_cast(i); } void bootstrap(BoxedCPP_System &s) { s.register_type("void"); s.register_type("double"); s.register_type("int"); s.register_type("char"); s.register_type("string"); s.register_function(boost::function(&add), "+"); s.register_function(boost::function(&add), "+"); s.register_function(boost::function(&add), "+"); s.register_function(boost::function(&add), "+"); s.register_function(boost::function(&add), "+"); s.register_function(boost::function(&subtract), "-"); s.register_function(boost::function(&subtract), "-"); s.register_function(boost::function(&subtract), "-"); s.register_function(boost::function(&subtract), "-"); s.register_function(boost::function), "/"); s.register_function(boost::function), "/"); s.register_function(boost::function), "/"); s.register_function(boost::function), "/"); s.register_function(boost::function(&multiply), "*"); s.register_function(boost::function(&multiply), "*"); s.register_function(boost::function(&multiply), "*"); s.register_function(boost::function(&multiply), "*"); s.register_function(boost::function(&to_string), "to_string"); s.register_function(boost::function(&to_string), "to_string"); s.register_function(boost::function(&to_string), "to_string"); s.register_function(boost::function(&to_string), "to_string"); s.register_function(boost::function(×equal), "*="); s.register_function(boost::function(×equal), "*="); s.register_function(boost::function(×equal), "*="); s.register_function(boost::function(×equal), "*="); } #endif