From 370121a9ffb300c290fe842f45984e947ab77c8e Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 23 Jul 2009 04:35:15 +0000 Subject: [PATCH] add example.cpp to build for VC++, fix minor bug in passing of & parameters to functor<>, move bootstrap functions into bootstrap namespace and clean up function names and add "retro" support for reversing of ranges. --- include/chaiscript/dispatchkit/bootstrap.hpp | 733 +++++++++--------- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 481 +++++++----- .../chaiscript/dispatchkit/function_call.hpp | 4 +- .../chaiscript/language/chaiscript_engine.hpp | 1 + msvc/chai-example/chai-example.vcproj | 196 +++++ msvc/chaiscript/Boost.vsprops | 8 + msvc/chaiscript/chaiscript.sln | 6 + src/example.cpp | 2 +- 8 files changed, 851 insertions(+), 580 deletions(-) create mode 100644 msvc/chai-example/chai-example.vcproj diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 06ce0f85..8b2a886c 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -12,139 +12,141 @@ namespace chaiscript { - namespace detail + namespace bootstrap { - /** - * Set of helper functions for common operators - */ - template + namespace detail + { + /** + * Set of helper functions for common operators + */ + template Ret add(P1 p1, P2 p2) { return p1 + p2; } - template + template Ret subtract(P1 p1, P2 p2) { return p1 - p2; } - template + template Ret divide(P1 p1, P2 p2) { return p1 / p2; } - template + template Ret multiply(P1 p1, P2 p2) { return p1 * p2; } - template + template Ret modulus(P1 p1, P2 p2) { return p1 % p2; } - template + template P1 &assign(P1 &p1, const P2 &p2) { return (p1 = p2); } - template + template bool equals(P1 p1, P2 p2) { return p1 == p2; } - template + template bool not_equals(P1 p1, P2 p2) { return p1 != p2; } - template + template bool less_than(P1 p1, P2 p2) { return p1 < p2; } - template + template bool greater_than(P1 p1, P2 p2) { return p1 > p2; } - template + template bool less_than_equals(P1 p1, P2 p2) { return p1 <= p2; } - template + template bool greater_than_equals(P1 p1, P2 p2) { return p1 >= p2; } - template + template P1 ×equal(P1 &p1, const P2 &p2) { return (p1 *= p2); } - template + template P1 ÷sequal(P1 &p1, const P2 &p2) { return (p1 /= p2); } - template + template P1 &addsequal(P1 &p1, const P2 &p2) { return (p1 += p2); } - template + template P1 &subtractsequal(P1 &p1, const P2 &p2) { return (p1 -= p2); } - template + template P1 &prefixincrement(P1 &p1) { return (++p1); } - template + template P1 &prefixdecrement(P1 &p1) { return (--p1); } - template + template P1 &prefixnegate(P1 &p1) { return (p1); } - template + template P1 &prefixnot(P1 &p1) { return (p1); } - /* Special helpers for generating generic "POD" type operators - * The POD operators are needed for general support of C++ POD - * types without iterating out all possible combinations of operators - * (<, >, +, +=, *=, \=, -, <=, >=, ==) and types - * (char, uint8_t, int8_t, uint16_t, int16_t...) - */ - template + /* Special helpers for generating generic "POD" type operators + * The POD operators are needed for general support of C++ POD + * types without iterating out all possible combinations of operators + * (<, >, +, +=, *=, \=, -, <=, >=, ==) and types + * (char, uint8_t, int8_t, uint16_t, int16_t...) + */ + template P1 &assign_pod(P1 &p1, Boxed_POD_Value v) { if (v.m_isfloat) @@ -155,7 +157,7 @@ namespace chaiscript } } - template + template P1 construct_pod(Boxed_POD_Value v) { if (v.m_isfloat) @@ -166,7 +168,7 @@ namespace chaiscript } } - template + template P1 ×equal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) @@ -177,7 +179,7 @@ namespace chaiscript } } - template + template P1 ÷sequal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) @@ -188,7 +190,7 @@ namespace chaiscript } } - template + template P1 &addsequal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) @@ -199,7 +201,7 @@ namespace chaiscript } } - template + template P1 &subtractsequal_pod(P1 &p1, Boxed_POD_Value r) { if (r.m_isfloat) @@ -209,341 +211,341 @@ namespace chaiscript return p1 -= P1(r.i); } } - } + } - /** - * Add canonical form of "=" for type T - */ - template - ModulePtr add_oper_equals(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::equals), "="); - return m; - } + /** + * Add canonical form of "=" for type T + */ + template + ModulePtr oper_equals(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::equals), "="); + return m; + } - /** - * Add canonical form of "+" for type T - */ - template - ModulePtr add_oper_add(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::add), "+"); - return m; - } + /** + * Add canonical form of "+" for type T + */ + template + ModulePtr oper_add(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::add), "+"); + return m; + } - /** - * Add canonical form of "+=" for type T - */ - template - ModulePtr add_oper_add_equals(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::addsequal), "+="); - return m; - } + /** + * Add canonical form of "+=" for type T + */ + template + ModulePtr oper_add_equals(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::addsequal), "+="); + return m; + } - /** - * Add canonical form of "-" for type T - */ - template - ModulePtr add_oper_subtract(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::subtract), "-"); - return m; - } + /** + * Add canonical form of "-" for type T + */ + template + ModulePtr oper_subtract(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::subtract), "-"); + return m; + } - /** - * Add canonical form of "/" for type T - */ - template - ModulePtr add_oper_divide(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::divide), "/"); - return m; - } + /** + * Add canonical form of "/" for type T + */ + template + ModulePtr oper_divide(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::divide), "/"); + return m; + } - /** - * Add canonical form of "*" for type T - */ - template - ModulePtr add_oper_multiply(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::multiply), "*"); - return m; - } + /** + * Add canonical form of "*" for type T + */ + template + ModulePtr oper_multiply(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::multiply), "*"); + return m; + } - /** - * Add canonical form of "!=" for type T - */ - template - ModulePtr add_oper_not_equals(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::not_equals), "!="); - return m; - } + /** + * Add canonical form of "!=" for type T + */ + template + ModulePtr oper_not_equals(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::not_equals), "!="); + return m; + } - /** - * Add user defined assignment operator for T = U - */ - template - ModulePtr add_oper_assign_overload(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::assign), "="); - return m; - } + /** + * Add user defined assignment operator for T = U + */ + template + ModulePtr oper_assign_overload(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::assign), "="); + return m; + } - /** - * Add canonical form of "=" for type T - */ - template - ModulePtr add_oper_assign(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::assign), "="); - return m; - } + /** + * Add canonical form of "=" for type T + */ + template + ModulePtr oper_assign(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::assign), "="); + return m; + } - /** - * Add assignment operator for T = POD. - */ - template - ModulePtr add_oper_assign_pod(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::assign_pod), "="); - return m; - } + /** + * Add assignment operator for T = POD. + */ + template + ModulePtr oper_assign_pod(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::assign_pod), "="); + return m; + } - /** - * Add canonical form of "<" for type T - */ - template - ModulePtr add_oper_less_than(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::less_than), "<"); - return m; - } + /** + * Add canonical form of "<" for type T + */ + template + ModulePtr oper_less_than(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::less_than), "<"); + return m; + } - /** - * Add canonical form of ">" for type T - */ - template - ModulePtr add_oper_greater_than(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::greater_than), ">"); - return m; - } + /** + * Add canonical form of ">" for type T + */ + template + ModulePtr oper_greater_than(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::greater_than), ">"); + return m; + } - /** - * Add canonical form of "<=" for type T - */ - template - ModulePtr add_oper_less_than_equals(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::less_than_equals), "<="); - return m; - } + /** + * Add canonical form of "<=" for type T + */ + template + ModulePtr oper_less_than_equals(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::less_than_equals), "<="); + return m; + } - /** - * Add canonical form of ">=" for type T - */ - template - ModulePtr add_oper_greater_than_equals(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::greater_than_equals), ">="); - return m; - } + /** + * Add canonical form of ">=" for type T + */ + template + ModulePtr oper_greater_than_equals(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::greater_than_equals), ">="); + return m; + } - /** - * Add user defined comparison operators for T and R. - * Examples: T < R, T == R, etc. - */ - template - ModulePtr add_opers_comparison_overload(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::equals), "=="); - m->add(fun(&detail::not_equals), "!="); - m->add(fun(&detail::less_than), "<"); - m->add(fun(&detail::greater_than), ">"); - m->add(fun(&detail::less_than_equals), "<="); - m->add(fun(&detail::greater_than_equals), ">="); - return m; - } + /** + * Add user defined comparison operators for T and R. + * Examples: T < R, T == R, etc. + */ + template + ModulePtr opers_comparison_overload(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::equals), "=="); + m->add(fun(&detail::not_equals), "!="); + m->add(fun(&detail::less_than), "<"); + m->add(fun(&detail::greater_than), ">"); + m->add(fun(&detail::less_than_equals), "<="); + m->add(fun(&detail::greater_than_equals), ">="); + return m; + } - /** - * Add canonical forms of all comparison operators for type T - */ - template - ModulePtr add_opers_comparison(ModulePtr m = ModulePtr(new Module())) - { - add_opers_comparison_overload(m); - return m; - } + /** + * Add canonical forms of all comparison operators for type T + */ + template + ModulePtr opers_comparison(ModulePtr m = ModulePtr(new Module())) + { + opers_comparison_overload(m); + return m; + } - /** - * Add all arithmetic operators that return a type of Ret, taking - * a lhs of T and a rhs of R, when possible. - * examples: Ret = T + R; - * ++T - * T *= R; - */ - template - ModulePtr add_opers_arithmetic_overload(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::add), "+"); - m->add(fun(&detail::subtract), "-"); - m->add(fun(&detail::divide), "/"); - m->add(fun(&detail::multiply), "*"); - m->add(fun(&detail::timesequal), "*="); - m->add(fun(&detail::dividesequal), "/="); - m->add(fun(&detail::subtractsequal), "-="); - m->add(fun(&detail::addsequal), "+="); - m->add(fun(&detail::prefixincrement), "++"); - m->add(fun(&detail::prefixdecrement), "--"); - m->add(fun(&detail::prefixnegate), "-"); - m->add(fun(&detail::prefixnot), "!"); - return m; - } + /** + * Add all arithmetic operators that return a type of Ret, taking + * a lhs of T and a rhs of R, when possible. + * examples: Ret = T + R; + * ++T + * T *= R; + */ + template + ModulePtr opers_arithmetic_overload(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::add), "+"); + m->add(fun(&detail::subtract), "-"); + m->add(fun(&detail::divide), "/"); + m->add(fun(&detail::multiply), "*"); + m->add(fun(&detail::timesequal), "*="); + m->add(fun(&detail::dividesequal), "/="); + m->add(fun(&detail::subtractsequal), "-="); + m->add(fun(&detail::addsequal), "+="); + m->add(fun(&detail::prefixincrement), "++"); + m->add(fun(&detail::prefixdecrement), "--"); + m->add(fun(&detail::prefixnegate), "-"); + m->add(fun(&detail::prefixnot), "!"); + return m; + } - /** - * Add arithmetic assign operators for POD types: - * example: POD *= T, POD /= T - */ - template - ModulePtr add_opers_arithmetic_modify_pod(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::timesequal_pod), "*="); - m->add(fun(&detail::dividesequal_pod), "/="); - m->add(fun(&detail::subtractsequal_pod), "-="); - m->add(fun(&detail::addsequal_pod), "+="); - return m; - } + /** + * Add arithmetic assign operators for POD types: + * example: POD *= T, POD /= T + */ + template + ModulePtr opers_arithmetic_modify_pod(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::timesequal_pod), "*="); + m->add(fun(&detail::dividesequal_pod), "/="); + m->add(fun(&detail::subtractsequal_pod), "-="); + m->add(fun(&detail::addsequal_pod), "+="); + return m; + } - /** - * Add a copy constructor for type T, also creates the standard - * function "clone" for the type. "clone" is a synonym for - * the copy constructor. - */ - template - ModulePtr add_copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module())) + /** + * Add a copy constructor for type T, also creates the standard + * function "clone" for the type. "clone" is a synonym for + * the copy constructor. + */ + template + ModulePtr copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module())) { m->add(constructor(), type); m->add(constructor(), "clone"); return m; } - /** - * Add default and copy constructors (including "clone") for type T - */ - template - ModulePtr add_basic_constructors(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(constructor(), type); - add_copy_constructor(type, m); - return m; - } - - /** - * Add POD type constructor for type T. ie: T = type(POD) - */ - template - ModulePtr add_construct_pod(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::construct_pod), type); - return m; - } - - /** - * add user defined single parameter constructor for type T. - * T = type(const U &) - */ - template - ModulePtr add_constructor_overload(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(constructor(), type); - return m; - } - - /** - * Add canonical forms of all arithmetic operators for type T - */ - template - ModulePtr add_opers_arithmetic(ModulePtr m = ModulePtr(new Module())) - { - add_opers_arithmetic_overload(m); - return m; - } - - /** - * to_string function for internal use. Uses ostream operator<< - */ - template - std::string to_string(Input i) - { - return boost::lexical_cast(i); - } - - /** - * Boolean specialization of internal to_string function - */ - template<> std::string to_string(bool b) - { - if (b) + /** + * Add default and copy constructors (including "clone") for type T + */ + template + ModulePtr basic_constructors(const std::string &type, ModulePtr m = ModulePtr(new Module())) { - return "true"; - } else { - return "false"; + m->add(constructor(), type); + copy_constructor(type, m); + return m; } - } - /** - * Internal function for converting from a string to a value - * uses ostream operator >> to perform the conversion - */ - template - Input parse_string(const std::string &i) - { - return boost::lexical_cast(i); - } + /** + * Add POD type constructor for type T. ie: T = type(POD) + */ + template + ModulePtr construct_pod(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&detail::construct_pod), type); + return m; + } - /** - * Add all common functions for a POD type. All operators, and - * common conversions - */ - template - ModulePtr bootstrap_pod_type(const std::string &name, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), name); - add_basic_constructors(name, m); - add_oper_assign(m); - add_oper_assign_pod(m); - add_construct_pod(name, m); - add_opers_arithmetic(m); - add_opers_arithmetic_modify_pod(m); - m->add(fun(&to_string), "to_string"); - m->add(fun(&parse_string), "to_" + name); - return m; - } + /** + * add user defined single parameter constructor for type T. + * T = type(const U &) + */ + template + ModulePtr constructor_overload(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(constructor(), type); + return m; + } - /** - * "clone" function for a shared_ptr type. This is used in the case - * where you do not want to make a deep copy of an object during cloning - * but want to instead maintain the shared_ptr. It is needed internally - * for handling of Proxy_Function object (that is, - * function variables. - */ - template + /** + * Add canonical forms of all arithmetic operators for type T + */ + template + ModulePtr opers_arithmetic(ModulePtr m = ModulePtr(new Module())) + { + opers_arithmetic_overload(m); + return m; + } + + /** + * to_string function for internal use. Uses ostream operator<< + */ + template + std::string to_string(Input i) + { + return boost::lexical_cast(i); + } + + /** + * Boolean specialization of internal to_string function + */ + template<> std::string to_string(bool b) + { + if (b) + { + return "true"; + } else { + return "false"; + } + } + + /** + * Internal function for converting from a string to a value + * uses ostream operator >> to perform the conversion + */ + template + Input parse_string(const std::string &i) + { + return boost::lexical_cast(i); + } + + /** + * Add all common functions for a POD type. All operators, and + * common conversions + */ + template + ModulePtr bootstrap_pod_type(const std::string &name, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), name); + basic_constructors(name, m); + oper_assign(m); + oper_assign_pod(m); + construct_pod(name, m); + opers_arithmetic(m); + opers_arithmetic_modify_pod(m); + m->add(fun(&to_string), "to_string"); + m->add(fun(&parse_string), "to_" + name); + return m; + } + + /** + * "clone" function for a shared_ptr type. This is used in the case + * where you do not want to make a deep copy of an object during cloning + * but want to instead maintain the shared_ptr. It is needed internally + * for handling of Proxy_Function object (that is, + * function variables. + */ + template boost::shared_ptr shared_ptr_clone(boost::shared_ptr f) { return f; } - /** - * Assignment function for shared_ptr objects, does not perform a copy of the - * object pointed to, instead maintains the shared_ptr concept. - * Similar to shared_ptr_clone. Used for Proxy_Function. - */ - template + /** + * Assignment function for shared_ptr objects, does not perform a copy of the + * object pointed to, instead maintains the shared_ptr concept. + * Similar to shared_ptr_clone. Used for Proxy_Function. + */ + template Boxed_Value ptr_assign(Boxed_Value lhs, boost::shared_ptr rhs) { lhs.assign(Boxed_Value(rhs)); @@ -551,16 +553,16 @@ namespace chaiscript return lhs; } - /** - * Class consisting of only static functions. All default bootstrapping occurs - * from this class. - */ - class Bootstrap - { + /** + * Class consisting of only static functions. All default bootstrapping occurs + * from this class. + */ + class Bootstrap + { private: /** - * Function allowing for assignment of an unknown type to any other value - */ + * Function allowing for assignment of an unknown type to any other value + */ static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs) { if (lhs.is_unknown()) @@ -582,9 +584,9 @@ namespace chaiscript } /** - * Add all comparison operators for POD types - */ - static void add_opers_comparison_pod(ModulePtr m = ModulePtr(new Module())) + * Add all comparison operators for POD types + */ + static void opers_comparison_pod(ModulePtr m = ModulePtr(new Module())) { m->add(fun(&detail::equals), "=="); m->add(fun(&detail::not_equals), "!="); @@ -595,9 +597,9 @@ namespace chaiscript } /** - * Add all arithmetic operators for PODs - */ - static void add_opers_arithmetic_pod(ModulePtr m = ModulePtr(new Module())) + * Add all arithmetic operators for PODs + */ + static void opers_arithmetic_pod(ModulePtr m = ModulePtr(new Module())) { m->add(fun(&detail::add), "+"); m->add(fun(&detail::subtract), "-"); @@ -606,10 +608,10 @@ namespace chaiscript } /** - * Create a bound function object. The first param is the function to bind - * the remaining parameters are the args to bind into the - * result - */ + * Create a bound function object. The first param is the function to bind + * the remaining parameters are the args to bind into the + * result + */ static Boxed_Value bind_function(const std::vector ¶ms) { if (params.size() < 2) @@ -620,13 +622,13 @@ namespace chaiscript Proxy_Function f = boxed_cast(params[0]); return Boxed_Value(Proxy_Function(new Bound_Function(f, - std::vector(params.begin() + 1, params.end())))); + std::vector(params.begin() + 1, params.end())))); } /** - * Returns true if a call can be made that consists of the first parameter - * (the function) with the remaining parameters as its arguments. - */ + * Returns true if a call can be made that consists of the first parameter + * (the function) with the remaining parameters as its arguments. + */ static Boxed_Value call_exists(const std::vector ¶ms) { if (params.size() < 1) @@ -647,8 +649,8 @@ namespace chaiscript public: /** - * perform all common bootstrap functions for std::string, void and POD types - */ + * perform all common bootstrap functions for std::string, void and POD types + */ static ModulePtr bootstrap(ModulePtr m = ModulePtr(new Module())) { m->add(user_type(), "void"); @@ -657,9 +659,9 @@ namespace chaiscript m->add(user_type(), "PODObject"); m->add(user_type(), "function"); - add_basic_constructors("bool", m); - add_oper_assign(m); - add_oper_assign(m); + basic_constructors("bool", m); + oper_assign(m); + oper_assign(m); m->add(fun(&to_string), "internal_to_string"); m->add(fun(&to_string), "internal_to_string"); @@ -671,8 +673,8 @@ namespace chaiscript bootstrap_pod_type("char", m); bootstrap_pod_type("int64_t", m); - add_opers_comparison_pod(m); - add_opers_arithmetic_pod(m); + opers_comparison_pod(m); + opers_arithmetic_pod(m); m->add(fun(&detail::modulus), "%"); @@ -680,19 +682,20 @@ namespace chaiscript m->add(fun(&println), "println_string"); m->add(Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&bind_function, _1))), - "bind"); + "bind"); m->add(fun(&shared_ptr_clone), "clone"); m->add(fun(&ptr_assign), "="); m->add(Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&call_exists, _1))), - "call_exists"); + "call_exists"); m->add(fun(&type_match), "type_match"); return m; } - }; + }; + } } #endif diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index ad48a972..bd298aa0 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -5,13 +5,13 @@ // http://www.chaiscript.com /** - * This file contains utility functions for registration of STL container - * classes. The methodology used is based on the SGI STL concepts. - * http://www.sgi.com/tech/stl/table_of_contents.html - */ +* This file contains utility functions for registration of STL container +* classes. The methodology used is based on the SGI STL concepts. +* http://www.sgi.com/tech/stl/table_of_contents.html +*/ -#ifndef __stl_hpp_type -#define __stl_hpp___type +#ifndef __bootstrap_stl_hpp__ +#define __bootstrap_stl_hpp__ #include "dispatchkit.hpp" #include "register_function.hpp" @@ -19,25 +19,29 @@ namespace chaiscript { - /** - * Input_Range, based on the D concept of ranges. - * \todo Update the Range code to base its capabilities on - * the user_typetraits of the iterator passed in - */ - template - struct Input_Range + namespace bootstrap + { + /** + * Bidir_Range, based on the D concept of ranges. + * \todo Update the Range code to base its capabilities on + * the user_typetraits of the iterator passed in + */ + template + struct Bidir_Range { - Input_Range(Container &c) + typedef typename std::iterator_traits::reference reference_type; + + Bidir_Range(Container &c) : m_begin(c.begin()), m_end(c.end()) { } - Input_Range(typename Container::iterator itr) + Bidir_Range(typename Container::iterator itr) : m_begin(itr), m_end(itr) { } - Input_Range(const std::pair &t_p) + Bidir_Range(const std::pair &t_p) : m_begin(t_p.first), m_end(t_p.second) { } @@ -56,7 +60,16 @@ namespace chaiscript ++m_begin; } - typename std::iterator_traits::reference front() const + void pop_back() + { + if (empty()) + { + throw std::range_error("Range empty"); + } + --m_end; + } + + reference_type front() const { if (empty()) { @@ -65,127 +78,170 @@ namespace chaiscript return *m_begin; } + reference_type back() const + { + if (empty()) + { + throw std::range_error("Range empty"); + } + Container::iterator pos = m_end; + --pos; + return *(pos); + } + typename Container::iterator m_begin; typename Container::iterator m_end; }; - - /** - * Add Input_Range support for the given ContainerType - */ - template + template + struct Retro + { + Retro(const Range &r) + : m_r(r) + {} + + bool empty() { return m_r.empty(); } + void pop_front() { m_r.pop_back(); } + void pop_back() { m_r.pop_front(); } + typename Range::reference_type front() { return m_r.back(); } + typename Range::reference_type back() { return m_r.front(); } + + private: + Range m_r; + }; + + + /** + * Add Bidir_Range support for the given ContainerType + */ + template ModulePtr input_range_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { - m->add(user_type >(), type + "_Range"); + m->add(user_type >(), type + "_Range"); + m->add(user_type > >(), type + "_Retro_Range"); m->add(user_type(), type+"_Iterator"); - m->add(constructor (ContainerType &)>(), "range"); - m->add(constructor (typename ContainerType::iterator)>(), "range"); + m->add(constructor (ContainerType &)>(), "range"); + m->add(constructor (typename ContainerType::iterator)>(), "range"); typedef std::pair ItrPair; - m->add(constructor (const ItrPair &)>(), "range"); + m->add(constructor (const ItrPair &)>(), "range"); m->add(user_type(), type+"_Iterator_Pair"); - m->add(fun(&Input_Range::empty), "empty"); - m->add(fun(&Input_Range::pop_front), "pop_front"); - m->add(fun(&Input_Range::front), "front"); - m->add(constructor (const Input_Range &)>(), "clone"); + m->add(fun(&Bidir_Range::empty), "empty"); + m->add(fun(&Bidir_Range::pop_front), "pop_front"); + m->add(fun(&Bidir_Range::front), "front"); + m->add(fun(&Bidir_Range::pop_back), "pop_back"); + m->add(fun(&Bidir_Range::back), "back"); + + m->add(fun(&Retro >::empty), "empty"); + m->add(fun(&Retro >::pop_front), "pop_front"); + m->add(fun(&Retro >::front), "front"); + m->add(fun(&Retro >::pop_back), "pop_back"); + m->add(fun(&Retro >::back), "back"); + + m->add(constructor > (const Bidir_Range &)>(), "retro"); + + + m->add(constructor (const Bidir_Range &)>(), "clone"); + m->add(constructor > (const Retro > &)>(), "clone"); + return m; } - - /** - * Add reversible_container concept to the given ContainerType - * http://www.sgi.com/tech/stl/ReversibleContainer.html - */ - template - ModulePtr reversible_container_type(const std::string &, ModulePtr m = ModulePtr(new Module())) - { - return m; - } - /** - * Add random_access_container concept to the given ContainerType - * http://www.sgi.com/tech/stl/RandomAccessContainer.html - */ - template - ModulePtr random_access_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - reversible_container_type(type, m); - typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); + /** + * Add reversible_container concept to the given ContainerType + * http://www.sgi.com/tech/stl/ReversibleContainer.html + */ + template + ModulePtr reversible_container_type(const std::string &, ModulePtr m = ModulePtr(new Module())) + { + return m; + } - //In the interest of runtime safety for the m, we prefer the at() method for [] access, - //to throw an exception in an out of bounds condition. - m->add( + /** + * Add random_access_container concept to the given ContainerType + * http://www.sgi.com/tech/stl/RandomAccessContainer.html + */ + template + ModulePtr random_access_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + reversible_container_type(type, m); + typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); + + //In the interest of runtime safety for the m, we prefer the at() method for [] access, + //to throw an exception in an out of bounds condition. + m->add( fun(boost::function(indexoper(&ContainerType::at))), "[]"); - m->add( + m->add( fun(boost::function(indexoper(&ContainerType::operator[]))), "at"); - return m; - } + return m; + } - /** - * Add assignable concept to the given ContainerType - * http://www.sgi.com/tech/stl/Assignable.html - */ - template - ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - add_basic_constructors(type, m); - add_oper_assign(m); - return m; - } + /** + * Add assignable concept to the given ContainerType + * http://www.sgi.com/tech/stl/Assignable.html + */ + template + ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + basic_constructors(type, m); + oper_assign(m); + return m; + } - /** - * Add container concept to the given ContainerType - * http://www.sgi.com/tech/stl/Container.html - */ - template - ModulePtr container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - assignable_type(type, m); + /** + * Add container concept to the given ContainerType + * http://www.sgi.com/tech/stl/Container.html + */ + template + ModulePtr container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + assignable_type(type, m); - m->add(fun(&ContainerType::size), "size"); - m->add(fun(&ContainerType::max_size), "max_size"); - m->add(fun(&ContainerType::empty), "empty"); + m->add(fun(&ContainerType::size), "size"); + m->add(fun(&ContainerType::max_size), "max_size"); + m->add(fun(&ContainerType::empty), "empty"); - return m; - } + return m; + } - /** - * Add forward container concept to the given ContainerType - * http://www.sgi.com/tech/stl/ForwardContainer.html - */ - template - ModulePtr forward_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - input_range_type(type, m); - container_type(type, m); + /** + * Add forward container concept to the given ContainerType + * http://www.sgi.com/tech/stl/ForwardContainer.html + */ + template + ModulePtr forward_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + input_range_type(type, m); + container_type(type, m); - return m; - } + return m; + } - /** - * Add default constructable concept to the given Type - * http://www.sgi.com/tech/stl/DefaultConstructible.html - */ - template - ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(constructor(), type); - return m; - } + /** + * Add default constructable concept to the given Type + * http://www.sgi.com/tech/stl/DefaultConstructible.html + */ + template + ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(constructor(), type); + return m; + } - /** - * Algorithm for inserting at a specific position into a container - */ - template + /** + * Algorithm for inserting at a specific position into a container + */ + template void insert_at(Type &container, int pos, const typename Type::value_type &v) { typename Type::iterator itr = container.begin(); typename Type::iterator end = container.end(); - + if (pos < 0 || std::distance(itr, end) < pos) { throw std::range_error("Cannot insert past end of range"); @@ -195,15 +251,15 @@ namespace chaiscript container.insert(itr, v); } - /** - * Algorithm for erasing a specific position from a container - */ - template + /** + * Algorithm for erasing a specific position from a container + */ + template void erase_at(Type &container, int pos) { typename Type::iterator itr = container.begin(); typename Type::iterator end = container.end(); - + if (pos < 0 || std::distance(itr, end) < (pos-1)) { throw std::range_error("Cannot erase past end of range"); @@ -213,75 +269,75 @@ namespace chaiscript container.erase(itr); } - /** - * Add sequence concept to the given ContainerType - * http://www.sgi.com/tech/stl/Sequence.html - */ - template - ModulePtr sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - forward_container_type(type, m); - default_constructible_type(type, m); - - std::string insert_name; - if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) + /** + * Add sequence concept to the given ContainerType + * http://www.sgi.com/tech/stl/Sequence.html + */ + template + ModulePtr sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { - insert_name = "insert_ref_at"; - } else { - insert_name = "insert_at"; + forward_container_type(type, m); + default_constructible_type(type, m); + + std::string insert_name; + if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) + { + insert_name = "insert_ref_at"; + } else { + insert_name = "insert_at"; + } + + m->add(fun(&insert_at), insert_name); + m->add(fun(&erase_at), "erase_at"); + + return m; } - m->add(fun(&insert_at), insert_name); - m->add(fun(&erase_at), "erase_at"); - - return m; - } - - /** - * Add back insertion sequence concept to the given ContainerType - * http://www.sgi.com/tech/stl/BackInsertionSequence.html - */ - template - ModulePtr back_insertion_sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - sequence_type(type, m); - - - typedef typename ContainerType::reference (ContainerType::*backptr)(); - - m->add(fun(backptr(&ContainerType::back)), "back"); - - std::string push_back_name; - if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) + /** + * Add back insertion sequence concept to the given ContainerType + * http://www.sgi.com/tech/stl/BackInsertionSequence.html + */ + template + ModulePtr back_insertion_sequence_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { - push_back_name = "push_back_ref"; - } else { - push_back_name = "push_back"; + sequence_type(type, m); + + + typedef typename ContainerType::reference (ContainerType::*backptr)(); + + m->add(fun(backptr(&ContainerType::back)), "back"); + + std::string push_back_name; + if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) + { + push_back_name = "push_back_ref"; + } else { + push_back_name = "push_back"; + } + + m->add(fun(&ContainerType::push_back), push_back_name); + m->add(fun(&ContainerType::pop_back), "pop_back"); + return m; } - m->add(fun(&ContainerType::push_back), push_back_name); - m->add(fun(&ContainerType::pop_back), "pop_back"); - return m; - } + /** + * Create a vector type with associated concepts + * http://www.sgi.com/tech/stl/Vector.html + */ + template + ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type); + random_access_container_type(type, m); + back_insertion_sequence_type(type, m); + return m; + } - /** - * Create a vector type with associated concepts - * http://www.sgi.com/tech/stl/Vector.html - */ - template - ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), type); - random_access_container_type(type, m); - back_insertion_sequence_type(type, m); - return m; - } - - /** - * Create a vector type with associated concepts - * http://www.sgi.com/tech/stl/Vector.html - */ - template + /** + * Create a vector type with associated concepts + * http://www.sgi.com/tech/stl/Vector.html + */ + template ModulePtr associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { forward_container_type(type, m); @@ -289,11 +345,11 @@ namespace chaiscript return m; } - /** - * bootstrap a given PairType - * http://www.sgi.com/tech/stl/pair.html - */ - template + /** + * bootstrap a given PairType + * http://www.sgi.com/tech/stl/pair.html + */ + template ModulePtr pair_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { m->add(user_type(), type); @@ -310,11 +366,11 @@ namespace chaiscript } - /** - * Add pair associative container concept to the given ContainerType - * http://www.sgi.com/tech/stl/PairAssociativeContainer.html - */ - template + /** + * Add pair associative container concept to the given ContainerType + * http://www.sgi.com/tech/stl/PairAssociativeContainer.html + */ + template ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { associative_container_type(type, m); @@ -323,11 +379,11 @@ namespace chaiscript return m; } - /** - * Add unique associative container concept to the given ContainerType - * http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html - */ - template + /** + * Add unique associative container concept to the given ContainerType + * http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html + */ + template ModulePtr unique_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { associative_container_type(type, m); @@ -336,28 +392,28 @@ namespace chaiscript return m; } - /** - * Add sorted associative container concept to the given ContainerType - * http://www.sgi.com/tech/stl/SortedAssociativeContainer.html - */ - template + /** + * Add sorted associative container concept to the given ContainerType + * http://www.sgi.com/tech/stl/SortedAssociativeContainer.html + */ + template ModulePtr sorted_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { typedef std::pair - (ContainerType::*eq_range)(const typename ContainerType::key_type &); + (ContainerType::*eq_range)(const typename ContainerType::key_type &); reversible_container_type(type, m); associative_container_type(type, m); m->add(fun(eq_range(&ContainerType::equal_range)), "equal_range"); return m; - } + } - /** - * Add unique sorted associative container concept to the given ContainerType - * http://www.sgi.com/tech/stl/UniqueSortedAssociativeContainer.html - */ - template + /** + * Add unique sorted associative container concept to the given ContainerType + * http://www.sgi.com/tech/stl/UniqueSortedAssociativeContainer.html + */ + template ModulePtr unique_sorted_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { sorted_associative_container_type(type, m); @@ -366,11 +422,11 @@ namespace chaiscript return m; } - /** - * Add a MapType container - * http://www.sgi.com/tech/stl/Map.html - */ - template + /** + * Add a MapType container + * http://www.sgi.com/tech/stl/Map.html + */ + template ModulePtr map_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { m->add(user_type(), type); @@ -381,17 +437,17 @@ namespace chaiscript return m; } - /** - * Add a String container - * http://www.sgi.com/tech/stl/basic_string.html - */ - template + /** + * Add a String container + * http://www.sgi.com/tech/stl/basic_string.html + */ + template ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { m->add(user_type(), type); - add_oper_add(m); - add_oper_add_equals(m); - add_opers_comparison(m); + oper_add(m); + oper_add_equals(m); + opers_comparison(m); random_access_container_type(type, m); sequence_type(type, m); typedef typename String::size_type (String::*find_func)(const String &, typename String::size_type) const; @@ -404,6 +460,7 @@ namespace chaiscript return m; } + } } #endif diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index bfb47c09..048d7b73 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -6,7 +6,7 @@ #include -#define addparam(z,n,text) params.push_back(Boxed_Value(BOOST_PP_CAT(p, n) )); +#define addparam(z,n,text) params.push_back(boost::is_reference::value?Boxed_Value(boost::ref(BOOST_PP_CAT(p, n))):Boxed_Value(BOOST_PP_CAT(p, n) )); #define curry(z,n,text) BOOST_PP_CAT(_, BOOST_PP_INC(n)) @@ -79,7 +79,7 @@ namespace chaiscript boost::function functor(const std::vector > &funcs) { - FunctionType *p; + FunctionType *p=0; return build_function_caller_helper(p, funcs); } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index ebb7b1e9..0ffb0d05 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -140,6 +140,7 @@ namespace chaiscript * Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude. */ void build_eval_system() { + using namespace bootstrap; engine.add(Bootstrap::bootstrap()); engine.add(fun(boost::function(boost::bind(&dump_system, boost::ref(engine)))), "dump_system"); diff --git a/msvc/chai-example/chai-example.vcproj b/msvc/chai-example/chai-example.vcproj new file mode 100644 index 00000000..df85bf7e --- /dev/null +++ b/msvc/chai-example/chai-example.vcproj @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/chaiscript/Boost.vsprops b/msvc/chaiscript/Boost.vsprops index a4a7ba48..fd9148b7 100644 --- a/msvc/chaiscript/Boost.vsprops +++ b/msvc/chaiscript/Boost.vsprops @@ -8,4 +8,12 @@ Name="VCCLCompilerTool" AdditionalIncludeDirectories=""C:\Programming\Boost\include\boost-1_38"" /> + + diff --git a/msvc/chaiscript/chaiscript.sln b/msvc/chaiscript/chaiscript.sln index a019b4e0..d8fced7c 100644 --- a/msvc/chaiscript/chaiscript.sln +++ b/msvc/chaiscript/chaiscript.sln @@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chaiscript", "chaiscript.vcproj", "{46FD9DC7-2DA9-4C17-ADE4-E3A18C46E87B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chai-example", "..\chai-example\chai-example.vcproj", "{CE422E94-B360-4588-8C65-6A9BE80798F9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -13,6 +15,10 @@ Global {46FD9DC7-2DA9-4C17-ADE4-E3A18C46E87B}.Debug|Win32.Build.0 = Debug|Win32 {46FD9DC7-2DA9-4C17-ADE4-E3A18C46E87B}.Release|Win32.ActiveCfg = Release|Win32 {46FD9DC7-2DA9-4C17-ADE4-E3A18C46E87B}.Release|Win32.Build.0 = Release|Win32 + {CE422E94-B360-4588-8C65-6A9BE80798F9}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE422E94-B360-4588-8C65-6A9BE80798F9}.Debug|Win32.Build.0 = Debug|Win32 + {CE422E94-B360-4588-8C65-6A9BE80798F9}.Release|Win32.ActiveCfg = Release|Win32 + {CE422E94-B360-4588-8C65-6A9BE80798F9}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/example.cpp b/src/example.cpp index c726a82c..de41c7d8 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -125,7 +125,7 @@ int main(int argc, char *argv[]) { //Ability to create our own container types when needed. std::vector and std::map are //mostly supported currently - chai.add(vector_type >("IntVector")); + chai.add(bootstrap::vector_type >("IntVector")); }