diff --git a/CMakeLists.txt b/CMakeLists.txt index accace0..1c1dd93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,11 @@ IF(BUILD_TESTING) "CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/" "CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/" ) + + add_executable(utility_test unittests/utility_test.cpp) + target_link_libraries(utility_test ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB}) + add_test(NAME Utility_Test COMMAND utility_test) + ENDIF(BUILD_TESTING) install(TARGETS chai stl_extra test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript ) diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp new file mode 100644 index 0000000..262d215 --- /dev/null +++ b/include/chaiscript/utility/utility.hpp @@ -0,0 +1,67 @@ +#ifndef CHAISCRIPT_UTILITY_UTILITY_HPP__ +#define CHAISCRIPT_UTILITY_UTILITY_HPP__ + +#include "../chaiscript.hpp" +#include +#include + +#define CHAISCRIPT_MODULE(_info) BOOST_PP_SEQ_ELEM(0, _info) + +#define CHAISCRIPT_CLASS_ELEM(_info) BOOST_PP_SEQ_ELEM(1, _info) + +#define CHAISCRIPT_METHOD(_info, _method) & CHAISCRIPT_CLASS_ELEM(_info) :: BOOST_PP_SEQ_ELEM(0, _method) + +#define CHAISCRIPT_METHOD_NAME(_info, _method) \ + BOOST_PP_SEQ_ELEM(3, _info) (BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(0, _method ) ) ) + +#define CHAISCRIPT_CLASS_NAME(_info) \ + BOOST_PP_STRINGIZE(CHAISCRIPT_CLASS_ELEM(_info)) + +#define CHAISCRIPT_METHOD_SIGNATURE_PART(_r, _info, _i, _method_part) \ + BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(_i, 1), < _method_part > ) + +#define CHAISCRIPT_METHOD_SIGNATURE(_info, _method) \ + BOOST_PP_SEQ_FOR_EACH_I(CHAISCRIPT_METHOD_SIGNATURE_PART, _info, _method) + +#define CHAISCRIPT_CLASS_CONSTRUCTOR(_r, _info, _constructor) \ + CHAISCRIPT_MODULE(_info) ->add BOOST_PP_LPAREN() chaiscript::constructor<_constructor>() BOOST_PP_COMMA() CHAISCRIPT_CLASS_NAME(_info) BOOST_PP_RPAREN() ; + +#define CHAISCRIPT_CLASS_METHOD(_r, _info, _method) \ + CHAISCRIPT_MODULE(_info) ->add BOOST_PP_LPAREN() chaiscript::fun CHAISCRIPT_METHOD_SIGNATURE(_info, _method) \ + BOOST_PP_LPAREN() CHAISCRIPT_METHOD(_info, _method) BOOST_PP_RPAREN() BOOST_PP_COMMA() CHAISCRIPT_METHOD_NAME(_info, _method)BOOST_PP_RPAREN() ; + +#define CHAISCRIPT_CLASS_CONSTRUCTORS(_info, _constructors) \ + BOOST_PP_SEQ_FOR_EACH(CHAISCRIPT_CLASS_CONSTRUCTOR, _info, _constructors) + +#define CHAISCRIPT_CLASS_METHODS(_info, _methods) \ + BOOST_PP_SEQ_FOR_EACH(CHAISCRIPT_CLASS_METHOD, _info, _methods) + +#define CHAISCRIPT_CLASS_EX(_module, _class_name, _class_name_translator, _method_name_translator, _constructors, _methods) \ + { \ + _module->add(chaiscript::user_type<_class_name>(), _class_name_translator (BOOST_PP_STRINGIZE(_class_name))); \ + CHAISCRIPT_CLASS_CONSTRUCTORS((_module)(_class_name), _constructors) \ + CHAISCRIPT_CLASS_METHODS((_module)(_class_name)(_class_name_translator)(_method_name_translator), _methods) \ + } + +#define CHAISCRIPT_CLASS(_module, _class_name, _constructors, _methods) \ + CHAISCRIPT_CLASS_EX(_module, _class_name, chaiscript::utility::class_name_translator, \ + chaiscript::utility::method_name_translator, _constructors, _methods) + +namespace chaiscript +{ + namespace utility + { + inline std::string class_name_translator(const std::string &t_name) + { + return t_name; + } + + inline std::string method_name_translator(const std::string &t_name) + { + return t_name; + } + } +} + +#endif + diff --git a/unittests/utility_test.cpp b/unittests/utility_test.cpp new file mode 100644 index 0000000..21294a1 --- /dev/null +++ b/unittests/utility_test.cpp @@ -0,0 +1,40 @@ +#include + +class Test +{ + public: + void function() {} + std::string function2() { return "Function2"; } + void function3() {} + std::string functionOverload(double) { return "double"; } + std::string functionOverload(int) { return "int"; } +}; + +int main() +{ + + chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module()); + + CHAISCRIPT_CLASS( m, + Test, + (Test ()) + (Test (const Test &)), + ((function)) + ((function2)) + ((function3)) + ((functionOverload)(std::string (Test::*)(double))) + ((functionOverload)(std::string (Test::*)(int))) + ); + + chaiscript::ChaiScript chai; + chai.add(m); + if (chai.eval("var t = Test(); t.function2(); ") == "Function2" + && chai.eval("var t = Test(); t.functionOverload(1); ") == "int" + && chai.eval("var t = Test(); t.functionOverload(1.1); ") == "double") + { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } + +}