#ifndef __bootstrap_hpp #define __bootstrap_hpp__ #include "dispatchkit.hpp" #include "register_function.hpp" namespace dispatchkit { 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 bool bool_and(P1 p1, P2 p2) { return p1 && p2; } template bool bool_or(P1 p1, P2 p2) { return p1 || p2; } template P1 &assign(P1 &p1, const P2 &p2) { return (p1 = p2); } template P1 &assign_pod(P1 &p1, Boxed_POD_Value v) { if (v.m_isfloat) { return (p1 = v.d); } else { return (p1 = v.i); } } template bool equals(P1 p1, P2 p2) { return p1 == p2; } template bool not_equals(P1 p1, P2 p2) { return p1 != p2; } template bool less_than(P1 p1, P2 p2) { return p1 < p2; } template bool greater_than(P1 p1, P2 p2) { return p1 > p2; } template bool less_than_equals(P1 p1, P2 p2) { return p1 <= p2; } template bool greater_than_equals(P1 p1, P2 p2) { return p1 >= p2; } template P1 ×equal(P1 &p1, const P2 &p2) { return (p1 *= p2); } template P1 ×equal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) { return (p1 *= r.d); } else { return (p1 *= r.i); } } template P1 ÷sequal(P1 &p1, const P2 &p2) { return (p1 /= p2); } template P1 ÷sequal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) { return (p1 /= r.d); } else { return (p1 /= r.i); } } template P1 &addsequal(P1 &p1, const P2 &p2) { return (p1 += p2); } template P1 &addsequal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) { return (p1 += r.d); } else { return (p1 += r.i); } } template P1 &subtractsequal(P1 &p1, const P2 &p2) { return (p1 -= p2); } template P1 &subtractsequal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) { return (p1 -= r.d); } else { return (p1 -= r.i); } } template P1 &prefixincrement(P1 &p1) { return (++p1); } template P1 &prefixdecrement(P1 &p1) { return (--p1); } template P1 &prefixnegate(P1 &p1) { return (p1); } template P1 &prefixnot(P1 &p1) { return (p1); } //Add canonical forms of operators template void add_oper_equals(Dispatch_Engine &s) { register_function(s, &equals, "="); } template void add_oper_add(Dispatch_Engine &s) { register_function(s, &add, "+"); } template void add_oper_add_equals(Dispatch_Engine &s) { register_function(s, &addsequal, "+="); } template void add_oper_subtract(Dispatch_Engine &s) { register_function(s, &subtract, "-"); } template void add_oper_divide(Dispatch_Engine &s) { register_function(s, ÷, "-"); } template void add_oper_multiply(Dispatch_Engine &s) { register_function(s, &multiply, "*"); } template void add_oper_not_equals(Dispatch_Engine &s) { register_function(s, ¬_equals, "!="); } template void add_oper_assign_overload(Dispatch_Engine &s) { register_function(s, &assign, "="); } template void add_oper_assign(Dispatch_Engine &s) { register_function(s, &assign, "="); } template void add_oper_assign_pod(Dispatch_Engine &s) { register_function(s, &assign_pod, "="); } template void add_oper_less_than(Dispatch_Engine &s) { register_function(s, &less_than, "<"); } template void add_oper_greater_than(Dispatch_Engine &s) { register_function(s, &greater_than, ">"); } template void add_oper_less_than_equals(Dispatch_Engine &s) { register_function(s, &less_than_equals, "<="); } template void add_oper_greater_than_equals(Dispatch_Engine &s) { register_function(s, &greater_than_equals, ">="); } template void add_opers_comparison_overload(Dispatch_Engine &s) { register_function(s, &equals, "=="); register_function(s, ¬_equals, "!="); register_function(s, &less_than, "<"); register_function(s, &greater_than, ">"); register_function(s, &less_than_equals, "<="); register_function(s, &greater_than_equals, ">="); } template void add_opers_comparison(Dispatch_Engine &s) { add_opers_comparison_overload(s); } template void add_opers_arithmetic_overload(Dispatch_Engine &s) { register_function(s, &add, "+"); register_function(s, &subtract, "-"); register_function(s, ÷, "/"); register_function(s, &multiply, "*"); register_function(s, ×equal, "*="); register_function(s, ÷sequal, "/="); register_function(s, &subtractsequal, "-="); register_function(s, &addsequal, "+="); register_function(s, &prefixincrement, "++"); register_function(s, &prefixdecrement, "--"); register_function(s, &prefixnegate, "-"); register_function(s, &prefixnot, "!"); } template void add_opers_arithmetic_modify_pod(Dispatch_Engine &s) { register_function(s, ×equal_pod, "*="); register_function(s, ÷sequal_pod, "/="); register_function(s, &subtractsequal_pod, "-="); register_function(s, &addsequal_pod, "+="); } template void add_basic_constructors(Dispatch_Engine &s, const std::string &type) { s.register_function(build_constructor(), type); s.register_function(build_constructor(), type); s.register_function(build_constructor(), "clone"); } template void add_constructor_overload(Dispatch_Engine &s, const std::string &type) { s.register_function(build_constructor(), type); } template void add_opers_arithmetic(Dispatch_Engine &s) { add_opers_arithmetic_overload(s); } class bad_boxed_value_cast : public std::bad_cast { public: bad_boxed_value_cast(const std::string &val) throw() : m_val(val) { } virtual ~bad_boxed_value_cast() throw() { } virtual const char * what() const throw() { return m_val.c_str(); } private: std::string m_val; }; //Built in to_string operator template std::string to_string(Input i) { return boost::lexical_cast(i); } template<> std::string to_string(bool b) { if (b) { return "true"; } else { return "false"; } } template void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name) { s.register_type(name); add_basic_constructors(s, name); add_oper_assign(s); add_oper_assign_pod(s); add_opers_arithmetic(s); add_opers_arithmetic_modify_pod(s); register_function(s, &to_string, "to_string"); } struct Bootstrap { static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs) { if (lhs.is_unknown()) { return (lhs.assign(rhs)); } else { throw bad_boxed_value_cast("boxed_value has a set type alread"); } } static void print(const std::string &s) { std::cout << s << std::endl; } static void add_opers_comparison_pod(Dispatch_Engine &s) { register_function(s, &equals, "=="); register_function(s, ¬_equals, "!="); register_function(s, &less_than, "<"); register_function(s, &greater_than, ">"); register_function(s, &less_than_equals, "<="); register_function(s, &greater_than_equals, ">="); } static void add_opers_arithmetic_pod(Dispatch_Engine &s) { register_function(s, &add, "+"); register_function(s, &subtract, "-"); register_function(s, ÷, "/"); register_function(s, &multiply, "*"); } static void bootstrap(Dispatch_Engine &s) { s.register_type("void"); s.register_type("string"); add_basic_constructors(s, "bool"); add_basic_constructors(s, "string"); add_oper_assign(s); register_function(s, &to_string, "to_string"); register_function(s, &to_string, "to_string"); register_function(s, &unknown_assign, "="); bootstrap_pod_type(s, "double"); bootstrap_pod_type(s, "int"); bootstrap_pod_type(s, "size_t"); bootstrap_pod_type(s, "char"); bootstrap_pod_type(s, "int64_t"); add_opers_comparison_pod(s); add_opers_arithmetic_pod(s); add_oper_add(s); add_oper_add_equals (s); add_opers_comparison(s); register_function(s, &print, "print_string"); s.register_function(boost::function(boost::bind(&dump_system, boost::ref(s))), "dump_system"); s.register_function(boost::function(boost::bind(&dump_object, _1)), "dump_object"); register_function(s, &bool_and, "&&"); register_function(s, &bool_or, "||"); } }; } #endif