diff --git a/.travis.yml b/.travis.yml index 0fcfba36..dacb8f18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,13 @@ language: cpp compiler: - gcc - - clang before_install: - - sudo apt-get install libboost-dev libboost-all-dev + - sudo pip install cpp-coveralls --use-mirrors script: - - mkdir build - - cd build - - cmake ../ + - cmake -D ENABLE_COVERAGE:BOOL=TRUE -D CMAKE_BUILD_TYPE:STRING=Debug -D USE_LIBCXX:BOOL=FALSE . - make - make test + - coveralls -x hpp notifications: recipients: - jason@emptycrate.com diff --git a/CMakeLists.txt b/CMakeLists.txt index 394c1eaa..6626fc0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,19 @@ cmake_minimum_required(VERSION 2.8) project(chaiscript) -option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE) +# MINGW does not yet support C++11's concurrency features +if (MINGW) + option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" FALSE) +else() + option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE) +endif() + +if (CMAKE_COMPILER_IS_GNUCC) + option(ENABLE_COVERAGE "Enable Coverage Reporting in GCC" FALSE) +endif() + + + option(BUILD_MODULES "Build Extra Modules (stl, reflection)" TRUE) option(BUILD_SAMPLES "Build Samples Folder" FALSE) @@ -16,21 +28,20 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.md") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt") -set(CPACK_PACKAGE_VERSION_MAJOR 4) +set(CPACK_PACKAGE_VERSION_MAJOR 5) set(CPACK_PACKAGE_VERSION_MINOR 3) set(CPACK_PACKAGE_VERSION_PATCH 0) + set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval") set(CPACK_PACKAGE_VENDOR "ChaiScript.com") set(CPACK_PACKAGE_CONTACT "contact@chaiscript.com") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "An embedded scripting language for C++") -set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev (>=1.36.0)") set(CPACK_DEBIAN_PACKAGE_SECTION "devel") set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") set(CPACK_RPM_PACKAGE_LICENSE "BSD") set(CPACK_RPM_PACKAGE_GROUP "Programming") -set(CPACK_RPM_PACKAGE_REQUIRES "boost-devel >= 1.36.0, boost-thread >= 1.36.0") set(CHAI_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}) @@ -39,7 +50,17 @@ configure_file(Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile) include(CTest) include(CPack) -find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib) +include(cmake/CheckCXX11Features.cmake) + +if(NOT MINGW) + find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib) +endif() + +if(HAS_CXX11_VARIADIC_TEMPLATES) + message(STATUS "Variadic Template support detected") +else() + message(SEND_ERROR "The selected compiler does not support the C++11 feature Variadic Templates.") +endif() enable_testing() @@ -55,85 +76,129 @@ else(READLINE_LIBRARY) set (READLINE_FLAG ) endif(READLINE_LIBRARY) +SET(EXTRA_LINKER_FLAGS "") + +if (CMAKE_COMPILER_IS_GNUCC) + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + + if (GCC_VERSION VERSION_LESS 4.8) + SET(CPP11_FLAG "-std=c++0x") + else() + SET(CPP11_FLAG "-std=c++11") + endif() + + if (ENABLE_COVERAGE) + add_definitions(-fprofile-arcs -ftest-coverage) + SET(EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} "-fprofile-arcs -ftest-coverage") + # SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "-fprofile-arcs -ftest-coverage") + endif() + + +else() + SET(CPP11_FLAG "-std=c++11") +endif() + if(MSVC) add_definitions(/W4) - if(CMAKE_CL_64) - add_definitions(/bigobj) - endif() + add_definitions(/bigobj) + # Note on MSVC compiler flags. + # The code base selective disables warnings as necessary when the compiler is complaining too much + # about something that is perfectly valid, or there is simply no technical way around it + # This particular warning, C4503 is in regards to the decorated names that MSVC generates internally. + # The error did not come up until the move to C++11, but the compiler doesn't give enough information + # to determine where the error is coming from, and the internet provides no real information for + # how to workaround or fix the error. So I'm disabling it globally. + ADD_DEFINITIONS(/wd4503) else() - add_definitions(-Wall -Wextra -Wshadow -pedantic) - + add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic ${CPP11_FLAG}) + if (APPLE) - # -Wno-missing-field-initializers is for boost on macos - add_definitions(-Wno-missing-field-initializers -Wno-sign-compare) + add_definitions(-Wno-sign-compare) endif() endif() +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + option(USE_LIBCXX "Use clang's libcxx" TRUE) + + if (USE_LIBCXX) + add_definitions(-stdlib=libc++) + set (EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} ${CPP11_FLAG} -stdlib=libc++) + else () + set (EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} ${CPP11_FLAG}) + endif() +elseif(CMAKE_COMPILER_IS_GNUCC) + set (EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} ${CPP11_FLAG}) +endif() + +# limitations in MinGW require us to make an optimized build +# for the sake of object sizes or something +if (MINGW) + add_definitions(-O3) +endif() + include_directories(include) -set(Boost_ADDITIONAL_VERSIONS "1.44" "1.44.0" "1.43" "1.43.0" "1.42" "1.42.0" "1.41") -set(Boost_USE_MULTITHREADED ON) -set (Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp) +set (Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.chai include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp) set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE) if (MULTITHREAD_SUPPORT_ENABLED) - find_package(Boost 1.36.0 COMPONENTS thread system) - - if (Boost_FOUND) - link_directories( ${Boost_LIBRARY_DIRS} ) - else() - message(FATAL_ERROR "Can not find Boost") - endif(Boost_FOUND) - - if (CMAKE_HOST_UNIX) - add_definitions(-pthread) - list(APPEND LIBS "pthread") - endif() else() add_definitions(-DCHAISCRIPT_NO_THREADS) endif() -if (CMAKE_HOST_UNIX AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - list(APPEND LIBS "dl") -endif() +if (CMAKE_HOST_UNIX) + if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + list(APPEND LIBS "dl") + endif(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + + if (MULTITHREAD_SUPPORT_ENABLED) + if (CMAKE_COMPILER_IS_GNUCC) + execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE GCC_FULL_VERSION) + if (GCC_FULL_VERSION MATCHES "4.8.1.*ubuntu") + set (EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} -Wl,--no-as-needed -pthread ) + else() + set (EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} -pthread ) + endif() + else() + set (EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} -pthread ) + endif() + + add_definitions(-pthread) + endif() + +endif(CMAKE_HOST_UNIX) list(APPEND LIBS ${READLINE_LIB}) -if (NOT MSVC) - # Boost on MSVC does automatic linking - list(APPEND LIBS ${Boost_LIBRARIES}) -endif() -if (CMAKE_COMPILER_2005) - # vs2005 is a bit too loud about possible loss of data warnings -# ADD_DEFINITIONS(/wd4244) -endif() -include_directories(${Boost_INCLUDE_DIRS}) -include_directories(${Boost_INCLUDE_DIR}) +add_library(chaiscript_stdlib MODULE src/chaiscript_stdlib.cpp) +target_link_libraries(chaiscript_stdlib ${LIBS} ${EXTRA_LINKER_FLAGS} ${CMAKE_THREAD_LIBS_INIT}) + add_executable(chai src/main.cpp ${Chai_INCLUDES}) -target_link_libraries(chai ${LIBS}) +target_link_libraries(chai ${LIBS} ${EXTRA_LINKER_FLAGS}) +add_dependencies(chai chaiscript_stdlib) if (BUILD_SAMPLES) add_executable(example samples/example.cpp) - target_link_libraries(example ${LIBS}) + target_link_libraries(example ${LIBS} ${EXTRA_LINKER_FLAGS}) add_executable(memory_leak_test samples/memory_leak_test.cpp) - target_link_libraries(memory_leak_test ${LIBS}) + target_link_libraries(memory_leak_test ${LIBS} ${EXTRA_LINKER_FLAGS}) endif() if (BUILD_MODULES) add_library(stl_extra MODULE src/stl_extra.cpp) - target_link_libraries(stl_extra ${LIBS}) + target_link_libraries(stl_extra ${LIBS} ${EXTRA_LINKER_FLAGS}) add_library(reflection MODULE src/reflection.cpp) - target_link_libraries(reflection ${LIBS}) + target_link_libraries(reflection ${LIBS} ${EXTRA_LINKER_FLAGS}) set(MODULES stl_extra reflection) endif() -file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai) +file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/3.x/*.chai) list(SORT UNIT_TESTS) @@ -143,7 +208,7 @@ if(BUILD_TESTING) foreach(filename ${UNIT_TESTS}) message(STATUS "Adding test ${filename}") add_test(${filename} chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/unit_test.inc ${CMAKE_CURRENT_SOURCE_DIR}/unittests/${filename}) - endforeach(filename) + endforeach(filename) set_property(TEST ${UNIT_TESTS} PROPERTY ENVIRONMENT @@ -152,73 +217,82 @@ if(BUILD_TESTING) ) if (NOT UNIT_TEST_LIGHT) + # commented out because uniform initializer syntax is not working properly in MSVC 2013 add_executable(utility_test unittests/utility_test.cpp) - target_link_libraries(utility_test ${LIBS}) + target_link_libraries(utility_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Utility_Test COMMAND utility_test) add_executable(dynamic_object_test unittests/dynamic_object_test.cpp) - target_link_libraries(dynamic_object_test ${LIBS}) + target_link_libraries(dynamic_object_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Dynamic_Object_Test COMMAND dynamic_object_test) add_executable(functor_creation_test unittests/functor_creation_test.cpp) - target_link_libraries(functor_creation_test ${LIBS}) + target_link_libraries(functor_creation_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Functor_Creation_Test COMMAND functor_creation_test) add_executable(functor_cast_test unittests/functor_cast_test.cpp) - target_link_libraries(functor_cast_test ${LIBS}) + target_link_libraries(functor_cast_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Functor_Cast_Test COMMAND functor_cast_test) add_executable(boxed_cast_test unittests/boxed_cast_test.cpp) - target_link_libraries(boxed_cast_test ${LIBS}) + target_link_libraries(boxed_cast_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Boxed_Cast_Test COMMAND boxed_cast_test) add_executable(object_lifetime_test unittests/object_lifetime_test.cpp) - target_link_libraries(object_lifetime_test ${LIBS}) + target_link_libraries(object_lifetime_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Object_Lifetime_Test COMMAND object_lifetime_test) add_executable(function_ordering_test unittests/function_ordering_test.cpp) - target_link_libraries(function_ordering_test ${LIBS}) + target_link_libraries(function_ordering_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Function_Ordering_Test COMMAND function_ordering_test) add_executable(type_info_test unittests/type_info_test.cpp) - target_link_libraries(type_info_test ${LIBS}) + target_link_libraries(type_info_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Type_Info_Test COMMAND type_info_test) add_executable(eval_catch_exception_test unittests/eval_catch_exception_test.cpp) - target_link_libraries(eval_catch_exception_test ${LIBS}) + target_link_libraries(eval_catch_exception_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Eval_Catch_Exception_Test COMMAND eval_catch_exception_test) add_executable(short_comparison_test unittests/short_comparison_test.cpp) - target_link_libraries(short_comparison_test ${LIBS}) + target_link_libraries(short_comparison_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Short_Comparison_Test COMMAND short_comparison_test) + add_executable(cpp_lambda_test unittests/cpp_lambda_test.cpp) + target_link_libraries(cpp_lambda_test ${LIBS} ${EXTRA_LINKER_FLAGS}) + add_test(NAME cpp_lambda_test COMMAND cpp_lambda_test) + add_executable(expected_eval_errors_test unittests/expected_eval_errors_test.cpp) - target_link_libraries(expected_eval_errors_test ${LIBS}) + target_link_libraries(expected_eval_errors_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Expected_Eval_Errors_Test COMMAND expected_eval_errors_test) add_executable(set_state_test unittests/set_state_test.cpp) - target_link_libraries(set_state_test ${LIBS}) + target_link_libraries(set_state_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Set_State_Test COMMAND set_state_test) add_executable(simultaneous_chaiscript_test unittests/simultaneous_chaiscript_test.cpp) - target_link_libraries(simultaneous_chaiscript_test ${LIBS}) + target_link_libraries(simultaneous_chaiscript_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Simultaneous_Chaiscript_Test COMMAND simultaneous_chaiscript_test) + add_executable(heap_allocated_chaiscript_test unittests/heap_allocated_chaiscript_test.cpp) + target_link_libraries(heap_allocated_chaiscript_test ${LIBS} ${EXTRA_LINKER_FLAGS}) + add_test(NAME Heap_Allocated_Chaiscript_Test COMMAND heap_allocated_chaiscript_test) + add_executable(c_linkage_test unittests/c_linkage_test.cpp) - target_link_libraries(c_linkage_test ${LIBS}) + target_link_libraries(c_linkage_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME C_Linkage_Test COMMAND c_linkage_test) add_executable(integer_literal_test unittests/integer_literal_test.cpp) - target_link_libraries(integer_literal_test ${LIBS}) + target_link_libraries(integer_literal_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Integer_Literal_Test COMMAND integer_literal_test) add_executable(arithmetic_conversions_test unittests/arithmetic_conversions_test.cpp) - target_link_libraries(arithmetic_conversions_test ${LIBS}) + target_link_libraries(arithmetic_conversions_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Arithmetic_Conversions_Test COMMAND arithmetic_conversions_test) if (MULTITHREAD_SUPPORT_ENABLED) add_executable(multithreaded_test unittests/multithreaded_test.cpp) - target_link_libraries(multithreaded_test ${LIBS}) + target_link_libraries(multithreaded_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME Multithreaded_Test COMMAND multithreaded_test) set_property(TEST Multithreaded_Test PROPERTY ENVIRONMENT @@ -231,17 +305,17 @@ if(BUILD_TESTING) add_executable(multifile_test unittests/multifile_test_main.cpp unittests/multifile_test_chai.cpp unittests/multifile_test_module.cpp) - target_link_libraries(multifile_test ${LIBS}) + target_link_libraries(multifile_test ${LIBS} ${EXTRA_LINKER_FLAGS}) add_test(NAME MultiFile_Test COMMAND multifile_test) add_library(test_module MODULE src/test_module.cpp) - target_link_libraries(test_module ${LIBS}) + target_link_libraries(test_module ${LIBS} ${EXTRA_LINKER_FLAGS}) install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript) endif() endif(BUILD_TESTING) -install(TARGETS chai ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript ) +install(TARGETS chai chaiscript_stdlib ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript ) install(DIRECTORY include/chaiscript DESTINATION include PATTERN "*.hpp" diff --git a/cmake/CheckCXX11Features.cmake b/cmake/CheckCXX11Features.cmake new file mode 100644 index 00000000..fc1243f1 --- /dev/null +++ b/cmake/CheckCXX11Features.cmake @@ -0,0 +1,103 @@ +# Checks for C++11 features +# CXX11_FEATURE_LIST - a list containing all supported features +# HAS_CXX11_AUTO - auto keyword +# HAS_CXX11_NULLPTR - nullptr +# HAS_CXX11_LAMBDA - lambdas +# HAS_CXX11_STATIC_ASSERT - static_assert() +# HAS_CXX11_RVALUE_REFERENCES - rvalue references +# HAS_CXX11_DECLTYPE - decltype keyword +# HAS_CXX11_CSTDINT_H - cstdint header +# HAS_CXX11_LONG_LONG - long long signed & unsigned types +# HAS_CXX11_VARIADIC_TEMPLATES - variadic templates +# HAS_CXX11_CONSTEXPR - constexpr keyword +# HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members +# HAS_CXX11_FUNC - __func__ preprocessor constant +# +# Original script by Rolf Eike Beer +# Modifications by Andreas Weis +# +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3) + +SET(CHECK_CXX11_OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +IF(CMAKE_COMPILER_IS_GNUCXX) + SET(CMAKE_CXX_FLAGS "-std=c++0x") +endif() + +MACRO(CXX11_CHECK_FEATURE FEATURE_NAME FEATURE_NUMBER RESULT_VAR) + IF (NOT DEFINED ${RESULT_VAR}) + SET(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx11/cxx11_${FEATURE_NAME}") + + IF (${FEATURE_NUMBER}) + SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++11-test-${FEATURE_NAME}-N${FEATURE_NUMBER}) + SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})") + ELSE (${FEATURE_NUMBER}) + SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++11-test-${FEATURE_NAME}) + SET(_LOG_NAME "\"${FEATURE_NAME}\"") + ENDIF (${FEATURE_NUMBER}) + MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME}") + + SET(_SRCFILE "${_SRCFILE_BASE}.cpp") + SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp") + SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp") + + IF (CROSS_COMPILING) + try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}") + IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}") + ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + ELSE (CROSS_COMPILING) + try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR + "${_bindir}" "${_SRCFILE}") + IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) + SET(${RESULT_VAR} TRUE) + ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) + SET(${RESULT_VAR} FALSE) + ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) + IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR + "${_bindir}_fail" "${_SRCFILE_FAIL}") + IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) + SET(${RESULT_VAR} TRUE) + ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) + SET(${RESULT_VAR} FALSE) + ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) + ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + ENDIF (CROSS_COMPILING) + IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) + try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}") + IF (_TMP_RESULT) + SET(${RESULT_VAR} FALSE) + ELSE (_TMP_RESULT) + SET(${RESULT_VAR} TRUE) + ENDIF (_TMP_RESULT) + ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) + + IF (${RESULT_VAR}) + MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- works") + LIST(APPEND CXX11_FEATURE_LIST ${RESULT_VAR}) + ELSE (${RESULT_VAR}) + MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- not supported") + ENDIF (${RESULT_VAR}) + SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}") + ENDIF (NOT DEFINED ${RESULT_VAR}) +ENDMACRO(CXX11_CHECK_FEATURE) + +CXX11_CHECK_FEATURE("auto" 2546 HAS_CXX11_AUTO) +CXX11_CHECK_FEATURE("nullptr" 2431 HAS_CXX11_NULLPTR) +CXX11_CHECK_FEATURE("lambda" 2927 HAS_CXX11_LAMBDA) +CXX11_CHECK_FEATURE("static_assert" 1720 HAS_CXX11_STATIC_ASSERT) +CXX11_CHECK_FEATURE("rvalue_references" 2118 HAS_CXX11_RVALUE_REFERENCES) +CXX11_CHECK_FEATURE("decltype" 2343 HAS_CXX11_DECLTYPE) +CXX11_CHECK_FEATURE("cstdint" "" HAS_CXX11_CSTDINT_H) +CXX11_CHECK_FEATURE("long_long" 1811 HAS_CXX11_LONG_LONG) +CXX11_CHECK_FEATURE("variadic_templates" 2555 HAS_CXX11_VARIADIC_TEMPLATES) +CXX11_CHECK_FEATURE("constexpr" 2235 HAS_CXX11_CONSTEXPR) +CXX11_CHECK_FEATURE("sizeof_member" 2253 HAS_CXX11_SIZEOF_MEMBER) +CXX11_CHECK_FEATURE("__func__" 2340 HAS_CXX11_FUNC) + +SET(CXX11_FEATURE_LIST ${CXX11_FEATURE_LIST} CACHE STRING "C++11 feature support list") +MARK_AS_ADVANCED(FORCE CXX11_FEATURE_LIST) + +SET(CMAKE_CXX_FLAGS ${CHECK_CXX11_OLD_CMAKE_CXX_FLAGS}) +UNSET(CHECK_CXX11_OLD_CMAKE_CXX_FLAGS) + diff --git a/cmake/c++11-test-__func__-N2340.cpp b/cmake/c++11-test-__func__-N2340.cpp new file mode 100644 index 00000000..c10dd185 --- /dev/null +++ b/cmake/c++11-test-__func__-N2340.cpp @@ -0,0 +1,8 @@ +#include + +int main() +{ + if (!__func__) { return 1; } + if(std::strlen(__func__) <= 0) { return 1; } + return 0; +} diff --git a/cmake/c++11-test-auto-N2546.cpp b/cmake/c++11-test-auto-N2546.cpp new file mode 100644 index 00000000..dbff4146 --- /dev/null +++ b/cmake/c++11-test-auto-N2546.cpp @@ -0,0 +1,12 @@ + +int main() +{ + auto i = 5; + auto f = 3.14159f; + auto d = 3.14159; + bool ret = ( + (sizeof(f) < sizeof(d)) && + (sizeof(i) == sizeof(int)) + ); + return ret ? 0 : 1; +} diff --git a/cmake/c++11-test-constexpr-N2235.cpp b/cmake/c++11-test-constexpr-N2235.cpp new file mode 100644 index 00000000..9f969e48 --- /dev/null +++ b/cmake/c++11-test-constexpr-N2235.cpp @@ -0,0 +1,19 @@ +constexpr int square(int x) +{ + return x*x; +} + +constexpr int the_answer() +{ + return 42; +} + +int main() +{ + int test_arr[square(3)]; + bool ret = ( + (square(the_answer()) == 1764) && + (sizeof(test_arr)/sizeof(test_arr[0]) == 9) + ); + return ret ? 0 : 1; +} diff --git a/cmake/c++11-test-cstdint.cpp b/cmake/c++11-test-cstdint.cpp new file mode 100644 index 00000000..58d4381e --- /dev/null +++ b/cmake/c++11-test-cstdint.cpp @@ -0,0 +1,10 @@ +#include +int main() +{ + bool test = + (sizeof(int8_t) == 1) && + (sizeof(int16_t) == 2) && + (sizeof(int32_t) == 4) && + (sizeof(int64_t) == 8); + return test ? 0 : 1; +} diff --git a/cmake/c++11-test-decltype-N2343.cpp b/cmake/c++11-test-decltype-N2343.cpp new file mode 100644 index 00000000..d0238859 --- /dev/null +++ b/cmake/c++11-test-decltype-N2343.cpp @@ -0,0 +1,11 @@ + +bool check_size(int i) +{ + return sizeof(int) == sizeof(decltype(i)); +} + +int main() +{ + bool ret = check_size(42); + return ret ? 0 : 1; +} diff --git a/cmake/c++11-test-lambda-N2927.cpp b/cmake/c++11-test-lambda-N2927.cpp new file mode 100644 index 00000000..b86ad170 --- /dev/null +++ b/cmake/c++11-test-lambda-N2927.cpp @@ -0,0 +1,5 @@ +int main() +{ + int ret = 0; + return ([&ret]() -> int { return ret; })(); +} diff --git a/cmake/c++11-test-long_long-N1811.cpp b/cmake/c++11-test-long_long-N1811.cpp new file mode 100644 index 00000000..2ae69887 --- /dev/null +++ b/cmake/c++11-test-long_long-N1811.cpp @@ -0,0 +1,7 @@ +int main(void) +{ + long long l; + unsigned long long ul; + + return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1; +} diff --git a/cmake/c++11-test-nullptr-N2431.cpp b/cmake/c++11-test-nullptr-N2431.cpp new file mode 100644 index 00000000..6c5ae662 --- /dev/null +++ b/cmake/c++11-test-nullptr-N2431.cpp @@ -0,0 +1,5 @@ +int main() +{ + int* test = nullptr; + return test ? 1 : 0; +} diff --git a/cmake/c++11-test-nullptr-N2431_fail_compile.cpp b/cmake/c++11-test-nullptr-N2431_fail_compile.cpp new file mode 100644 index 00000000..5747f1b8 --- /dev/null +++ b/cmake/c++11-test-nullptr-N2431_fail_compile.cpp @@ -0,0 +1,5 @@ +int main() +{ + int i = nullptr; + return 1; +} diff --git a/cmake/c++11-test-rvalue_references-N2118.cpp b/cmake/c++11-test-rvalue_references-N2118.cpp new file mode 100644 index 00000000..ef4e421f --- /dev/null +++ b/cmake/c++11-test-rvalue_references-N2118.cpp @@ -0,0 +1,15 @@ +int foo(int& lvalue) +{ + return 123; +} + +int foo(int&& rvalue) +{ + return 321; +} + +int main() +{ + int i = 42; + return ((foo(i) == 123) && (foo(42) == 321)) ? 0 : 1; +} diff --git a/cmake/c++11-test-sizeof_member-N2253.cpp b/cmake/c++11-test-sizeof_member-N2253.cpp new file mode 100644 index 00000000..3049ed18 --- /dev/null +++ b/cmake/c++11-test-sizeof_member-N2253.cpp @@ -0,0 +1,14 @@ +struct foo { + char bar; + int baz; +}; + +int main(void) +{ + bool ret = ( + (sizeof(foo::bar) == 1) && + (sizeof(foo::baz) >= sizeof(foo::bar)) && + (sizeof(foo) >= sizeof(foo::bar)+sizeof(foo::baz)) + ); + return ret ? 0 : 1; +} diff --git a/cmake/c++11-test-static_assert-N1720.cpp b/cmake/c++11-test-static_assert-N1720.cpp new file mode 100644 index 00000000..eae3c9a2 --- /dev/null +++ b/cmake/c++11-test-static_assert-N1720.cpp @@ -0,0 +1,5 @@ +int main() +{ + static_assert(0 < 1, "your ordering of integers is screwed"); + return 0; +} diff --git a/cmake/c++11-test-static_assert-N1720_fail_compile.cpp b/cmake/c++11-test-static_assert-N1720_fail_compile.cpp new file mode 100644 index 00000000..d97b6791 --- /dev/null +++ b/cmake/c++11-test-static_assert-N1720_fail_compile.cpp @@ -0,0 +1,5 @@ +int main() +{ + static_assert(1 < 0, "this should fail"); + return 0; +} diff --git a/cmake/c++11-test-variadic_templates-N2555.cpp b/cmake/c++11-test-variadic_templates-N2555.cpp new file mode 100644 index 00000000..79fae84f --- /dev/null +++ b/cmake/c++11-test-variadic_templates-N2555.cpp @@ -0,0 +1,23 @@ +int Accumulate() +{ + return 0; +} + +template +int Accumulate(T v, Ts... vs) +{ + return v + Accumulate(vs...); +} + +template +int CountElements() +{ + return sizeof...(Is); +} + +int main() +{ + int acc = Accumulate(1, 2, 3, 4, -5); + int count = CountElements<1,2,3,4,5>(); + return ((acc == 5) && (count == 5)) ? 0 : 1; +} diff --git a/contrib/codeanalysis/codeanalysis.sh b/contrib/codeanalysis/codeanalysis.sh index 6a322104..3da80b43 100755 --- a/contrib/codeanalysis/codeanalysis.sh +++ b/contrib/codeanalysis/codeanalysis.sh @@ -50,7 +50,7 @@ function run_test # Run multithreaded tests echo "****Building multithreaded test" pushd src - g++ multithreaded.cpp -lboost_thread-mt -ldl -omultithreaded -I../include -O3 + g++ multithreaded.cpp -ldl -omultithreaded -I../include -O3 echo "****Testing 1 thread runtime" /usr/bin/time -p ./multithreaded 1 2> ../../r$1-1threadruntime.out echo "****Testing 2 thread runtime" diff --git a/contrib/codeanalysis/is_prime.chai b/contrib/codeanalysis/is_prime.chai index d34bad25..9e5fe38b 100644 --- a/contrib/codeanalysis/is_prime.chai +++ b/contrib/codeanalysis/is_prime.chai @@ -1,6 +1,6 @@ def isprime(n) { - for (var i = 2; i < n; ++i) + for (auto i = 2; i < n; ++i) { if (n % i == 0) {return false} } @@ -11,8 +11,8 @@ def isprime(n) def primes(n) { - var count = 0 - for (var i = 2; i <= n; ++i) + auto count = 0 + for (auto i = 2; i <= n; ++i) { if (isprime(i)) {++count} } @@ -21,5 +21,6 @@ def primes(n) } -var N = 5000 +auto N = 5000 + print("primes: " + primes(N).to_string()) diff --git a/contrib/geshi/chaiscript.php b/contrib/geshi/chaiscript.php index 2235c8c5..06e4328f 100644 --- a/contrib/geshi/chaiscript.php +++ b/contrib/geshi/chaiscript.php @@ -51,7 +51,7 @@ $language_data = array ( 'break', 'else', 'else if', 'eval', 'for', 'if', 'return', 'while', 'try', 'catch', 'finally', 'case', 'switch', 'default', ), 2 => array( - 'def', 'false', 'fun', 'true', 'var', 'attr', + 'def', 'false', 'fun', 'true', 'var', 'auto', 'attr', ), 3 => array( // built in functions diff --git a/contrib/vim/syntax/chaiscript.vim b/contrib/vim/syntax/chaiscript.vim index 4a552628..b442aaa9 100644 --- a/contrib/vim/syntax/chaiscript.vim +++ b/contrib/vim/syntax/chaiscript.vim @@ -52,7 +52,7 @@ syn keyword chaiscriptExceptions try catch throw syn keyword chaiscriptKeyword def true false attr "Built in types -syn keyword chaiscriptType fun var +syn keyword chaiscriptType fun var auto "Built in funcs, keep it simple syn keyword chaiscriptFunc eval throw diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index afdba248..5ae46fcc 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -74,16 +74,16 @@ ///
/// \subsection compiling Compiling ChaiScript Applications /// -/// ChaiScript is a header only library with only two dependecies. boost::threads (optional) and the +/// ChaiScript is a header only library with only one dependecy: The /// operating system provided dynamic library loader, which has to be specified on some platforms. /// /// \subsubsection compilinggcc Compiling with GCC /// /// To compile the above application on a Unix like operating system (MacOS, Linux) with GCC you need to link -/// both boost::threads and the dynamic loader. For example: +/// the dynamic loader. For example: /// /// \code -/// gcc main.cpp -I/path/to/chaiscript/headers -ldl -lboost_threads +/// gcc main.cpp -I/path/to/chaiscript/headers -ldl /// \endcode /// /// Alternatively, you may compile without threading support. @@ -248,7 +248,9 @@ /// /// std::string append_string_int(const std::string &t_lhs, int t_rhs) /// { -/// return t_lhs + boost::lexical_cast(t_rhs); +/// std::stringstream ss; +/// ss << t_lhs << t_rhs; +/// return ss.str(); /// } /// /// chai.add(fun(append_string_int), "+"); @@ -300,8 +302,8 @@ ///
/// \subsection pointerconversions Pointer / Object Conversions /// -/// As much as possible, ChaiScript attempts to convert between &, *, const &, const *, boost::shared_ptr, -/// boost::shared_ptr, boost::reference_wrapper, boost::reference_wrapper and value types automatically. +/// As much as possible, ChaiScript attempts to convert between &, *, const &, const *, std::shared_ptr, +/// std::shared_ptr, std::reference_wrapper, std::reference_wrapper and value types automatically. /// /// If a chaiscript::var object was created in C++ from a pointer, it cannot be convered to a shared_ptr (this would add invalid reference counting). /// Const may be added, but never removed. @@ -314,12 +316,12 @@ /// void fun3(int); /// void fun4(int &); /// void fun5(const int &); -/// void fun5(boost::shared_ptr); -/// void fun6(boost::shared_ptr); -/// void fun7(const boost::shared_ptr &); -/// void fun8(const boost::shared_ptr &); -/// void fun9(boost::reference_wrapper); -/// void fun10(boost::reference_wrapper); +/// void fun5(std::shared_ptr); +/// void fun6(std::shared_ptr); +/// void fun7(const std::shared_ptr &); +/// void fun8(const std::shared_ptr &); +/// void fun9(std::reference_wrapper); +/// void fun10(std::reference_wrapper); /// /// int main() /// { @@ -380,10 +382,10 @@ /// \subsection functionobjects Function Objects /// /// Functions are first class objects in Chaiscript and ChaiScript supports automatic conversion -/// between ChaiScript functions and boost::function objects. +/// between ChaiScript functions and std::function objects. /// /// \code -/// void callafunc(const boost::function &t_func) +/// void callafunc(const std::function &t_func) /// { /// t_func("bob"); /// } @@ -393,9 +395,9 @@ /// chaiscript::ChaiScript chai; /// chai.add(chaiscript::fun(&callafunc), "callafunc"); /// chai("callafunc(fun(x) { print(x); })"); // pass a lambda function to the registered function -/// // which expects a typed boost::function +/// // which expects a typed std::function /// -/// boost::function f = chai.eval >("dump_system"); +/// std::function f = chai.eval >("dump_system"); /// f(); // call the ChaiScript function dump_system, from C++ /// } /// \endcode @@ -410,7 +412,7 @@ /// /// Thread safety can be disabled by defining CHAISCRIPT_NO_THREADS when using the library. /// -/// Disabling thread safety increases performance and removes the requirement for boost_threads. +/// Disabling thread safety increases performance in many cases. /// ///
/// @@ -746,20 +748,16 @@ /// \namespace chaiscript::detail /// \brief Classes and functions reserved for internal use. Items in this namespace are not supported. +#include "chaiscript_defines.hpp" + #include "dispatchkit/dispatchkit.hpp" -#include "dispatchkit/bootstrap.hpp" -#include "dispatchkit/bootstrap_stl.hpp" #include "dispatchkit/function_call.hpp" #include "dispatchkit/dynamic_object.hpp" #include "dispatchkit/boxed_number.hpp" -#ifdef BOOST_HAS_DECLSPEC -#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport) -#else -#define CHAISCRIPT_MODULE_EXPORT extern "C" -#endif - #include "language/chaiscript_eval.hpp" #include "language/chaiscript_engine.hpp" + + #endif /* CHAISCRIPT_HPP_ */ diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp new file mode 100644 index 00000000..9dd60f99 --- /dev/null +++ b/include/chaiscript/chaiscript_defines.hpp @@ -0,0 +1,37 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// and Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_DEFINES_HPP_ +#define CHAISCRIPT_DEFINES_HPP_ + +#ifdef _MSC_VER +#define CHAISCRIPT_MSVC _MSC_VER +#define CHAISCRIPT_HAS_DECLSPEC +#endif + +#ifdef _WIN32 +#define CHAISCRIPT_WINDOWS +#endif + + +#ifdef CHAISCRIPT_HAS_DECLSPEC +#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport) +#else +#define CHAISCRIPT_MODULE_EXPORT extern "C" +#endif + +#ifdef CHAISCRIPT_MSVC +#define CHAISCRIPT_NOEXCEPT throw() +#define CHAISCRIPT_CONSTEXPR +#else +#define CHAISCRIPT_NOEXCEPT noexcept +#define CHAISCRIPT_CONSTEXPR constexpr +#endif + + + +#endif + diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp new file mode 100644 index 00000000..57f312f0 --- /dev/null +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -0,0 +1,42 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// and Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_STDLIB_HPP_ +#define CHAISCRIPT_STDLIB_HPP_ + +#include "chaiscript_defines.hpp" +#include "dispatchkit/bootstrap.hpp" +#include "dispatchkit/bootstrap_stl.hpp" + +/// \file +/// +/// This file generates the standard library that normal ChaiScript usage requires. + +namespace chaiscript +{ + class Std_Lib + { + public: + + static ModulePtr library() + { + using namespace bootstrap; + + ModulePtr lib = Bootstrap::bootstrap(); + + lib->add(standard_library::vector_type >("Vector")); + lib->add(standard_library::string_type("string")); + lib->add(standard_library::map_type >("Map")); + lib->add(standard_library::pair_type >("Pair")); + + return lib; + } + + }; +} + +#endif + diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 36d22791..baf000d6 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -7,17 +7,11 @@ #ifndef CHAISCRIPT_THREADING_HPP_ #define CHAISCRIPT_THREADING_HPP_ -#ifndef CHAISCRIPT_NO_THREADS +#include -#ifdef __llvm__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wc++11-long-long" -#pragma clang diagnostic ignored "-Wshadow" -#endif -#include -#ifdef __llvm__ -#pragma clang diagnostic pop -#endif +#ifndef CHAISCRIPT_NO_THREADS +#include +#include #else #pragma message ("ChaiScript is compiling without thread safety.") #endif @@ -34,48 +28,92 @@ namespace chaiscript { namespace detail { - /// If threading is enabled, then this namespace contains boost::thread classes. + /// If threading is enabled, then this namespace contains std thread classes. /// If threading is not enabled, then stubbed in wrappers that do nothing are provided. /// This allows us to avoid \#ifdef code in the sections that need thread safety. namespace threading { #ifndef CHAISCRIPT_NO_THREADS - using boost::unique_lock; - using boost::shared_lock; - using boost::lock_guard; - using boost::shared_mutex; - using boost::recursive_mutex; + + template + class unique_lock : public std::unique_lock + { + public: + unique_lock(T &t) : std::unique_lock(t) {} + }; + + template + class shared_lock : public std::unique_lock + { + public: + shared_lock(T &t) : std::unique_lock(t) {} + void unlock() {} + }; + + template + class lock_guard : public std::lock_guard + { + public: + lock_guard(T &t) : std::lock_guard(t) {} + }; + + class shared_mutex : public std::mutex { }; + + using std::mutex; + + using std::recursive_mutex; - /// Typesafe thread specific storage. If threading is enabled, this class uses boost::thread_specific_ptr. If + + /// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If /// threading is not enabled, the class always returns the same data, regardless of which thread it is called from. + /// + /// \todo move to thread_local when it exists template class Thread_Storage { public: - ~Thread_Storage() - { - m_thread_storage.reset(); - } - inline T *operator->() const { - if (!m_thread_storage.get()) - { - m_thread_storage.reset(new T()); - } - - return m_thread_storage.get(); + return get_tls().get(); } inline T &operator*() const { - return *(this->operator->()); + return *get_tls(); } + private: - mutable boost::thread_specific_ptr m_thread_storage; + std::shared_ptr get_tls() const + { + + unique_lock lock(m_mutex); + + auto itr = m_instances.find(std::this_thread::get_id()); + + if (itr != m_instances.end()) { return itr->second; } + + std::shared_ptr new_instance(new T()); + + m_instances.insert(std::make_pair(std::this_thread::get_id(), new_instance)); + + return new_instance; + + + /* + static __thread std::shared_ptr *m_data = 0; + + if (!m_data) { m_data = new std::shared_ptr(new T()); } + + return *m_data; + */ + } + + + mutable mutex m_mutex; + mutable std::unordered_map > m_instances; }; #else diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp new file mode 100644 index 00000000..75a01c0f --- /dev/null +++ b/include/chaiscript/dispatchkit/any.hpp @@ -0,0 +1,167 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// and Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_ANY_HPP_ +#define CHAISCRIPT_ANY_HPP_ + +namespace chaiscript { + namespace detail { + namespace exception + { + /// \brief Thrown in the event that an Any cannot be cast to the desired type + /// + /// It is used internally during function dispatch. + /// + /// \sa chaiscript::detail::Any + class bad_any_cast : public std::bad_cast + { + public: + bad_any_cast() CHAISCRIPT_NOEXCEPT + : m_what("bad any cast") + { + } + + virtual ~bad_any_cast() CHAISCRIPT_NOEXCEPT {} + + /// \brief Description of what error occured + virtual const char * what() const CHAISCRIPT_NOEXCEPT + { + return m_what.c_str(); + } + + private: + std::string m_what; + }; + } + + + class Any { + private: + struct Data + { + virtual ~Data() {} + virtual void *data() = 0; + virtual const std::type_info &type() const = 0; + virtual std::shared_ptr clone() const = 0; + }; + + template + struct Data_Impl : Data + { + Data_Impl(const T &t_type) + : m_type(typeid(T)), + m_data(t_type) + { + } + + virtual ~Data_Impl() {} + + virtual void *data() + { + return &m_data; + } + + const std::type_info &type() const + { + return m_type; + } + + std::shared_ptr clone() const + { + return std::shared_ptr(new Data_Impl(m_data)); + } + + Data_Impl &operator=(const Data_Impl&) = delete; + + const std::type_info &m_type; + T m_data; + }; + + std::shared_ptr m_data; + + public: + // construct/copy/destruct + Any() = default; + + Any(const Any &t_any) + { + if (!t_any.empty()) + { + m_data = t_any.m_data->clone(); + } else { + m_data.reset(); + } + } + + template + Any(const ValueType &t_value) + : m_data(std::shared_ptr(new Data_Impl(t_value))) + { + } + + Any & operator=(const Any &t_any) + { + Any copy(t_any); + swap(copy); + return *this; + } + + template + Any & operator=(const ValueType &t_value) + { + m_data = std::shared_ptr(new Data_Impl(t_value)); + return *this; + } + + template + ToType &cast() const + { + if (m_data && typeid(ToType) == m_data->type()) + { + return *static_cast(m_data->data()); + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + + } + + + ~Any() + { + } + + // modifiers + Any & swap(Any &t_other) + { + std::shared_ptr data = t_other.m_data; + t_other.m_data = m_data; + m_data = data; + return *this; + } + + // queries + bool empty() const + { + return !bool(m_data); + } + + const std::type_info & type() const + { + if (m_data) + { + return m_data->type(); + } else { + return typeid(void); + } + } + }; + + } +} + +#endif + + diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index 5d519811..0d5fb7ec 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -22,25 +22,25 @@ namespace chaiscript { public: bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to, - const std::string &t_what) throw() + const std::string &t_what) CHAISCRIPT_NOEXCEPT : from(t_from), to(&t_to), m_what(t_what) { } - bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) throw() + bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) CHAISCRIPT_NOEXCEPT : from(t_from), to(&t_to), m_what("Cannot perform boxed_cast") { } - bad_boxed_cast(const std::string &t_what) throw() + bad_boxed_cast(const std::string &t_what) CHAISCRIPT_NOEXCEPT : to(0), m_what(t_what) { } - virtual ~bad_boxed_cast() throw() {} + virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT {} /// \brief Description of what error occured - virtual const char * what() const throw() + virtual const char * what() const CHAISCRIPT_NOEXCEPT { return m_what.c_str(); } diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index 512a120f..16f95b06 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -4,91 +4,130 @@ // Copyright 2009-2014, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com -#include -#include - -#define param(z,n,text) BOOST_PP_CAT(text, BOOST_PP_INC(n)) - -#ifndef BOOST_PP_IS_ITERATING #ifndef CHAISCRIPT_BIND_FIRST_HPP_ #define CHAISCRIPT_BIND_FIRST_HPP_ -#include -#include -#include - -#define BOOST_PP_ITERATION_LIMITS ( 0, 8 ) -#define BOOST_PP_FILENAME_1 - -#include BOOST_PP_ITERATE() - - -# endif -#else -# define n BOOST_PP_ITERATION() -# define m BOOST_PP_INC(n) +#include namespace chaiscript { namespace detail - { - /// \brief Helper function for binding the first parameter of a class method pointer. Used in chaiscript::fun overloads - /// that take 1 or 2 parameters to pre-bind to the function. - /// - /// \param[in] f method pointer to bind - /// \param[in] o object to bind as first parameter - /// \returns a new boost::function object with one fewer parameters than the function passed in. - template - boost::function - bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const O &o) + { + + template + struct Placeholder { - return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); + }; + + template<> + struct Placeholder<1> + { + static decltype(std::placeholders::_1) value() { return std::placeholders::_1; } + }; + + template<> + struct Placeholder<2> + { + static decltype(std::placeholders::_2) value() { return std::placeholders::_2; } + }; + + template<> + struct Placeholder<3> + { + static decltype(std::placeholders::_3) value() { return std::placeholders::_3; } + }; + + template<> + struct Placeholder<4> + { + static decltype(std::placeholders::_4) value() { return std::placeholders::_4; } + }; + + template<> + struct Placeholder<5> + { + static decltype(std::placeholders::_5) value() { return std::placeholders::_5; } + }; + + template<> + struct Placeholder<6> + { + static decltype(std::placeholders::_6) value() { return std::placeholders::_6; } + }; + + template<> + struct Placeholder<7> + { + static decltype(std::placeholders::_7) value() { return std::placeholders::_7; } + }; + + template<> + struct Placeholder<8> + { + static decltype(std::placeholders::_8) value() { return std::placeholders::_8; } + }; + + template<> + struct Placeholder<9> + { + static decltype(std::placeholders::_9) value() { return std::placeholders::_9; } + }; + + template<> + struct Placeholder<10> + { + static decltype(std::placeholders::_10) value() { return std::placeholders::_10; } + }; + + + template + struct Bind_First + { + template + static std::function bind(F f, InnerParams ... innerparams) + { + return Bind_First::bind(f, innerparams..., Placeholder::value()); + } + }; + + template + struct Bind_First<0, maxcount, Sig> + { + template + static std::function bind(F f, InnerParams ... innerparams) + { + return std::bind(f, innerparams...); + } + }; + + + template + std::function bind_first(Ret (*f)(P1, Param...), O o) + { + return Bind_First::bind(f, o); } - /// \brief Helper function for binding the first parameter of a const class method pointer. Used in chaiscript::fun overloads - /// that take 1 or 2 parameters to pre-bind to the function. - /// - /// \param[in] f method pointer to bind - /// \param[in] o object to bind as first parameter - /// \returns a new boost::function object with one fewer parameters than the function passed in. - template - boost::function - bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)) const, const O &o) + template + std::function bind_first(Ret (Class::*f)(Param...), O o) { - return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); + return Bind_First::bind(f, o); } - /// \brief Helper function for binding the first parameter of a function pointer. Used in chaiscript::fun overloads - /// that take 1 or 2 parameters to pre-bind to the function. - /// - /// \param[in] f method pointer to bind - /// \param[in] o object to bind as first parameter - /// \returns a new boost::function object with one fewer parameters than the function passed in. - template - boost::function - bind_first(Ret (*f)(BOOST_PP_ENUM_PARAMS(m, Param)), const O &o) + template + std::function bind_first(Ret (Class::*f)(Param...) const, O o) { - return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); + return Bind_First::bind(f, o); } - /// \brief Helper function for binding the first parameter of a boost::function object. Used in chaiscript::fun overloads - /// that take 1 or 2 parameters to pre-bind to the function. - /// - /// \param[in] f method pointer to bind - /// \param[in] o object to bind as first parameter - /// \returns a new boost::function object with one fewer parameters than the function passed in. - template - boost::function - bind_first(const boost::function &f, const O &o) + template + std::function bind_first(const std::function &f, O o) { - return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); + return Bind_First::bind(f, o); } + } } -#undef n -#undef m -#undef param #endif diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index af2a148b..d42baa3b 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -12,8 +12,8 @@ #include "register_function.hpp" #include "operators.hpp" #include "boxed_number.hpp" -#include #include +#include namespace chaiscript { @@ -26,9 +26,9 @@ namespace chaiscript /// \param[in] v Boxed_Number to copy into the new object /// \returns The newly created object. template - boost::shared_ptr construct_pod(Boxed_Number v) + std::shared_ptr construct_pod(Boxed_Number v) { - boost::shared_ptr p(new P1()); + std::shared_ptr p(new P1()); Boxed_Value bv(p); Boxed_Number nb(bv); nb = v; @@ -97,29 +97,25 @@ namespace chaiscript * to_string function for internal use. Uses ostream operator<< */ template - std::string to_string(Input i) - { - std::stringstream ss; - ss << i; - return ss.str(); - } + std::string to_string(Input i) + { + std::stringstream ss; + ss << i; + return ss.str(); + } /** * 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) - { - std::stringstream ss(i); - Input t; - ss >> t; - return t; - } - - - - + Input parse_string(const std::string &i) + { + std::stringstream ss(i); + Input t; + ss >> t; + return t; + } /** @@ -147,7 +143,7 @@ namespace chaiscript * function variables. */ template - boost::shared_ptr shared_ptr_clone(const boost::shared_ptr &p) + std::shared_ptr shared_ptr_clone(const std::shared_ptr &p) { return p; } @@ -156,10 +152,10 @@ namespace chaiscript * Specific version of shared_ptr_clone just for Proxy_Functions */ template - boost::shared_ptr::type> - shared_ptr_unconst_clone(const boost::shared_ptr::type> &p) + std::shared_ptr::type> + shared_ptr_unconst_clone(const std::shared_ptr::type> &p) { - return boost::const_pointer_cast::type>(p); + return std::const_pointer_cast::type>(p); } @@ -170,7 +166,7 @@ namespace chaiscript * Similar to shared_ptr_clone. Used for Proxy_Function. */ template - Boxed_Value ptr_assign(Boxed_Value lhs, const boost::shared_ptr &rhs) + Boxed_Value ptr_assign(Boxed_Value lhs, const std::shared_ptr &rhs) { if (lhs.is_undef() || (!lhs.get_type_info().is_const() && lhs.get_type_info().bare_equal(chaiscript::detail::Get_Type_Info::get()))) @@ -276,7 +272,7 @@ namespace chaiscript static bool has_guard(const Const_Proxy_Function &t_pf) { - boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); + auto pf = std::dynamic_pointer_cast(t_pf); if (pf) { if (pf->get_guard()) { @@ -291,7 +287,7 @@ namespace chaiscript static Const_Proxy_Function get_guard(const Const_Proxy_Function &t_pf) { - boost::shared_ptr pf = boost::dynamic_pointer_cast(t_pf); + auto pf = std::dynamic_pointer_cast(t_pf); if (pf) { if (pf->get_guard()) @@ -309,7 +305,9 @@ namespace chaiscript throw bv; } - static boost::shared_ptr bootstrap2(boost::shared_ptr e = boost::shared_ptr (new chaiscript::detail::Dispatch_Engine())) + static std::shared_ptr bootstrap2( + std::shared_ptr e + = std::shared_ptr (new chaiscript::detail::Dispatch_Engine())) { e->add(user_type(), "void"); return e; @@ -337,24 +335,22 @@ namespace chaiscript static std::vector do_return_boxed_value_vector(FunctionType f, const dispatch::Proxy_Function_Base *b) { - typedef typename boost::function_types::result_type::type Vector; - Vector v = (b->*f)(); + auto v = (b->*f)(); std::vector vbv; - for (typename Vector::const_iterator itr = v.begin(); - itr != v.end(); - ++itr) + + for (const auto &o: v) { - vbv.push_back(const_var(*itr)); + vbv.push_back(const_var(o)); } return vbv; } template - static boost::function (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f) + static std::function (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f) { - return boost::bind(&do_return_boxed_value_vector, f, _1); + return std::bind(&do_return_boxed_value_vector, f, std::placeholders::_1); } public: @@ -384,7 +380,7 @@ namespace chaiscript m->add(constructor(), "runtime_error"); - m->add(fun(boost::function(&what)), "what"); + m->add(fun(std::function(&what)), "what"); m->add(user_type(), "Dynamic_Object"); m->add(constructor(), "Dynamic_Object"); @@ -392,7 +388,7 @@ namespace chaiscript m->add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs"); m->add(fun(&dispatch::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; }"); + m->eval("def Dynamic_Object::clone() { auto &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; }"); m->add(fun(&has_guard), "has_guard"); m->add(fun(&get_guard), "get_guard"); @@ -440,14 +436,14 @@ namespace chaiscript bootstrap_pod_type("unsigned_long", m); bootstrap_pod_type("size_t", m); bootstrap_pod_type("char", m); - bootstrap_pod_type("int8_t", m); - bootstrap_pod_type("int16_t", m); - bootstrap_pod_type("int32_t", m); - bootstrap_pod_type("int64_t", m); - bootstrap_pod_type("uint8_t", m); - bootstrap_pod_type("uint16_t", m); - bootstrap_pod_type("uint32_t", m); - bootstrap_pod_type("uint64_t", m); + bootstrap_pod_type("int8_t", m); + bootstrap_pod_type("int16_t", m); + bootstrap_pod_type("int32_t", m); + bootstrap_pod_type("int64_t", m); + bootstrap_pod_type("uint8_t", m); + bootstrap_pod_type("uint16_t", m); + bootstrap_pod_type("uint32_t", m); + bootstrap_pod_type("uint64_t", m); operators::logical_compliment(m); @@ -457,14 +453,14 @@ namespace chaiscript m->add(fun(&print), "print_string"); m->add(fun(&println), "println_string"); - m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&bind_function, _1))), + m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(std::bind(&bind_function, std::placeholders::_1))), "bind"); m->add(fun(&shared_ptr_unconst_clone), "clone"); - m->add(fun(&ptr_assign::type>), "="); - m->add(fun(&ptr_assign::type>), "="); + m->add(fun(&ptr_assign::type>), "="); + m->add(fun(&ptr_assign::type>), "="); - m->add(fun(&type_match), "type_match"); + m->add(fun(&Boxed_Value::type_match), "type_match"); return m; } diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index db6520d9..13b778a9 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -14,6 +14,7 @@ #define CHAISCRIPT_BOOTSTRAP_STL_HPP_ #include "dispatchkit.hpp" +#include "bootstrap.hpp" #include "register_function.hpp" namespace chaiscript @@ -143,89 +144,13 @@ namespace chaiscript }; namespace detail { - template - int return_int_impl(const boost::function &t_func, const T *t_obj) - { -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4267) -#endif - return t_func(t_obj); -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - } template - boost::function return_int(size_t (T::*t_func)() const) - { - return boost::bind(&return_int_impl, boost::function(boost::mem_fn(t_func)), _1); - } - - template - int return_int_impl(const boost::function &t_func, const T *t_obj, P1 p1) - { -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4267) -#endif - return t_func(t_obj, p1); -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - } - - template - int return_int_impl_non_const(const boost::function &t_func, T *t_obj, P1 p1) - { -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4267) -#endif - return t_func(t_obj, p1); -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - } - - template - boost::function return_int(size_t (T::*t_func)(P1) const) - { - return boost::bind(&return_int_impl, boost::function(boost::mem_fn(t_func)), _1, _2); - } - - template - boost::function return_int(size_t (T::*t_func)(P1) ) - { - return boost::bind(&return_int_impl_non_const, boost::function(boost::mem_fn(t_func)), _1, _2); - } - - - template - int return_int_impl(const boost::function &t_func, const T *t_obj, P1 p1, P2 p2) - { -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4267) -#endif - return t_func(t_obj, p1, p2); -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - } - - template - StringType substr_helper(const StringType &str, int begin, int end) + size_t count(const T &t_target, const typename T::key_type &t_key) { - return (str.*Func)(begin, end); + return t_target.count(t_key); } - template - boost::function return_int(size_t (T::*t_func)(P1, P2) const) - { - return boost::bind(&return_int_impl, boost::function(boost::mem_fn(t_func)), _1, _2, _3); - } - template void insert(T &t_target, const T &t_other) { @@ -240,8 +165,6 @@ namespace chaiscript - - /// Add Bidir_Range support for the given ContainerType template ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module())) @@ -317,11 +240,11 @@ namespace chaiscript //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 - (boost::mem_fn(static_cast(&ContainerType::at)))), "[]"); + fun(std::function + (std::mem_fn(static_cast(&ContainerType::at)))), "[]"); m->add( - fun(boost::function - (boost::mem_fn(static_cast(&ContainerType::at)))), "[]"); + fun(std::function + (std::mem_fn(static_cast(&ContainerType::at)))), "[]"); return m; } @@ -343,10 +266,9 @@ namespace chaiscript template ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) { - boost::function f = detail::return_int(&ContainerType::size); - m->add(fun(f), "size"); - m->add(fun(&ContainerType::empty), "empty"); - m->add(fun(&ContainerType::clear), "clear"); + m->add(fun( std::function( [](const ContainerType *a) { return a->size(); } ) ), "size"); + m->add(fun( std::function( [](const ContainerType *a) { return a->empty(); } ) ), "empty"); + m->add(fun( std::function( [](ContainerType *a) { a->clear(); } ) ), "clear"); return m; } @@ -472,13 +394,11 @@ namespace chaiscript template ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) { - m->add(fun(boost::function(detail::return_int(&ContainerType::count))), "count"); + m->add(fun(detail::count), "count"); + typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &); - typedef size_t (ContainerType::*erase)(const typename ContainerType::key_type &); - erase eraseptr(&ContainerType::erase); - - m->add(fun(boost::function(detail::return_int(eraseptr))), "erase"); + m->add(fun(static_cast(&ContainerType::erase)), "erase"); m->add(fun(&detail::insert), "insert"); @@ -560,8 +480,8 @@ namespace chaiscript if ( rhs.size() != this.size() ) { \ return false; \ } else { \ - var r1 = range(this); \ - var r2 = range(rhs); \ + auto r1 = range(this); \ + auto r2 = range(rhs); \ while (!r1.empty()) \ { \ if (!eq(r1.front(), r2.front())) \ @@ -579,32 +499,6 @@ namespace chaiscript return m; } - namespace detail { - template - struct apple_string_workarounds - { - /// The latest version of MacOS has a broken std::string implementation which will not allow - /// us to take pointers to the members. Code compiles, but does not link - /// \todo re-evaluate at some point - - static size_t find(const String *s, const String &w, int pos) { return s->find(w, pos); } - static size_t rfind(const String *s, const String &w, size_t pos) { return s->rfind(w, pos); } - static size_t find_first_of(const String *s, const String &w, size_t pos) { return s->find_first_of(w, pos); } - static size_t find_last_of(const String *s, const String &w, size_t pos) { return s->find_last_of(w, pos); } - static size_t find_first_not_of(const String *s, const String &w, size_t pos) { return s->find_first_not_of(w, pos); } - static size_t find_last_not_of(const String *s, const String &w, size_t pos) { return s->find_last_not_of(w, pos); } - - static void clear(String *s) { s->clear(); } - static bool empty(const String *s) { return s->empty(); } - static size_t size(const String *s) { return s->size(); } - - static std::string substr(const String *s, size_t pos, size_t len) { return s->substr(pos,len); } - static const char *c_str(const String *s) { return s->c_str(); } - static const char *data(const String *s) { return s->data(); } - }; - } - - /// Add a String container /// http://www.sgi.com/tech/stl/basic_string.html template @@ -631,21 +525,24 @@ namespace chaiscript } m->add(fun(&String::push_back), push_back_name); - - m->add(fun(&detail::apple_string_workarounds::find), "find"); - m->add(fun(&detail::apple_string_workarounds::rfind), "rfind"); - m->add(fun(&detail::apple_string_workarounds::find_first_of), "find_first_of"); - m->add(fun(&detail::apple_string_workarounds::find_last_of), "find_last_of"); - m->add(fun(&detail::apple_string_workarounds::find_first_not_of), "find_first_not_of"); - m->add(fun(&detail::apple_string_workarounds::find_last_not_of), "find_last_not_of"); - m->add(fun(&detail::apple_string_workarounds::clear), "clear"); - m->add(fun(&detail::apple_string_workarounds::size), "size"); - m->add(fun(&detail::apple_string_workarounds::empty), "empty"); - m->add(fun(&detail::apple_string_workarounds::substr), "substr"); - m->add(fun(&detail::apple_string_workarounds::c_str), "c_str"); - m->add(fun(&detail::apple_string_workarounds::data), "data"); + typedef std::function find_func; + m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find(f, pos); } )), "find"); + m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->rfind(f, pos); } ) ), "rfind"); + m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_first_of(f, pos); } ) ), "find_first_of"); + m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ) ), "find_last_of"); + m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ) ), "find_last_not_of"); + m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ) ), "find_first_not_of"); + + m->add(fun( std::function( [](String *s) { return s->clear(); } ) ), "clear"); + m->add(fun( std::function( [](const String *s) { return s->empty(); } ) ), "empty"); + m->add(fun( std::function( [](const String *s) { return s->size(); } ) ), "size"); + + m->add(fun( std::function( [](const String *s) { return s->c_str(); } ) ), "c_str"); + m->add(fun( std::function( [](const String *s) { return s->data(); } ) ), "data"); + m->add(fun( std::function( [](const String *s, int pos, int len) { return s->substr(pos, len); } ) ), "substr"); + return m; } } @@ -654,3 +551,5 @@ namespace chaiscript #endif + + diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index 345e89a8..a603da58 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -7,20 +7,14 @@ #ifndef CHAISCRIPT_BOXED_CAST_HPP_ #define CHAISCRIPT_BOXED_CAST_HPP_ +#include "../chaiscript_defines.hpp" + #include "type_info.hpp" #include "boxed_value.hpp" #include "boxed_cast_helper.hpp" #include "dynamic_cast_conversion.hpp" #include "../chaiscript_threading.hpp" -#include -#include -#include -#include -#include -#include -#include -#include namespace chaiscript { @@ -31,63 +25,64 @@ namespace chaiscript /// \returns Type equivalent to the requested type /// \throws exception::bad_boxed_cast If the requested conversion is not possible /// - /// boxed_cast will attempt to make conversions between value, &, *, boost::shared_ptr, boost::reference_wrapper, - /// and boost::function (const and non-const) where possible. boxed_cast is used internally during function + /// boxed_cast will attempt to make conversions between value, &, *, std::shared_ptr, std::reference_wrapper, + /// and std::function (const and non-const) where possible. boxed_cast is used internally during function /// dispatch. This means that all of these conversions will be attempted automatically for you during /// ChaiScript function calls. /// /// \li non-const values can be extracted as const or non-const /// \li const values can be extracted only as const - /// \li Boxed_Value constructed from pointer or boost::reference_wrapper can be extracted as reference, + /// \li Boxed_Value constructed from pointer or std::reference_wrapper can be extracted as reference, /// pointer or value types - /// \li Boxed_Value constructed from boost::shared_ptr or value types can be extracted as reference, - /// pointer, value, or boost::shared_ptr types + /// \li Boxed_Value constructed from std::shared_ptr or value types can be extracted as reference, + /// pointer, value, or std::shared_ptr types /// - /// Conversions to boost::function objects are attempted as well + /// Conversions to std::function objects are attempted as well /// /// Example: /// \code /// // All of the following should succeed /// chaiscript::Boxed_Value bv(1); - /// boost::shared_ptr spi = chaiscript::boxed_cast >(bv); + /// std::shared_ptr spi = chaiscript::boxed_cast >(bv); /// int i = chaiscript::boxed_cast(bv); /// int *ip = chaiscript::boxed_cast(bv); /// int &ir = chaiscript::boxed_cast(bv); - /// boost::shared_ptr cspi = chaiscript::boxed_cast >(bv); + /// std::shared_ptr cspi = chaiscript::boxed_cast >(bv); /// const int ci = chaiscript::boxed_cast(bv); /// const int *cip = chaiscript::boxed_cast(bv); /// const int &cir = chaiscript::boxed_cast(bv); /// \endcode /// - /// boost::function conversion example + /// std::function conversion example /// \code /// chaiscript::ChaiScript chai; /// Boxed_Value bv = chai.eval("`+`"); // Get the functor for the + operator which is built in - /// boost::function f = chaiscript::boxed_cast >(bv); + /// std::function f = chaiscript::boxed_cast >(bv); /// int i = f(2,3); /// assert(i == 5); /// \endcode template - typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv, const Dynamic_Cast_Conversions *t_conversions = 0) + typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv, const Dynamic_Cast_Conversions *t_conversions = nullptr) { try { return detail::Cast_Helper::cast(bv, t_conversions); - } catch (const boost::bad_any_cast &) { + } catch (const chaiscript::detail::exception::bad_any_cast &) { -#ifdef BOOST_MSVC + +#ifdef CHAISCRIPT_MSVC //Thank you MSVC, yes we know that a constant value is being used in the if // statment in THIS VERSION of the template instantiation #pragma warning(push) #pragma warning(disable : 4127) #endif - if (boost::is_polymorphic::type>::value && t_conversions) + if (std::is_polymorphic::type>::value && t_conversions) { try { // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it // either way, we are not responsible if it doesn't work return detail::Cast_Helper::cast(t_conversions->boxed_dynamic_cast(bv), t_conversions); - } catch (const boost::bad_any_cast &) { + } catch (const chaiscript::detail::exception::bad_any_cast &) { throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type)); } } else { @@ -96,7 +91,7 @@ namespace chaiscript throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type)); } -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index afb9b01c..2008de31 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -10,10 +10,6 @@ #include "type_info.hpp" #include "boxed_value.hpp" -#include -#include -#include -#include namespace chaiscript { @@ -29,7 +25,7 @@ namespace chaiscript template struct Cast_Helper_Inner { - typedef typename boost::reference_wrapper::type > Result_Type; + typedef typename std::reference_wrapper::type > Result_Type; static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *) { @@ -37,16 +33,16 @@ namespace chaiscript { if (!ob.get_type_info().is_const()) { - return boost::cref((boost::any_cast >(ob.get())).get()); + return std::cref((ob.get().cast >()).get()); } else { - return boost::any_cast >(ob.get()); + return ob.get().cast >(); } } else { if (!ob.get_type_info().is_const()) { - return boost::cref(*(boost::any_cast >(ob.get()))); + return std::cref(*(ob.get().cast >())); } else { - return boost::cref(*(boost::any_cast >(ob.get()))); + return std::cref(*(ob.get().cast >())); } } } @@ -79,16 +75,16 @@ namespace chaiscript { if (!ob.get_type_info().is_const()) { - return (boost::any_cast >(ob.get())).get_pointer(); + return &(ob.get().cast >()).get(); } else { - return (boost::any_cast >(ob.get())).get_pointer(); + return &(ob.get().cast >()).get(); } } else { if (!ob.get_type_info().is_const()) { - return (boost::any_cast >(ob.get())).get(); + return (ob.get().cast >()).get(); } else { - return (boost::any_cast >(ob.get())).get(); + return (ob.get().cast >()).get(); } } } @@ -106,9 +102,9 @@ namespace chaiscript { if (ob.is_ref()) { - return (boost::any_cast >(ob.get())).get_pointer(); + return &(ob.get().cast >()).get(); } else { - return (boost::any_cast >(ob.get())).get(); + return (ob.get().cast >()).get(); } } }; @@ -119,76 +115,77 @@ namespace chaiscript template struct Cast_Helper_Inner { - typedef typename boost::reference_wrapper Result_Type; + typedef Result& Result_Type; static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *) { if (ob.is_ref()) { - return boost::any_cast >(ob.get()); + return ob.get().cast >(); } else { - return boost::ref(*(boost::any_cast >(ob.get()))); + Result &r = *(ob.get().cast >()); + return r; } } }; /** - * Cast_Helper_Inner for casting to a boost::shared_ptr<> type + * Cast_Helper_Inner for casting to a std::shared_ptr<> type */ template - struct Cast_Helper_Inner > + struct Cast_Helper_Inner > { - typedef typename boost::shared_ptr Result_Type; + typedef typename std::shared_ptr Result_Type; static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *) { - return boost::any_cast >(ob.get()); + return ob.get().cast >(); } }; /** - * Cast_Helper_Inner for casting to a boost::shared_ptr type + * Cast_Helper_Inner for casting to a std::shared_ptr type */ template - struct Cast_Helper_Inner > + struct Cast_Helper_Inner > { - typedef typename boost::shared_ptr Result_Type; + typedef typename std::shared_ptr Result_Type; static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *) { if (!ob.get_type_info().is_const()) { - return boost::const_pointer_cast(boost::any_cast >(ob.get())); + return std::const_pointer_cast(ob.get().cast >()); } else { - return boost::any_cast >(ob.get()); + return ob.get().cast >(); } } }; /** - * Cast_Helper_Inner for casting to a const boost::shared_ptr<> & type + * Cast_Helper_Inner for casting to a const std::shared_ptr<> & type */ template - struct Cast_Helper_Inner > : Cast_Helper_Inner > + struct Cast_Helper_Inner > : Cast_Helper_Inner > { }; template - struct Cast_Helper_Inner &> : Cast_Helper_Inner > + struct Cast_Helper_Inner &> : Cast_Helper_Inner > { }; /** - * Cast_Helper_Inner for casting to a const boost::shared_ptr & type + * Cast_Helper_Inner for casting to a const std::shared_ptr & type */ template - struct Cast_Helper_Inner > : Cast_Helper_Inner > + struct Cast_Helper_Inner > : Cast_Helper_Inner > { }; template - struct Cast_Helper_Inner &> : Cast_Helper_Inner > + struct Cast_Helper_Inner &> : Cast_Helper_Inner > { }; @@ -223,35 +220,35 @@ namespace chaiscript /** - * Cast_Helper_Inner for casting to a boost::reference_wrapper type + * Cast_Helper_Inner for casting to a std::reference_wrapper type */ template - struct Cast_Helper_Inner > : Cast_Helper_Inner + struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template - struct Cast_Helper_Inner > : Cast_Helper_Inner + struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template - struct Cast_Helper_Inner &> : Cast_Helper_Inner + struct Cast_Helper_Inner &> : Cast_Helper_Inner { }; template - struct Cast_Helper_Inner > : Cast_Helper_Inner + struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template - struct Cast_Helper_Inner > : Cast_Helper_Inner + struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template - struct Cast_Helper_Inner & > : Cast_Helper_Inner + struct Cast_Helper_Inner & > : Cast_Helper_Inner { }; diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 29c6c8d0..c78545d4 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -9,13 +9,13 @@ #include "boxed_value.hpp" #include "../language/chaiscript_algebraic.hpp" -#include #include +#include namespace chaiscript { -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(push) #pragma warning(disable : 4244 4018 4389 4146) #endif @@ -48,7 +48,7 @@ namespace chaiscript case Operators::not_equal: return const_var(t != u); default: - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -82,7 +82,7 @@ namespace chaiscript t -= u; break; default: - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } return t_lhs; @@ -115,7 +115,7 @@ namespace chaiscript t ^= u; break; default: - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } return t_lhs; } @@ -143,7 +143,7 @@ namespace chaiscript case Operators::bitwise_complement: return const_var(~t); default: - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -168,7 +168,7 @@ namespace chaiscript case Operators::unary_plus: return const_var(+t); default: - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -190,7 +190,7 @@ namespace chaiscript } else if (t_oper > Operators::const_flag) { return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -206,13 +206,13 @@ namespace chaiscript } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const()) { return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } else if (t_oper > Operators::const_flag) { return const_binary::go(t_oper, *static_cast(t_lhs.get_const_ptr()), *static_cast(t_rhs.get_const_ptr()), t_lhs); } else { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -238,24 +238,24 @@ namespace chaiscript return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int8_t)) { - return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int16_t)) { - return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int32_t)) { - return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int64_t)) { - return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint8_t)) { - return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint16_t)) { - return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint32_t)) { - return Go::go(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint64_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int8_t)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int16_t)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int32_t)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int64_t)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint8_t)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint16_t)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint32_t)) { + return Go::go(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint64_t)) { + return Go::go(t_oper, t_lhs, t_rhs); } else { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -279,24 +279,24 @@ namespace chaiscript return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int8_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int16_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int32_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::int64_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint8_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint16_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint32_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); - } else if (inp_ == typeid(boost::uint64_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int8_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int16_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int32_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::int64_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint8_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint16_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint32_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); + } else if (inp_ == typeid(std::uint64_t)) { + return oper_rhs(t_oper, t_lhs, t_rhs); } else { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -351,24 +351,24 @@ namespace chaiscript return Boxed_Number(get_as()); } else if (inp_.bare_equal_type_info(typeid(unsigned long))) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::int8_t))) { - return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::int16_t))) { - return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::int32_t))) { - return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::int64_t))) { - return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::uint8_t))) { - return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::uint16_t))) { - return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::uint32_t))) { - return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(boost::uint64_t))) { - return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(int8_t))) { + return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(int16_t))) { + return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(int32_t))) { + return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(int64_t))) { + return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(uint8_t))) { + return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(uint16_t))) { + return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(uint32_t))) { + return Boxed_Number(get_as()); + } else if (inp_.bare_equal_type_info(typeid(uint64_t))) { + return Boxed_Number(get_as()); } else { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -393,24 +393,24 @@ namespace chaiscript return get_as_aux(); } else if (inp_ == typeid(unsigned long)) { return get_as_aux(); - } else if (inp_ == typeid(boost::int8_t)) { - return get_as_aux(); - } else if (inp_ == typeid(boost::int16_t)) { - return get_as_aux(); - } else if (inp_ == typeid(boost::int32_t)) { - return get_as_aux(); - } else if (inp_ == typeid(boost::int64_t)) { - return get_as_aux(); - } else if (inp_ == typeid(boost::uint8_t)) { - return get_as_aux(); - } else if (inp_ == typeid(boost::uint16_t)) { - return get_as_aux(); - } else if (inp_ == typeid(boost::uint32_t)) { - return get_as_aux(); - } else if (inp_ == typeid(boost::uint64_t)) { - return get_as_aux(); + } else if (inp_ == typeid(std::int8_t)) { + return get_as_aux(); + } else if (inp_ == typeid(std::int16_t)) { + return get_as_aux(); + } else if (inp_ == typeid(std::int32_t)) { + return get_as_aux(); + } else if (inp_ == typeid(std::int64_t)) { + return get_as_aux(); + } else if (inp_ == typeid(std::uint8_t)) { + return get_as_aux(); + } else if (inp_ == typeid(std::uint16_t)) { + return get_as_aux(); + } else if (inp_ == typeid(std::uint32_t)) { + return get_as_aux(); + } else if (inp_ == typeid(std::uint64_t)) { + return get_as_aux(); } else { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -434,24 +434,24 @@ namespace chaiscript return to_string_aux(bv); } else if (inp_ == typeid(unsigned long)) { return to_string_aux(bv); - } else if (inp_ == typeid(boost::int8_t)) { - return to_string_aux(Boxed_Value(get_as_aux())); - } else if (inp_ == typeid(boost::int16_t)) { - return to_string_aux(bv); - } else if (inp_ == typeid(boost::int32_t)) { - return to_string_aux(bv); - } else if (inp_ == typeid(boost::int64_t)) { - return to_string_aux(bv); - } else if (inp_ == typeid(boost::uint8_t)) { - return to_string_aux(Boxed_Value(get_as_aux())); - } else if (inp_ == typeid(boost::uint16_t)) { - return to_string_aux(bv); - } else if (inp_ == typeid(boost::uint32_t)) { - return to_string_aux(bv); - } else if (inp_ == typeid(boost::uint64_t)) { - return to_string_aux(bv); + } else if (inp_ == typeid(std::int8_t)) { + return to_string_aux(Boxed_Value(get_as_aux())); + } else if (inp_ == typeid(std::int16_t)) { + return to_string_aux(bv); + } else if (inp_ == typeid(std::int32_t)) { + return to_string_aux(bv); + } else if (inp_ == typeid(std::int64_t)) { + return to_string_aux(bv); + } else if (inp_ == typeid(std::uint8_t)) { + return to_string_aux(Boxed_Value(get_as_aux())); + } else if (inp_ == typeid(std::uint16_t)) { + return to_string_aux(bv); + } else if (inp_ == typeid(std::uint32_t)) { + return to_string_aux(bv); + } else if (inp_ == typeid(std::uint64_t)) { + return to_string_aux(bv); } else { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -525,12 +525,12 @@ namespace chaiscript const Type_Info &inp_ = v.get_type_info(); if (inp_ == typeid(bool)) { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } if (!inp_.is_arithmetic()) { - throw boost::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -844,7 +844,7 @@ namespace chaiscript }; } -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index ab04ff53..bcb5839b 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -12,27 +12,7 @@ #include "../chaiscript_threading.hpp" #include -#include - -#ifdef __llvm__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wshadow" -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -#ifdef __llvm__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include -#include -#include -#include -#include +#include "any.hpp" namespace chaiscript { @@ -56,7 +36,7 @@ namespace chaiscript struct Data { Data(const Type_Info &ti, - const boost::any &to, + const chaiscript::detail::Any &to, bool tr, const void *t_void_ptr) : m_type_info(ti), m_obj(to), m_data_ptr(ti.is_const()?0:const_cast(t_void_ptr)), m_const_data_ptr(t_void_ptr), @@ -80,7 +60,7 @@ namespace chaiscript } Type_Info m_type_info; - boost::any m_obj; + chaiscript::detail::Any m_obj; void *m_data_ptr; const void *m_const_data_ptr; bool m_is_ref; @@ -88,65 +68,70 @@ namespace chaiscript struct Object_Data { - static boost::shared_ptr get(Boxed_Value::Void_Type) + static std::shared_ptr get(Boxed_Value::Void_Type) { - return boost::make_shared( + return std::make_shared( detail::Get_Type_Info::get(), - boost::any(), + chaiscript::detail::Any(), false, - static_cast(0)); + nullptr) + ; } template - static boost::shared_ptr get(const boost::shared_ptr *obj) + static std::shared_ptr get(const std::shared_ptr *obj) { return get(*obj); } template - static boost::shared_ptr get(const boost::shared_ptr &obj) + static std::shared_ptr get(const std::shared_ptr &obj) { - return boost::make_shared( + return std::make_shared( detail::Get_Type_Info::get(), - boost::any(obj), + chaiscript::detail::Any(obj), false, - obj.get()); + obj.get() + ); } template - static boost::shared_ptr get(T *t) + static std::shared_ptr get(T *t) { - return get(boost::ref(*t)); + return get(std::ref(*t)); } template - static boost::shared_ptr get(boost::reference_wrapper obj) + static std::shared_ptr get(std::reference_wrapper obj) { - return boost::make_shared( + return std::make_shared( detail::Get_Type_Info::get(), - boost::any(obj), + chaiscript::detail::Any(obj), true, - obj.get_pointer()); + &obj.get() + ); } template - static boost::shared_ptr get(const T& t) + static std::shared_ptr get(const T& t) { - boost::shared_ptr p(new T(t)); - return boost::make_shared( + auto p = std::make_shared(t); + return std::make_shared( detail::Get_Type_Info::get(), - boost::any(p), + chaiscript::detail::Any(p), false, - p.get()); + p.get() + ); } - static boost::shared_ptr get() + static std::shared_ptr get() { - return boost::make_shared( + return std::make_shared( Type_Info(), - boost::any(), + chaiscript::detail::Any(), false, - static_cast(0)); + nullptr + ); } }; @@ -234,7 +219,7 @@ namespace chaiscript return (m_data->m_data_ptr == 0 && m_data->m_const_data_ptr == 0); } - const boost::any & get() const + const chaiscript::detail::Any & get() const { return m_data->m_obj; } @@ -259,11 +244,17 @@ namespace chaiscript return m_data->m_const_data_ptr; } + /// \returns true if the two Boxed_Values share the same internal type + static bool type_match(Boxed_Value l, Boxed_Value r) + { + return l.get_type_info() == r.get_type_info(); + } + private: - boost::shared_ptr m_data; + std::shared_ptr m_data; }; - /// \brief Creates a Boxed_Value. If the object passed in is a value type, it is copied. If it is a pointer, boost::shared_ptr, or boost::reference_type + /// \brief Creates a Boxed_Value. If the object passed in is a value type, it is copied. If it is a pointer, std::shared_ptr, or std::reference_type /// a copy is not made. /// \param t The value to box /// @@ -290,7 +281,7 @@ namespace chaiscript template Boxed_Value const_var_impl(const T &t) { - return Boxed_Value(boost::shared_ptr::type >(new T(t))); + return Boxed_Value(std::shared_ptr::type >(new T(t))); } /// \brief Takes a pointer to a value, adds const to the pointed to type and returns an immutable Boxed_Value. @@ -301,33 +292,33 @@ namespace chaiscript template Boxed_Value const_var_impl(T *t) { - return Boxed_Value( const_cast::type *>(t) ); + return Boxed_Value( const_cast::type *>(t) ); } - /// \brief Takes a boost::shared_ptr to a value, adds const to the pointed to type and returns an immutable Boxed_Value. + /// \brief Takes a std::shared_ptr to a value, adds const to the pointed to type and returns an immutable Boxed_Value. /// Does not copy the pointed to value. /// \param[in] t Pointer to make immutable /// \returns Immutable Boxed_Value /// \sa Boxed_Value::is_const template - Boxed_Value const_var_impl(const boost::shared_ptr &t) + Boxed_Value const_var_impl(const std::shared_ptr &t) { - return Boxed_Value( boost::const_pointer_cast::type>(t) ); + return Boxed_Value( std::const_pointer_cast::type>(t) ); } - /// \brief Takes a boost::reference_wrapper value, adds const to the referenced type and returns an immutable Boxed_Value. + /// \brief Takes a std::reference_wrapper value, adds const to the referenced type and returns an immutable Boxed_Value. /// Does not copy the referenced value. /// \param[in] t Reference object to make immutable /// \returns Immutable Boxed_Value /// \sa Boxed_Value::is_const template - Boxed_Value const_var_impl(const boost::reference_wrapper &t) + Boxed_Value const_var_impl(const std::reference_wrapper &t) { - return Boxed_Value( boost::cref(t.get()) ); + return Boxed_Value( std::cref(t.get()) ); } } - /// \brief Takes an object and returns an immutable Boxed_Value. If the object is a boost::reference or pointer type + /// \brief Takes an object and returns an immutable Boxed_Value. If the object is a std::reference or pointer type /// the value is not copied. If it is an object type, it is copied. /// \param[in] t Object to make immutable /// \returns Immutable Boxed_Value @@ -357,11 +348,6 @@ namespace chaiscript - /// \returns true if the two Boxed_Values share the same internal type - static bool type_match(Boxed_Value l, Boxed_Value r) - { - return l.get_type_info() == r.get_type_info(); - } } #endif diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index f8e31fc6..93ed1fb8 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -11,12 +11,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include "boxed_value.hpp" #include "type_info.hpp" @@ -39,12 +39,12 @@ namespace chaiscript class reserved_word_error : public std::runtime_error { public: - reserved_word_error(const std::string &t_word) throw() + reserved_word_error(const std::string &t_word) CHAISCRIPT_NOEXCEPT : std::runtime_error("Reserved word not allowed in object name: " + t_word), m_word(t_word) { } - virtual ~reserved_word_error() throw() {} + virtual ~reserved_word_error() CHAISCRIPT_NOEXCEPT {} std::string word() const { @@ -108,12 +108,12 @@ namespace chaiscript class global_non_const : public std::runtime_error { public: - global_non_const() throw() + global_non_const() CHAISCRIPT_NOEXCEPT : std::runtime_error("a global object must be const") { } - virtual ~global_non_const() throw() {} + virtual ~global_non_const() CHAISCRIPT_NOEXCEPT {} }; } @@ -145,7 +145,7 @@ namespace chaiscript { if (!t_bv.is_const()) { - throw exception::global_non_const(); + throw chaiscript::exception::global_non_const(); } m_globals.push_back(std::make_pair(t_bv, t_name)); @@ -160,7 +160,7 @@ namespace chaiscript return *this; } - Module &add(const boost::shared_ptr &m) + Module &add(const std::shared_ptr &m) { m->apply(*this, *this); return *m; @@ -176,6 +176,10 @@ namespace chaiscript apply_globals(m_globals.begin(), m_globals.end(), t_engine); } + ~Module() + { + } + private: std::vector > m_typeinfos; std::vector > m_funcs; @@ -190,7 +194,7 @@ namespace chaiscript { try { t.add(begin->first, begin->second); - } catch (const exception::name_conflict_error &) { + } catch (const chaiscript::exception::name_conflict_error &) { /// \todo Should we throw an error if there's a name conflict /// while applying a module? } @@ -230,7 +234,7 @@ namespace chaiscript }; /// Convenience typedef for Module objects to be added to the ChaiScript runtime - typedef boost::shared_ptr ModulePtr; + typedef std::shared_ptr ModulePtr; namespace detail { @@ -393,7 +397,7 @@ namespace chaiscript typedef std::map Type_Name_Map; typedef std::map Scope; typedef std::deque StackData; - typedef boost::shared_ptr Stack; + typedef std::shared_ptr Stack; struct State { @@ -402,10 +406,12 @@ namespace chaiscript std::map m_global_objects; Type_Name_Map m_types; std::set m_reserved_words; + + State &operator=(const State &) = default; }; Dispatch_Engine() - : m_place_holder(boost::shared_ptr(new dispatch::Placeholder_Object())) + : m_place_holder(std::shared_ptr(new dispatch::Placeholder_Object())) { } @@ -472,7 +478,7 @@ namespace chaiscript Scope::iterator itr = scope.find(name); if (itr != stack.back().end()) { - throw exception::name_conflict_error(name); + throw chaiscript::exception::name_conflict_error(name); } else { stack.back().insert(std::make_pair(name, obj)); } @@ -486,14 +492,14 @@ namespace chaiscript validate_object_name(name); if (!obj.is_const()) { - throw exception::global_non_const(); + throw chaiscript::exception::global_non_const(); } chaiscript::detail::threading::unique_lock l(m_global_object_mutex); if (m_state.m_global_objects.find(name) != m_state.m_global_objects.end()) { - throw exception::name_conflict_error(name); + throw chaiscript::exception::name_conflict_error(name); } else { m_state.m_global_objects.insert(std::make_pair(name, obj)); } @@ -511,7 +517,7 @@ namespace chaiscript if (m_state.m_global_objects.find(name) != m_state.m_global_objects.end()) { - throw exception::name_conflict_error(name); + throw chaiscript::exception::name_conflict_error(name); } else { m_state.m_global_objects.insert(std::make_pair(name, obj)); } @@ -903,7 +909,7 @@ namespace chaiscript { if (params.size() < 1) { - throw exception::arity_error(static_cast(params.size()), 1); + throw chaiscript::exception::arity_error(static_cast(params.size()), 1); } Const_Proxy_Function f = this->boxed_cast(params[0]); @@ -1048,8 +1054,8 @@ namespace chaiscript const Type_Info boxed_type = user_type(); const Type_Info boxed_pod_type = user_type(); - boost::shared_ptr dynamic_lhs(boost::dynamic_pointer_cast(lhs)); - boost::shared_ptr dynamic_rhs(boost::dynamic_pointer_cast(rhs)); + std::shared_ptr dynamic_lhs(std::dynamic_pointer_cast(lhs)); + std::shared_ptr dynamic_rhs(std::dynamic_pointer_cast(rhs)); if (dynamic_lhs && dynamic_rhs) { @@ -1138,14 +1144,14 @@ namespace chaiscript void validate_object_name(const std::string &name) const { if (name.find("::") != std::string::npos) { - throw exception::illegal_name_error(name); + throw chaiscript::exception::illegal_name_error(name); } chaiscript::detail::threading::shared_lock l(m_mutex); if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end()) { - throw exception::reserved_word_error(name); + throw chaiscript::exception::reserved_word_error(name); } } @@ -1173,7 +1179,7 @@ namespace chaiscript { if ((*t_f) == *(*itr2)) { - throw exception::name_conflict_error(t_name); + throw chaiscript::exception::name_conflict_error(t_name); } } diff --git a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp index 91e0a884..1fd461bb 100644 --- a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp +++ b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp @@ -7,13 +7,13 @@ #ifndef CHAISCRIPT_DYNAMIC_CAST_CONVERSION_HPP_ #define CHAISCRIPT_DYNAMIC_CAST_CONVERSION_HPP_ +#include +#include + #include "type_info.hpp" #include "boxed_value.hpp" #include "boxed_cast_helper.hpp" #include "bad_boxed_cast.hpp" -#include -#include -#include namespace chaiscript { @@ -23,22 +23,22 @@ namespace chaiscript { public: bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to, - const std::string &t_what) throw() + const std::string &t_what) CHAISCRIPT_NOEXCEPT : bad_boxed_cast(t_from, t_to, t_what) { } - bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) throw() + bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) CHAISCRIPT_NOEXCEPT : bad_boxed_cast(t_from, t_to) { } - bad_boxed_dynamic_cast(const std::string &w) throw() + bad_boxed_dynamic_cast(const std::string &w) CHAISCRIPT_NOEXCEPT : bad_boxed_cast(w) { } - virtual ~bad_boxed_dynamic_cast() throw() {} + virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT {} }; } @@ -90,8 +90,8 @@ namespace chaiscript // Dynamic cast out the contained boxed value, which we know is the type we want if (t_derived.is_const()) { - boost::shared_ptr data - = boost::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, 0)); + std::shared_ptr data + = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, nullptr)); if (!data) { throw std::bad_cast(); @@ -99,8 +99,8 @@ namespace chaiscript return Boxed_Value(data); } else { - boost::shared_ptr data - = boost::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, 0)); + std::shared_ptr data + = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, nullptr)); if (!data) { @@ -115,15 +115,15 @@ namespace chaiscript { const Derived &d = detail::Cast_Helper::cast(t_derived, 0); const Base &data = dynamic_cast(d); - return Boxed_Value(boost::cref(data)); + return Boxed_Value(std::cref(data)); } else { Derived &d = detail::Cast_Helper::cast(t_derived, 0); Base &data = dynamic_cast(d); - return Boxed_Value(boost::ref(data)); + return Boxed_Value(std::ref(data)); } } } else { - throw exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion"); + throw chaiscript::exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion"); } } }; @@ -141,7 +141,7 @@ namespace chaiscript { } - void add_conversion(const boost::shared_ptr &conversion) + void add_conversion(const std::shared_ptr &conversion) { chaiscript::detail::threading::unique_lock l(m_mutex); m_conversions.insert(conversion); @@ -176,11 +176,11 @@ namespace chaiscript return find(base, derived) != m_conversions.end(); } - boost::shared_ptr get_conversion(const Type_Info &base, const Type_Info &derived) const + std::shared_ptr get_conversion(const Type_Info &base, const Type_Info &derived) const { chaiscript::detail::threading::shared_lock l(m_mutex); - std::set >::const_iterator itr = + std::set >::const_iterator itr = find(base, derived); if (itr != m_conversions.end()) @@ -192,10 +192,10 @@ namespace chaiscript } private: - std::set >::const_iterator find( + std::set >::const_iterator find( const Type_Info &base, const Type_Info &derived) const { - for (std::set >::const_iterator itr = m_conversions.begin(); + for (std::set >::const_iterator itr = m_conversions.begin(); itr != m_conversions.end(); ++itr) { @@ -208,7 +208,7 @@ namespace chaiscript return m_conversions.end(); } - std::set > get_conversions() const + std::set > get_conversions() const { chaiscript::detail::threading::shared_lock l(m_mutex); @@ -216,10 +216,10 @@ namespace chaiscript } mutable chaiscript::detail::threading::shared_mutex m_mutex; - std::set > m_conversions; + std::set > m_conversions; }; - typedef boost::shared_ptr Dynamic_Cast_Conversion; + typedef std::shared_ptr Dynamic_Cast_Conversion; /// \brief Used to register a base / parent class relationship with ChaiScript. Necessary if you /// want automatic conversions up your inheritance hierarchy. @@ -245,16 +245,16 @@ namespace chaiscript /// \todo Move share static type registration code into a mechanism that allows it to be properly /// shared by all modules template - Dynamic_Cast_Conversion base_class() - { - //Can only be used with related polymorphic types - //may be expanded some day to support conversions other than child -> parent - BOOST_STATIC_ASSERT((boost::is_base_of::value)); - BOOST_STATIC_ASSERT(boost::is_polymorphic::value); - BOOST_STATIC_ASSERT(boost::is_polymorphic::value); + Dynamic_Cast_Conversion base_class() + { + //Can only be used with related polymorphic types + //may be expanded some day to support conversions other than child -> parent + static_assert(std::is_base_of::value, "Classes are not related by inheritance"); + static_assert(std::is_polymorphic::value, "Base class must be polymorphic"); + static_assert(std::is_polymorphic::value, "Derived class must be polymorphic"); - return boost::shared_ptr(new detail::Dynamic_Conversion_Impl()); - } + return std::shared_ptr(new detail::Dynamic_Conversion_Impl()); + } } diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 8952a4a0..487505c9 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -7,7 +7,6 @@ #ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_ #define CHAISCRIPT_DYNAMIC_OBJECT_HPP_ -#include namespace chaiscript { @@ -52,12 +51,22 @@ namespace chaiscript class Dynamic_Object_Function : public Proxy_Function_Base { public: + Dynamic_Object_Function( + const std::string &t_type_name, + const Proxy_Function &t_func) + : Proxy_Function_Base(t_func->get_param_types()), + m_type_name(t_type_name), m_func(t_func) + { + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); + } + Dynamic_Object_Function( const std::string &t_type_name, const Proxy_Function &t_func, - const boost::optional &t_ti = boost::optional()) + const Type_Info &t_ti) : Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)), - m_type_name(t_type_name), m_func(t_func), m_ti(t_ti) + m_type_name(t_type_name), m_func(t_func), m_ti(new Type_Info(t_ti)) { assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); @@ -88,9 +97,7 @@ namespace chaiscript virtual std::vector get_contained_functions() const { - std::vector fs; - fs.push_back(m_func); - return fs; + return {m_func}; } @@ -123,23 +130,18 @@ namespace chaiscript private: static std::vector build_param_types( - const std::vector &t_inner_types, boost::optional t_objectti) + const std::vector &t_inner_types, const Type_Info& t_objectti) { - if (t_objectti) - { - std::vector types(t_inner_types); + std::vector types(t_inner_types); - assert(types.size() > 1); - assert(types[1].bare_equal(user_type())); - types[1] = *t_objectti; - return types; - } else { - return t_inner_types; - } + assert(types.size() > 1); + assert(types[1].bare_equal(user_type())); + types[1] = t_objectti; + return types; } static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, - const boost::optional &ti, const Dynamic_Cast_Conversions &t_conversions) + const std::shared_ptr &ti, const Dynamic_Cast_Conversions &t_conversions) { static Type_Info doti = user_type(); if (bv.get_type_info().bare_equal(doti)) @@ -162,7 +164,7 @@ namespace chaiscript } static bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, - const boost::optional &ti, const Dynamic_Cast_Conversions &t_conversions) + const std::shared_ptr &ti, const Dynamic_Cast_Conversions &t_conversions) { if (bvs.size() > 0) { @@ -174,7 +176,7 @@ namespace chaiscript std::string m_type_name; Proxy_Function m_func; - boost::optional m_ti; + std::shared_ptr m_ti; }; diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 909e7fb4..1997ef09 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -23,7 +23,7 @@ namespace chaiscript template void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - try { T t = t_engine.boxed_cast(bv); throw t; } catch (const exception::bad_boxed_cast &) {} + try { T t = t_engine.boxed_cast(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {} } }; @@ -140,7 +140,7 @@ namespace chaiscript /// /// \sa chaiscript::exception_specification for creation of chaiscript::Exception_Handler objects /// \sa \ref exceptions - typedef boost::shared_ptr Exception_Handler; + typedef std::shared_ptr Exception_Handler; /// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing /// \sa \ref exceptions diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 27749f9b..1ef1ca49 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -7,9 +7,6 @@ #ifndef CHAISCRIPT_FUNCTION_CALL_HPP_ #define CHAISCRIPT_FUNCTION_CALL_HPP_ -#include -#include -#include #include #include #include "proxy_functions.hpp" @@ -25,13 +22,13 @@ namespace chaiscript /** * Build a function caller that knows how to dispatch on a set of functions * example: - * boost::function f = + * std::function f = * build_function_caller(dispatchkit.get_function("print")); - * \returns A boost::function object for dispatching + * \returns A std::function object for dispatching * \param[in] funcs the set of functions to dispatch on. */ template - boost::function + std::function functor(const std::vector &funcs, const Dynamic_Cast_Conversions *t_conversions) { FunctionType *p=0; @@ -45,14 +42,14 @@ namespace chaiscript * example: * void my_function(Proxy_Function f) * { - * boost::function local_f = + * std::function local_f = * build_function_caller(f); * } - * \returns A boost::function object for dispatching + * \returns A std::function object for dispatching * \param[in] func A function to execute. */ template - boost::function + std::function functor(Const_Proxy_Function func, const Dynamic_Cast_Conversions *t_conversions) { std::vector funcs; @@ -65,7 +62,7 @@ namespace chaiscript * and creating a typesafe C++ function caller from it. */ template - boost::function + std::function functor(const Boxed_Value &bv, const Dynamic_Cast_Conversions *t_conversions) { return functor(boxed_cast(bv, t_conversions), t_conversions); @@ -74,12 +71,12 @@ namespace chaiscript namespace detail{ /** - * Cast helper to handle automatic casting to const boost::function & + * Cast helper to handle automatic casting to const std::function & */ template - struct Cast_Helper &> + struct Cast_Helper &> { - typedef boost::function Result_Type; + typedef std::function Result_Type; static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *t_conversions) { @@ -87,18 +84,18 @@ namespace chaiscript { return dispatch::functor(ob, t_conversions); } else { - return Cast_Helper_Inner &>::cast(ob, t_conversions); + return Cast_Helper_Inner &>::cast(ob, t_conversions); } } }; /** - * Cast helper to handle automatic casting to boost::function + * Cast helper to handle automatic casting to std::function */ template - struct Cast_Helper > + struct Cast_Helper > { - typedef boost::function Result_Type; + typedef std::function Result_Type; static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *t_conversions) { @@ -106,18 +103,18 @@ namespace chaiscript { return dispatch::functor(ob, t_conversions); } else { - return Cast_Helper_Inner >::cast(ob, t_conversions); + return Cast_Helper_Inner >::cast(ob, t_conversions); } } }; /** - * Cast helper to handle automatic casting to const boost::function + * Cast helper to handle automatic casting to const std::function */ template - struct Cast_Helper > + struct Cast_Helper > { - typedef boost::function Result_Type; + typedef std::function Result_Type; static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *t_conversions) { @@ -125,7 +122,7 @@ namespace chaiscript { return dispatch::functor(ob, t_conversions); } else { - return Cast_Helper_Inner >::cast(ob, t_conversions); + return Cast_Helper_Inner >::cast(ob, t_conversions); } } }; diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index b739281f..579ae678 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -4,19 +4,9 @@ // Copyright 2009-2014, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com -#include - -#define addparam(z,n,text) params.push_back((boost::is_reference::value&&!(boost::is_same::type>::type>::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)) - - -#ifndef BOOST_PP_IS_ITERATING #ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_ #define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_ -#include -#include -#include #include #include #include "proxy_functions.hpp" @@ -54,51 +44,43 @@ namespace chaiscript dispatch::dispatch(t_funcs, params, t_conversions); } }; - } - } -} -#define BOOST_PP_ITERATION_LIMITS ( 0, 9 ) -#define BOOST_PP_FILENAME_1 -#include BOOST_PP_ITERATE() - -# endif -#else -# define n BOOST_PP_ITERATION() - -namespace chaiscript -{ - namespace dispatch - { - namespace detail - { /** * used internally for unwrapping a function call's types */ - template - Ret function_caller(const std::vector &funcs, const Dynamic_Cast_Conversions &t_conversions - BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) + template + struct Build_Function_Caller_Helper { - std::vector params; + Build_Function_Caller_Helper(const std::vector &t_funcs, const Dynamic_Cast_Conversions &t_conversions) + : m_funcs(t_funcs), + m_conversions(t_conversions) + { + } - BOOST_PP_REPEAT(n, addparam, ~); + Ret operator()(Param...param) + { + return Function_Caller_Ret::call(m_funcs, { +(std::is_reference::value&&!(std::is_same::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)... + }, m_conversions + + ); - return Function_Caller_Ret::call(funcs, params, t_conversions); - } + } - /** - * used internally for unwrapping a function call's types - */ - template - boost::function - build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector &funcs, - const Dynamic_Cast_Conversions *t_conversions) + std::vector m_funcs; + Dynamic_Cast_Conversions m_conversions; + }; + + + + template + std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Dynamic_Cast_Conversions *t_conversions) { if (funcs.size() == 1) { - boost::shared_ptr > pfi = - boost::dynamic_pointer_cast > - (funcs[0]); + std::shared_ptr> pfi = + std::dynamic_pointer_cast > + (funcs[0]); if (pfi) { @@ -108,15 +90,11 @@ namespace chaiscript // we cannot make any other guesses or assumptions really, so continuing } - return boost::bind(&function_caller, funcs, (t_conversions?*t_conversions:Dynamic_Cast_Conversions()) - BOOST_PP_ENUM_TRAILING(n, curry, ~)); + return std::function(Build_Function_Caller_Helper(funcs, t_conversions?*t_conversions:Dynamic_Cast_Conversions())); } } } } -#undef n -#undef addparam -#undef curry #endif diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index ff1902de..99e4cd57 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -11,7 +11,6 @@ #include "boxed_number.hpp" #include "type_info.hpp" #include -#include #include #include @@ -44,27 +43,27 @@ namespace chaiscript }; template - struct Handle_Return &> + struct Handle_Return &> { - static Boxed_Value handle(const boost::shared_ptr &r) + static Boxed_Value handle(const std::shared_ptr &r) { return Boxed_Value(r); } }; template - struct Handle_Return > + struct Handle_Return > { - static Boxed_Value handle(const boost::shared_ptr &r) + static Boxed_Value handle(const std::shared_ptr &r) { return Boxed_Value(r); } }; template - struct Handle_Return &> + struct Handle_Return &> { - static Boxed_Value handle(const boost::shared_ptr &r) + static Boxed_Value handle(const std::shared_ptr &r) { return Boxed_Value(r); } @@ -75,7 +74,7 @@ namespace chaiscript { static Boxed_Value handle(const Ret &r) { - return Boxed_Value(boost::cref(r)); + return Boxed_Value(std::cref(r)); } }; @@ -88,12 +87,12 @@ namespace chaiscript { static Boxed_Value handle(Ret &r) { - return Boxed_Value(boost::ref(r)); + return Boxed_Value(std::ref(r)); } static Boxed_Value handle(const Ret &r) { - return Boxed_Value(boost::cref(r)); + return Boxed_Value(std::cref(r)); } }; diff --git a/include/chaiscript/dispatchkit/operators.hpp b/include/chaiscript/dispatchkit/operators.hpp index 8677c511..ed64b2c4 100644 --- a/include/chaiscript/dispatchkit/operators.hpp +++ b/include/chaiscript/dispatchkit/operators.hpp @@ -7,6 +7,8 @@ #ifndef CHAISCRIPT_OPERATORS_HPP_ #define CHAISCRIPT_OPERATORS_HPP_ +#include "../chaiscript_defines.hpp" + namespace chaiscript { namespace bootstrap @@ -154,7 +156,7 @@ namespace chaiscript template Ret unary_minus(L l) { -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(push) #pragma warning(disable : 4146) return (-l); diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index 5d436ced..1fe2f3f9 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -4,24 +4,36 @@ // Copyright 2009-2014, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com -#include -#ifndef BOOST_PP_IS_ITERATING #ifndef CHAISCRIPT_PROXY_CONSTRUCTORS_HPP_ #define CHAISCRIPT_PROXY_CONSTRUCTORS_HPP_ -#include -#include -#include - - -#define BOOST_PP_ITERATION_LIMITS ( 0, 10 ) -#define BOOST_PP_FILENAME_1 -#include BOOST_PP_ITERATE() -# endif - namespace chaiscript { + namespace dispatch + { + namespace detail + { + /** + * A constructor function, used for creating a new object + * of a given type with a given set of params + */ + template + std::shared_ptr constructor_(Params ... params) + { + return std::shared_ptr(new Class(params...)); + } + + template + Proxy_Function build_constructor_(Class (*)(Params...)) + { + typedef std::shared_ptr (sig)(Params...); + return Proxy_Function(new Proxy_Function_Impl(std::function(&(constructor_)))); + } + } + } + + /// \brief Generates a constructor function for use with ChaiScript /// /// \tparam T The signature of the constructor to generate. In the form of: ClassType (ParamType1, ParamType2, ...) @@ -39,43 +51,8 @@ namespace chaiscript T *f = 0; return (dispatch::detail::build_constructor_(f)); } + } -#else -# define n BOOST_PP_ITERATION() - -namespace chaiscript -{ - namespace dispatch - { - namespace detail - { - /** - * A constructor function, used for creating a new object - * of a given type with a given set of params - */ - template - boost::shared_ptr constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) - { - return boost::shared_ptr(new Class( BOOST_PP_ENUM_PARAMS(n, p) )); - } - - /** - * Helper function for build a constructor function - * example: - * dispatchengine.register_function(build_constructor, "MyClass"); - * \todo See if it is possible to make this not be a variadic function - */ - template - Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param))) - { - typedef boost::shared_ptr (sig)(BOOST_PP_ENUM_PARAMS(n, Param)); - return Proxy_Function(new Proxy_Function_Impl(boost::function(&(constructor_)))); - } - } - } -} -#undef n - #endif diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 2b4aff7f..d5de8556 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -12,10 +12,10 @@ #include "boxed_value.hpp" #include "type_info.hpp" #include -#include -#include +#include #include #include +#include #include "proxy_functions_detail.hpp" namespace chaiscript @@ -23,41 +23,10 @@ namespace chaiscript class Boxed_Number; struct AST_Node; - typedef boost::shared_ptr AST_NodePtr; + typedef std::shared_ptr AST_NodePtr; namespace dispatch { - /** - * Helper for building a list of parameters for calling a Proxy_Function - * it does automatic conversion to Boxed_Value types via operator<< - * - * example usage: - * Boxed_Value retval = dispatch(dispatchengine.get_function("+"), - * chaiscript::Param_List_Builder() << 5 << 6); - */ - struct Param_List_Builder - { - Param_List_Builder &operator<<(const Boxed_Value &so) - { - objects.push_back(so); - return *this; - } - - template - Param_List_Builder &operator<<(T t) - { - objects.push_back(Boxed_Value(t)); - return *this; - } - - operator const std::vector &() const - { - return objects; - } - - std::vector objects; - }; - /** * Pure virtual base class for all Proxy_Function implementations * Proxy_Functions are a type erasure of type safe C++ @@ -70,6 +39,7 @@ namespace chaiscript { public: virtual ~Proxy_Function_Base() {} + Boxed_Value operator()(const std::vector ¶ms, const chaiscript::Dynamic_Cast_Conversions &t_conversions) const { Boxed_Value bv = do_call(params, t_conversions); @@ -80,7 +50,7 @@ namespace chaiscript /// if the function is variadic or takes no arguments (arity of 0 or -1), the returned /// value containes exactly 1 Type_Info object: the return type /// \returns the types of all parameters. - std::vector get_param_types() const { return m_types; } + const std::vector &get_param_types() const { return m_types; } virtual bool operator==(const Proxy_Function_Base &) const = 0; virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const = 0; @@ -90,12 +60,11 @@ namespace chaiscript return m_has_arithmetic_param; } - virtual std::vector > get_contained_functions() const + virtual std::vector > get_contained_functions() const { - return std::vector >(); + return std::vector >(); } - //! Return true if the function is a possible match //! to the passed in values bool filter(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const @@ -129,7 +98,7 @@ namespace chaiscript || (!bv.get_type_info().is_undef() && (ti.bare_equal(user_type()) || ti.bare_equal(bv.get_type_info()) - || bv.get_type_info().bare_equal(user_type >()) + || bv.get_type_info().bare_equal(user_type >()) || t_conversions.dynamic_cast_converts(ti, bv.get_type_info()) ) ) @@ -196,11 +165,11 @@ namespace chaiscript } /// \brief Common typedef used for passing of any registered function in ChaiScript - typedef boost::shared_ptr Proxy_Function; + typedef std::shared_ptr Proxy_Function; /// \brief Const version of Proxy_Function chaiscript. Points to a const Proxy_Function. This is how most registered functions /// are handled internally. - typedef boost::shared_ptr Const_Proxy_Function; + typedef std::shared_ptr Const_Proxy_Function; namespace exception { @@ -208,11 +177,11 @@ namespace chaiscript class guard_error : public std::runtime_error { public: - guard_error() throw() + guard_error() CHAISCRIPT_NOEXCEPT : std::runtime_error("Guard evaluation failed") { } - virtual ~guard_error() throw() + virtual ~guard_error() CHAISCRIPT_NOEXCEPT { } }; } @@ -227,7 +196,7 @@ namespace chaiscript { public: Dynamic_Proxy_Function( - const boost::function &)> &t_f, + const std::function &)> &t_f, int t_arity=-1, const AST_NodePtr &t_parsenode = AST_NodePtr(), const std::string &t_description = "", @@ -237,6 +206,8 @@ namespace chaiscript { } + virtual ~Dynamic_Proxy_Function() {} + virtual bool operator==(const Proxy_Function_Base &rhs) const { const Dynamic_Proxy_Function *prhs = dynamic_cast(&rhs); @@ -253,9 +224,6 @@ namespace chaiscript && test_guard(vals, t_conversions); } - virtual ~Dynamic_Proxy_Function() {} - - virtual int get_arity() const { return m_arity; @@ -318,7 +286,7 @@ namespace chaiscript // For the return type types.push_back(chaiscript::detail::Get_Type_Info::get()); - if (arity >= 0) + if (arity > 0) { for (int i = 0; i < arity; ++i) { @@ -329,7 +297,7 @@ namespace chaiscript return types; } - boost::function &)> m_f; + std::function &)> m_f; int m_arity; std::string m_description; Proxy_Function m_guard; @@ -429,6 +397,7 @@ namespace chaiscript const std::vector &t_args) { assert(t_f->get_arity() < 0 || t_f->get_arity() == static_cast(t_args.size())); + if (t_f->get_arity() < 0) { return std::vector(); } std::vector types = t_f->get_param_types(); @@ -460,14 +429,14 @@ namespace chaiscript /** * The standard typesafe function call implementation of Proxy_Function - * It takes a boost::function<> object and performs runtime + * It takes a std::function<> object and performs runtime * type checking of Boxed_Value parameters, in a type safe manner */ template class Proxy_Function_Impl : public Proxy_Function_Base { public: - Proxy_Function_Impl(const boost::function &f) + Proxy_Function_Impl(const std::function &f) : Proxy_Function_Base(detail::build_param_type_list(static_cast(0))), m_f(f), m_dummy_func(0) { @@ -481,13 +450,11 @@ namespace chaiscript return pimpl != 0; } - virtual int get_arity() const { return static_cast(m_types.size()) - 1; } - virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { if (int(vals.size()) != get_arity()) @@ -503,7 +470,7 @@ namespace chaiscript return ""; } - boost::function internal_function() const + std::function internal_function() const { return m_f; } @@ -511,11 +478,11 @@ namespace chaiscript protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { - return detail::Do_Call::result_type>::go(m_f, params, t_conversions); + return detail::Do_Call::result_type>::go(m_f, params, t_conversions); } private: - boost::function m_f; + std::function m_f; Func *m_dummy_func; }; @@ -538,6 +505,7 @@ namespace chaiscript { const Attribute_Access * aa = dynamic_cast *>(&t_func); + if (aa) { return m_attr == aa->m_attr; } else { @@ -575,10 +543,10 @@ namespace chaiscript if (bv.is_const()) { const Class *o = boxed_cast(bv, &t_conversions); - return detail::Handle_Return::type>::handle(o->*m_attr); + return detail::Handle_Return::type>::handle(o->*m_attr); } else { Class *o = boxed_cast(bv, &t_conversions); - return detail::Handle_Return::type>::handle(o->*m_attr); + return detail::Handle_Return::type>::handle(o->*m_attr); } } else { throw exception::arity_error(static_cast(params.size()), 1); @@ -588,11 +556,9 @@ namespace chaiscript private: static std::vector param_types() { - std::vector v; - v.push_back(user_type()); - v.push_back(user_type()); - return v; + return {user_type(), user_type()}; } + T Class::* m_attr; }; } @@ -613,7 +579,7 @@ namespace chaiscript { } - virtual ~dispatch_error() throw() {} + virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {} std::vector parameters; std::vector functions; diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index dedc44ef..8f1901c6 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -4,13 +4,6 @@ // Copyright 2009-2014, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com -#include - -#define gettypeinfo(z,n,text) ti.push_back(chaiscript::detail::Get_Type_Info::get()); -#define casthelper(z,n,text) BOOST_PP_COMMA_IF(n) chaiscript::boxed_cast< Param ## n >(params[n], &t_conversions) -#define trycast(z,n,text) chaiscript::boxed_cast(params[n], &t_conversions); - -#ifndef BOOST_PP_IS_ITERATING #ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ #define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ @@ -19,8 +12,6 @@ #include "type_info.hpp" #include "handle_return.hpp" #include -#include -#include #include #include @@ -41,109 +32,91 @@ namespace chaiscript { } - virtual ~arity_error() throw() {} + virtual ~arity_error() CHAISCRIPT_NOEXCEPT {} int got; int expected; }; } -} - -#define BOOST_PP_ITERATION_LIMITS ( 0, 10 ) -#define BOOST_PP_FILENAME_1 -#include BOOST_PP_ITERATE() - - -# endif -#else -# define n BOOST_PP_ITERATION() - -namespace chaiscript -{ namespace dispatch { namespace detail { + template + struct Build_Param_Type_List; + + template + struct Build_Param_Type_List + { + static void build(std::vector &t_params) + { + t_params.push_back(chaiscript::detail::Get_Type_Info::get()); + Build_Param_Type_List::build(t_params); + } + }; + + // 0th case + template<> + struct Build_Param_Type_List<> + { + static void build(std::vector &) + { + } + }; + + /** * Used by Proxy_Function_Impl to return a list of all param types * it contains. */ - template - std::vector build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param))) + template + std::vector build_param_type_list(Ret (*)(Params...)) { - std::vector ti; - ti.push_back(chaiscript::detail::Get_Type_Info::get()); - - BOOST_PP_REPEAT(n, gettypeinfo, ~) - - return ti; + /// \todo this code was previously using { chaiscript::detail::Get_Type_Info::get()... } + /// but this seems to indicate another bug with MSVC's uniform initializer lists + std::vector params; + params.push_back(chaiscript::detail::Get_Type_Info::get()); + Build_Param_Type_List::build(params); + return params; } - /** - * Used by Proxy_Function_Impl to perform typesafe execution of a function. - * The function attempts to unbox each paramter to the expected type. - * if any unboxing fails the execution of the function fails and - * the bad_boxed_cast is passed up to the caller. - */ -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4100) -#endif -#ifdef __llvm__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif + // Forward declaration + template + struct Try_Cast; - template - Ret call_func(const boost::function &f, - const std::vector ¶ms, const Dynamic_Cast_Conversions & BOOST_PP_IF(n, t_conversions, BOOST_PP_EMPTY)) - -#ifdef __llvm__ -#pragma clang diagnostic pop -#endif + template + struct Try_Cast { - if (params.size() != n) + static void do_try(const std::vector ¶ms, int generation, const Dynamic_Cast_Conversions &t_conversions) { - throw exception::arity_error(static_cast(params.size()), n); - } else { - return f(BOOST_PP_REPEAT(n, casthelper, ~)); + boxed_cast(params[generation], &t_conversions); + Try_Cast::do_try(params, generation+1, t_conversions); } - } + }; -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif + // 0th case + template<> + struct Try_Cast<> + { + static void do_try(const std::vector &, int, const Dynamic_Cast_Conversions &) + { + } + }; + /** * Used by Proxy_Function_Impl to determine if it is equivalent to another * Proxy_Function_Impl object. This function is primarly used to prevent * registration of two functions with the exact same signatures */ - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4100) -#endif - -#ifdef __llvm__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - - template - bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), - const std::vector & BOOST_PP_IF(n, params, BOOST_PP_EMPTY), const Dynamic_Cast_Conversions &t_conversions) - - -#ifdef __llvm__ -#pragma clang diagnostic pop -#endif - { + template + bool compare_types_cast(Ret (*)(Params...), + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) + { try { - (void)t_conversions; - BOOST_PP_REPEAT(n, trycast, ~); + Try_Cast::do_try(params, 0, t_conversions); } catch (const exception::bad_boxed_cast &) { return false; } @@ -151,24 +124,59 @@ namespace chaiscript return true; } -#ifdef BOOST_MSVC + template + struct Call_Func + { + + template + static Ret do_call(const std::function &f, + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions, InnerParams &&... innerparams) + { + return Call_Func::do_call(f, params, t_conversions, std::forward(innerparams)..., params[sizeof...(Params) - count]); + } + }; + + template + struct Call_Func + { +#ifdef CHAISCRIPT_MSVC +#pragma warning(push) +#pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this +#endif + template + static Ret do_call(const std::function &f, + const std::vector &, const Dynamic_Cast_Conversions &t_conversions, InnerParams &&... innerparams) + { + return f(boxed_cast(std::forward(innerparams), &t_conversions)...); + } +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif + }; + /** + * Used by Proxy_Function_Impl to perform typesafe execution of a function. + * The function attempts to unbox each paramter to the expected type. + * if any unboxing fails the execution of the function fails and + * the bad_boxed_cast is passed up to the caller. + */ + template + Ret call_func(const std::function &f, + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) + { + if (params.size() == sizeof...(Params)) + { + return Call_Func::do_call(f, params, t_conversions); + } + + throw exception::arity_error(static_cast(params.size()), sizeof...(Params)); + } + } } + } -#undef n -#undef gettypeinfo -#undef casthelper -#undef trycast - - -#endif - - -#ifndef BOOST_PP_IS_ITERATING namespace chaiscript { @@ -180,7 +188,7 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const boost::function &fun, const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) + static Boxed_Value go(const std::function &fun, const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { return Handle_Return::handle(call_func(fun, params, t_conversions)); } @@ -190,7 +198,7 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const boost::function &fun, const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) + static Boxed_Value go(const std::function &fun, const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { call_func(fun, params, t_conversions); return Handle_Return::handle(); diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index afa56589..c1993b39 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -9,12 +9,6 @@ #include "dispatchkit.hpp" #include "bind_first.hpp" -#include -#include -#include -#include -#include -#include namespace chaiscript { @@ -22,39 +16,53 @@ namespace chaiscript { namespace detail { - template + template + struct FunctionSignature + { + }; + + template + struct FunctionSignature > + { + typedef Sig Signature; + }; + + template + std::function to_function(Ret (*func)(Args...)) + { + return std::function(func); + } + + template + std::function to_function(Ret (Class::*func)(Args...)) + { + /// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for + /// std::function for member function pointers seems to be broken in MSVC + return std::function(std::mem_fn(func)); + } + + template + std::function to_function(Ret (Class::*func)(Args...) const) + { + /// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for + /// std::function for member function pointers seems to be broken in MSVC + return std::function(std::mem_fn(func)); + } + + template struct Fun_Helper { template static Proxy_Function go(T t) { + /// \todo is it possible to reduce the number of templates generated here? return Proxy_Function( - new Proxy_Function_Impl< - typename boost::function_types::function_type >::type> ( - boost::function< - typename boost::function_types::function_type >::type - >(t))); + new Proxy_Function_Impl::Signature>(to_function(t))); } }; template<> - struct Fun_Helper - { - template - static Proxy_Function go(T t) - { - return Proxy_Function( - new Proxy_Function_Impl< - typename boost::function_types::function_type >::type> ( - boost::function< - typename boost::function_types::function_type >::type - >(boost::mem_fn(t)))); - } - }; - - - template<> - struct Fun_Helper + struct Fun_Helper { template static Proxy_Function go(T Class::* m) @@ -65,23 +73,6 @@ namespace chaiscript } } - /// \brief Creates a new Proxy_Function object from a boost::function object - /// \param[in] f boost::function to expose to ChaiScript - /// - /// \b Example: - /// \code - /// boost::function f = get_some_function(); - /// chaiscript::ChaiScript chai; - /// chai.add(fun(f), "some_function"); - /// \endcode - /// - /// \sa \ref addingfunctions - template - Proxy_Function fun(const boost::function &f) - { - return Proxy_Function(new dispatch::Proxy_Function_Impl(f)); - } - /// \brief Creates a new Proxy_Function object from a free function, member function or data member /// \param[in] t Function / member to expose /// @@ -105,9 +96,28 @@ namespace chaiscript template Proxy_Function fun(T t) { - return dispatch::detail::Fun_Helper::value, boost::function_types::is_member_function_pointer::value>::go(t); + return dispatch::detail::Fun_Helper::value>::go(t); } + + /// \brief Creates a new Proxy_Function object from a std::function object + /// \param[in] f std::function to expose to ChaiScript + /// + /// \b Example: + /// \code + /// std::function f = get_some_function(); + /// chaiscript::ChaiScript chai; + /// chai.add(fun(f), "some_function"); + /// \endcode + /// + /// \sa \ref addingfunctions + template + Proxy_Function fun(const std::function &f) + { + return Proxy_Function(new dispatch::Proxy_Function_Impl(f)); + } + + /// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it /// \param[in] t Function / member to expose /// \param[in] q Value to bind to first parameter @@ -122,7 +132,7 @@ namespace chaiscript /// MyClass obj; /// chaiscript::ChaiScript chai; /// // Add function taking only one argument, an int, and permanently bound to "obj" - /// chai.add(fun(&MyClass::memberfunction, boost::ref(obj)), "memberfunction"); + /// chai.add(fun(&MyClass::memberfunction, std::ref(obj)), "memberfunction"); /// \endcode /// /// \sa \ref addingfunctions @@ -148,7 +158,7 @@ namespace chaiscript /// chaiscript::ChaiScript chai; /// // Add function taking only no arguments, and permanently bound to "obj" and "1" /// // memberfunction() will be equivalent to obj.memberfunction(1) - /// chai.add(fun(&MyClass::memberfunction, boost::ref(obj), 1), "memberfunction"); + /// chai.add(fun(&MyClass::memberfunction, std::ref(obj), 1), "memberfunction"); /// \endcode /// /// \sa \ref addingfunctions diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index b03194be..fe4c7421 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -9,17 +9,8 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include namespace chaiscript { @@ -29,7 +20,7 @@ namespace chaiscript template struct Bare_Type { - typedef typename boost::remove_const::type>::type>::type type; + typedef typename std::remove_cv::type>::type>::type type; }; } @@ -37,7 +28,7 @@ namespace chaiscript class Type_Info { public: - Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, + CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bareti) : m_type_info(t_ti), m_bare_type_info(t_bareti), m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer), @@ -153,72 +144,72 @@ namespace chaiscript { typedef T type; - static Type_Info get() + CHAISCRIPT_CONSTEXPR static Type_Info get() { - return Type_Info(boost::is_const::type>::type>::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - boost::is_arithmetic::value && !boost::is_same::type, bool>::value, + return Type_Info(std::is_const::type>::type>::value, std::is_reference::value, std::is_pointer::value, + std::is_void::value, + std::is_arithmetic::value && !std::is_same::type, bool>::value, &typeid(T), &typeid(typename Bare_Type::type)); } }; template - struct Get_Type_Info > + struct Get_Type_Info > { typedef T type; - static Type_Info get() + CHAISCRIPT_CONSTEXPR static Type_Info get() { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - boost::is_arithmetic::value && !boost::is_same::type, bool>::value, - &typeid(boost::shared_ptr ), + return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, + std::is_void::value, + std::is_arithmetic::value && !std::is_same::type, bool>::value, + &typeid(std::shared_ptr ), &typeid(typename Bare_Type::type)); } }; template - struct Get_Type_Info &> + struct Get_Type_Info &> { typedef T type; - static Type_Info get() + CHAISCRIPT_CONSTEXPR static Type_Info get() { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - boost::is_arithmetic::value && !boost::is_same::type, bool>::value, - &typeid(const boost::shared_ptr &), + return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, + std::is_void::value, + std::is_arithmetic::value && !std::is_same::type, bool>::value, + &typeid(const std::shared_ptr &), &typeid(typename Bare_Type::type)); } }; template - struct Get_Type_Info > + struct Get_Type_Info > { typedef T type; - static Type_Info get() + CHAISCRIPT_CONSTEXPR static Type_Info get() { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - boost::is_arithmetic::value && !boost::is_same::type, bool>::value, - &typeid(boost::reference_wrapper ), + return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, + std::is_void::value, + std::is_arithmetic::value && !std::is_same::type, bool>::value, + &typeid(std::reference_wrapper ), &typeid(typename Bare_Type::type)); } }; template - struct Get_Type_Info &> + struct Get_Type_Info &> { typedef T type; - static Type_Info get() + CHAISCRIPT_CONSTEXPR static Type_Info get() { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - boost::is_arithmetic::value && !boost::is_same::type, bool>::value, - &typeid(const boost::reference_wrapper &), + return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, + std::is_void::value, + std::is_arithmetic::value && !std::is_same::type, bool>::value, + &typeid(const std::reference_wrapper &), &typeid(typename Bare_Type::type)); } }; @@ -240,7 +231,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(i); /// \endcode template - Type_Info user_type(const T &/*t*/) + CHAISCRIPT_CONSTEXPR Type_Info user_type(const T &/*t*/) { return detail::Get_Type_Info::get(); } @@ -255,7 +246,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(); /// \endcode template - Type_Info user_type() + CHAISCRIPT_CONSTEXPR Type_Info user_type() { return detail::Get_Type_Info::get(); } diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index d16a367d..fde79e6b 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -7,8 +7,7 @@ #ifndef CHAISCRIPT_ALGEBRAIC_HPP_ #define CHAISCRIPT_ALGEBRAIC_HPP_ -#include -#include +#include "../dispatchkit/dispatchkit.hpp" namespace chaiscript { diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 2f7e0c1a..05729060 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -7,8 +7,8 @@ #ifndef CHAISCRIPT_COMMON_HPP_ #define CHAISCRIPT_COMMON_HPP_ -#include -#include +#include +#include "../dispatchkit/dispatchkit.hpp" namespace chaiscript { @@ -23,7 +23,7 @@ namespace chaiscript Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, - Logical_And, Logical_Or, Switch, Case, Default, Ternary_Cond, Noop + Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop }; }; @@ -36,7 +36,7 @@ namespace chaiscript "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", - "Logical_And", "Logical_Or", "Switch", "Case", "Default", "Ternary Condition", "Noop"}; + "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop"}; return ast_node_types[ast_node_type]; } @@ -54,7 +54,7 @@ namespace chaiscript }; /// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree - typedef boost::shared_ptr AST_NodePtr; + typedef std::shared_ptr AST_NodePtr; /// \brief Classes which may be thrown during error cases when ChaiScript is executing. @@ -73,26 +73,26 @@ namespace chaiscript eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname, const std::vector &t_parameters, const std::vector &t_functions, bool t_dot_notation, - const chaiscript::detail::Dispatch_Engine &t_ss) : + const chaiscript::detail::Dispatch_Engine &t_ss) CHAISCRIPT_NOEXCEPT : std::runtime_error(format(t_why, t_where, t_fname, t_parameters, t_dot_notation, t_ss)), - reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname), detail(format_detail(t_functions, t_dot_notation, t_ss)) + reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname), detail(format_detail(t_functions, t_dot_notation, t_ss)) {} eval_error(const std::string &t_why, const std::vector &t_parameters, const std::vector &t_functions, bool t_dot_notation, - const chaiscript::detail::Dispatch_Engine &t_ss) : + const chaiscript::detail::Dispatch_Engine &t_ss) CHAISCRIPT_NOEXCEPT : std::runtime_error(format(t_why, t_parameters, t_dot_notation, t_ss)), reason(t_why), detail(format_detail(t_functions, t_dot_notation, t_ss)) {} - eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) : + eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) CHAISCRIPT_NOEXCEPT : std::runtime_error(format(t_why, t_where, t_fname)), reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname) {} - eval_error(const std::string &t_why) throw() + eval_error(const std::string &t_why) CHAISCRIPT_NOEXCEPT : std::runtime_error("Error: \"" + t_why + "\" "), reason(t_why) {} @@ -119,7 +119,7 @@ namespace chaiscript return ss.str(); } - virtual ~eval_error() throw() {} + virtual ~eval_error() CHAISCRIPT_NOEXCEPT {} private: @@ -203,8 +203,8 @@ namespace chaiscript } - boost::shared_ptr dynfun - = boost::dynamic_pointer_cast(t_func); + std::shared_ptr dynfun + = std::dynamic_pointer_cast(t_func); if (dynfun) { @@ -212,8 +212,8 @@ namespace chaiscript if (f) { - boost::shared_ptr dynfunguard - = boost::dynamic_pointer_cast(f); + std::shared_ptr dynfunguard + = std::dynamic_pointer_cast(f); if (dynfunguard) { retval += " : " + format_guard(dynfunguard->get_parse_tree()); @@ -378,22 +378,22 @@ namespace chaiscript /// Errors generated when loading a file struct file_not_found_error : public std::runtime_error { - file_not_found_error(const std::string &t_filename) throw() + file_not_found_error(const std::string &t_filename) CHAISCRIPT_NOEXCEPT : std::runtime_error("File Not Found: " + t_filename) { } - virtual ~file_not_found_error() throw() {} + virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT {} }; } /// \brief Struct that doubles as both a parser ast_node and an AST node. - struct AST_Node : boost::enable_shared_from_this { + struct AST_Node : std::enable_shared_from_this { public: const std::string text; - const int identifier; - boost::shared_ptr filename; + const int identifier; //< \todo shouldn't this be a strongly typed enum value? + std::shared_ptr filename; File_Position start, end; std::vector children; AST_NodePtr annotation; @@ -446,14 +446,14 @@ namespace chaiscript } protected: - AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr &t_fname, + AST_Node(const std::string &t_ast_node_text, int t_id, const std::shared_ptr &t_fname, int t_start_line, int t_start_col, int t_end_line, int t_end_col) : text(t_ast_node_text), identifier(t_id), filename(t_fname), start(t_start_line, t_start_col), end(t_end_line, t_end_col) { } - AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr &t_fname) : + AST_Node(const std::string &t_ast_node_text, int t_id, const std::shared_ptr &t_fname) : text(t_ast_node_text), identifier(t_id), filename(t_fname) {} virtual ~AST_Node() {} diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 0b74d7b8..58d48f0a 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -10,12 +10,17 @@ #include #include +#include "../chaiscript_defines.hpp" #include "chaiscript_common.hpp" +#if defined(__linux__) || defined(__unix__) || defined(__APPLE__) +#include +#endif + #ifdef _POSIX_VERSION #include #else -#ifdef BOOST_WINDOWS +#ifdef CHAISCRIPT_WINDOWS #define VC_EXTRA_LEAN #define WIN32_LEAN_AND_MEAN #include @@ -23,7 +28,7 @@ #endif -#include "chaiscript_prelude.hpp" +#include "chaiscript_prelude.chai" #include "chaiscript_parser.hpp" #include "../dispatchkit/exception_specification.hpp" @@ -34,12 +39,12 @@ namespace chaiscript /// \brief Thrown if an error occurs while attempting to load a binary module struct load_module_error : std::runtime_error { - load_module_error(const std::string &t_reason) throw() + load_module_error(const std::string &t_reason) CHAISCRIPT_NOEXCEPT : std::runtime_error(t_reason) { } - virtual ~load_module_error() throw() + virtual ~load_module_error() CHAISCRIPT_NOEXCEPT { } }; @@ -57,7 +62,7 @@ namespace chaiscript { if (!m_data) { - throw exception::load_module_error(dlerror()); + throw chaiscript::exception::load_module_error(dlerror()); } } @@ -80,7 +85,7 @@ namespace chaiscript { if (!m_symbol) { - throw exception::load_module_error(dlerror()); + throw chaiscript::exception::load_module_error(dlerror()); } } @@ -152,9 +157,9 @@ namespace chaiscript typedef LPSTR StringType; std::string retval = "Unknown Error"; #endif - StringType lpMsgBuf = 0; + StringType lpMsgBuf = nullptr; - FormatMessage( + if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -162,14 +167,12 @@ namespace chaiscript t_err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (StringType)&lpMsgBuf, - 0, NULL ); - - if (lpMsgBuf) + 0, NULL ) != 0 && lpMsgBuf) { retval = lpMsgBuf; + LocalFree(lpMsgBuf); } - LocalFree(lpMsgBuf); return tostring(retval); } @@ -180,7 +183,7 @@ namespace chaiscript { if (!m_data) { - throw exception::load_module_error(GetErrorMessage(GetLastError())); + throw chaiscript::exception::load_module_error(GetErrorMessage(GetLastError())); } } @@ -200,7 +203,7 @@ namespace chaiscript { if (!m_symbol) { - throw exception::load_module_error(GetErrorMessage(GetLastError())); + throw chaiscript::exception::load_module_error(GetErrorMessage(GetLastError())); } } @@ -223,7 +226,7 @@ namespace chaiscript { Loadable_Module(const std::string &, const std::string &) { - throw exception::load_module_error("Loadable module support not available for your platform"); + throw chaiscript::exception::load_module_error("Loadable module support not available for your platform"); } ModulePtr m_moduleptr; @@ -231,7 +234,7 @@ namespace chaiscript #endif #endif - typedef boost::shared_ptr Loadable_Module_Ptr; + typedef std::shared_ptr Loadable_Module_Ptr; } @@ -291,18 +294,13 @@ namespace chaiscript } } - - /// Returns the current evaluation m_engine chaiscript::detail::Dispatch_Engine &get_eval_engine() { return m_engine; } - /// Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude. - void build_eval_system() { - using namespace bootstrap; - m_engine.add_reserved_word("auto"); + void build_eval_system(const ModulePtr &t_lib) { m_engine.add_reserved_word("def"); m_engine.add_reserved_word("fun"); m_engine.add_reserved_word("while"); @@ -312,50 +310,44 @@ namespace chaiscript m_engine.add_reserved_word("&&"); m_engine.add_reserved_word("||"); m_engine.add_reserved_word(","); - m_engine.add_reserved_word(":="); - m_engine.add_reserved_word("var"); + m_engine.add_reserved_word("auto"); m_engine.add_reserved_word("return"); m_engine.add_reserved_word("break"); m_engine.add_reserved_word("true"); m_engine.add_reserved_word("false"); m_engine.add_reserved_word("_"); - add(Bootstrap::bootstrap()); + if (t_lib) + { + add(t_lib); + } - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, boost::ref(m_engine)), "dump_system"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, boost::ref(m_engine)), "dump_object"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, boost::ref(m_engine)), "is_type"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, boost::ref(m_engine)), "type_name"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, boost::ref(m_engine)), "function_exists"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, boost::ref(m_engine)), "get_functions"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, boost::ref(m_engine)), "get_objects"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, std::ref(m_engine)), "dump_system"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, std::ref(m_engine)), "dump_object"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, std::ref(m_engine)), "is_type"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, std::ref(m_engine)), "type_name"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, std::ref(m_engine)), "function_exists"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, std::ref(m_engine)), "get_functions"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, std::ref(m_engine)), "get_objects"); - - m_engine.add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&chaiscript::detail::Dispatch_Engine::call_exists, boost::ref(m_engine), _1))), + m_engine.add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(std::bind(&chaiscript::detail::Dispatch_Engine::call_exists, std::ref(m_engine), std::placeholders::_1))), "call_exists"); - m_engine.add(fun &)>(boost::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), _1, _2, boost::ref(m_engine.conversions()))), "call"); + m_engine.add(fun &)>(std::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), std::placeholders::_1, std::placeholders::_2, std::ref(m_engine.conversions()))), "call"); + + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name"); - - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, boost::ref(m_engine)), "name"); - - - typedef void (ChaiScript::*load_mod_1)(const std::string&); + typedef std::string (ChaiScript::*load_mod_1)(const std::string&); typedef void (ChaiScript::*load_mod_2)(const std::string&, const std::string&); m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); - add(standard_library::vector_type >("Vector")); - add(standard_library::string_type("string")); - add(standard_library::map_type >("Map")); - add(standard_library::pair_type >("Pair")); - m_engine.add(fun(&ChaiScript::use, this), "use"); m_engine.add(fun(&ChaiScript::internal_eval, this), "eval"); m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval"); - do_eval(chaiscript_prelude, "standard prelude"); + do_eval(ChaiScript_Prelude::chaiscript_prelude(), "standard prelude"); } @@ -364,7 +356,7 @@ namespace chaiscript std::ifstream infile(t_filename.c_str(), std::ios::in | std::ios::ate | std::ios::binary ); if (!infile.is_open()) { - throw exception::file_not_found_error(t_filename); + throw chaiscript::exception::file_not_found_error(t_filename); } std::streampos size = infile.tellg(); @@ -384,9 +376,11 @@ namespace chaiscript public: /// \brief Constructor for ChaiScript + /// \param[in] t_lib Standard library to apply to this ChaiScript instance /// \param[in] t_modulepaths Vector of paths to search when attempting to load a binary module /// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file - ChaiScript(const std::vector &t_modulepaths = std::vector(), + ChaiScript(const ModulePtr &t_lib, + const std::vector &t_modulepaths = std::vector(), const std::vector &t_usepaths = std::vector()) : m_modulepaths(t_modulepaths), m_usepaths(t_usepaths) { @@ -400,9 +394,74 @@ namespace chaiscript m_usepaths.push_back(""); } - build_eval_system(); + build_eval_system(t_lib); } + /// \brief Constructor for ChaiScript. + /// + /// This version of the ChaiScript constructor attempts to find the stdlib module to load + /// at runtime generates an error if it cannot be found. + /// + /// \param[in] t_modulepaths Vector of paths to search when attempting to load a binary module + /// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file + ChaiScript( const std::vector &t_modulepaths = std::vector(), + const std::vector &t_usepaths = std::vector()) + : m_modulepaths(t_modulepaths), m_usepaths(t_usepaths) + { + if (m_modulepaths.empty()) + { + m_modulepaths.push_back(""); + } + + if (m_usepaths.empty()) + { + m_usepaths.push_back(""); + } + + +#ifdef _POSIX_VERSION + // If on Unix, add the path of the current executable to the module search path + // as windows would do + + union cast_union + { + void (ChaiScript::*in_ptr)(const std::string&); + void *out_ptr; + }; + + Dl_info rInfo; + memset( &rInfo, 0, sizeof(rInfo) ); + cast_union u; + u.in_ptr = &ChaiScript::use; + if ( dladdr((void*)(u.out_ptr), &rInfo) && rInfo.dli_fname ) { + std::string dllpath(rInfo.dli_fname); + size_t lastslash = dllpath.rfind('/'); + if (lastslash != std::string::npos) + { + dllpath.erase(lastslash); + } + + // Let's see if this is a link that we should expand + std::vector buf(2048); + size_t pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size()); + if (pathlen > 0 && pathlen < buf.size()) + { + dllpath = std::string(&buf.front(), pathlen); + } + + m_modulepaths.insert(m_modulepaths.begin(), dllpath+"/"); + } +#endif + + + // attempt to load the stdlib + load_module("chaiscript_stdlib"); + + build_eval_system(ModulePtr()); + } + + + /// \brief Loads and parses a file. If the file is already, it is not reloaded /// The use paths specified at ChaiScript construction time are searched for the /// requested file. @@ -441,7 +500,7 @@ namespace chaiscript /// \brief Adds a constant object that is available in all contexts and to all threads /// \param[in] t_bv Boxed_Value to add as a global /// \param[in] t_name Name of the value to add - /// \throw exception::global_non_const If t_bv is not a constant object + /// \throw chaiscript::exception::global_non_const If t_bv is not a constant object /// \sa Boxed_Value::is_const ChaiScript &add_global_const(const Boxed_Value &t_bv, const std::string &t_name) { @@ -592,8 +651,8 @@ namespace chaiscript /// If no file can be found matching the search criteria and containing the appropriate entry point /// (the symbol mentioned above), an exception is thrown. /// - /// \throw exception::load_module_error In the event that no matching module can be found. - void load_module(const std::string &t_module_name) + /// \throw chaiscript::exception::load_module_error In the event that no matching module can be found. + std::string load_module(const std::string &t_module_name) { std::vector errors; @@ -606,23 +665,25 @@ namespace chaiscript postfixes.push_back(".so"); postfixes.push_back(""); - for (size_t i = 0; i < m_modulepaths.size(); ++i) + for (size_t i = 0; i < m_modulepaths.size(); ++i) + { + for (size_t j = 0; j < prefixes.size(); ++j) { - for (size_t j = 0; j < prefixes.size(); ++j) - { - for (size_t k = 0; k < postfixes.size(); ++k) - { - try { - std::string name = m_modulepaths[i] + prefixes[j] + t_module_name + postfixes[k]; - load_module(t_module_name, name); - return; - } catch (const exception::load_module_error &e) { - errors.push_back(e); - // Try next set - } - } + for (size_t k = 0; k < postfixes.size(); ++k) + { + try { + std::string name = m_modulepaths[i] + prefixes[j] + t_module_name + postfixes[k]; + // std::cerr << "trying location: " << name << std::endl; + load_module(t_module_name, name); + return name; + } catch (const chaiscript::exception::load_module_error &e) { + // std::cerr << "error: " << e.what() << std::endl; + errors.push_back(e); + // Try next set } + } } + } std::string errstring; @@ -638,7 +699,7 @@ namespace chaiscript errstring += itr->what(); } - throw exception::load_module_error("Unable to find module: " + t_module_name + " Errors: " + errstring); + throw chaiscript::exception::load_module_error("Unable to find module: " + t_module_name + " Errors: " + errstring); } /// \brief Load a binary module from a dynamic library. Works on platforms that support @@ -672,7 +733,7 @@ namespace chaiscript /// /// \return result of the script execution /// - /// \throw exception::eval_error In the case that evaluation fails. + /// \throw chaiscript::exception::eval_error In the case that evaluation fails. Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler = Exception_Handler()) { try { @@ -695,8 +756,8 @@ namespace chaiscript /// /// \return result of the script execution /// - /// \throw exception::eval_error In the case that evaluation fails. - /// \throw exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted + /// \throw chaiscript::exception::eval_error In the case that evaluation fails. + /// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted /// to the requested type. template T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__") @@ -745,7 +806,7 @@ namespace chaiscript /// \param[in] t_filename File to load and parse. /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions /// \return result of the script execution - /// \throw exception::eval_error In the case that evaluation fails. + /// \throw chaiscript::exception::eval_error In the case that evaluation fails. Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { try { return do_eval(load_file(t_filename), t_filename); @@ -762,8 +823,8 @@ namespace chaiscript /// \param[in] t_filename File to load and parse. /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions /// \return result of the script execution - /// \throw exception::eval_error In the case that evaluation fails. - /// \throw exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted + /// \throw chaiscript::exception::eval_error In the case that evaluation fails. + /// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted /// to the requested type. template T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 8fb9809c..076c7dea 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -9,7 +9,8 @@ #include -#include +#include "chaiscript_common.hpp" +#include "../dispatchkit/register_function.hpp" namespace chaiscript { @@ -38,7 +39,7 @@ namespace chaiscript struct Binary_Operator_AST_Node : public AST_Node { public: - Binary_Operator_AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Binary_Operator_AST_Node(const std::string &t_ast_node_text, int t_id, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } @@ -92,7 +93,7 @@ namespace chaiscript struct Error_AST_Node : public AST_Node { public: - Error_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Error_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Error, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Error_AST_Node() {} @@ -100,10 +101,10 @@ namespace chaiscript struct Int_AST_Node : public AST_Node { public: - Int_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Int_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Int, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(const_var(int(atoi(t_ast_node_text.c_str())))) { } - Int_AST_Node(const std::string &t_ast_node_text, const Boxed_Value &t_bv, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Int_AST_Node(const std::string &t_ast_node_text, const Boxed_Value &t_bv, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Int, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(t_bv) { } virtual ~Int_AST_Node() {} @@ -118,10 +119,10 @@ namespace chaiscript struct Float_AST_Node : public AST_Node { public: - Float_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Float_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Float, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(const_var(double(atof(t_ast_node_text.c_str())))) { } - Float_AST_Node(const std::string &t_ast_node_text, const Boxed_Value &t_bv, const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Float_AST_Node(const std::string &t_ast_node_text, const Boxed_Value &t_bv, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Float, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(t_bv) { } virtual ~Float_AST_Node() {} @@ -136,7 +137,7 @@ namespace chaiscript struct Id_AST_Node : public AST_Node { public: - Id_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Id_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(get_value(t_ast_node_text)) { } @@ -180,21 +181,21 @@ namespace chaiscript struct Char_AST_Node : public AST_Node { public: - Char_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Char_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Char, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Char_AST_Node() {} }; struct Str_AST_Node : public AST_Node { public: - Str_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Str_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Str, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Str_AST_Node() {} }; struct Eol_AST_Node : public AST_Node { public: - Eol_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Eol_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Eol, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Eol_AST_Node() {} @@ -206,26 +207,26 @@ namespace chaiscript struct Fun_Call_AST_Node : public AST_Node { public: - Fun_Call_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Fun_Call_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Fun_Call, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Fun_Call_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - dispatch::Param_List_Builder plb; + std::vector params; if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { for (size_t i = 0; i < this->children[1]->children.size(); ++i) { - plb << this->children[1]->children[i]->eval(t_ss); + params.push_back(this->children[1]->children[i]->eval(t_ss)); } } - fpp.save_params(plb.objects); + fpp.save_params(params); + Boxed_Value fn = this->children[0]->eval(t_ss); - try { chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); - const Boxed_Value &retval = (*t_ss.boxed_cast(fn))(plb, t_ss.conversions()); + const Boxed_Value &retval = (*t_ss.boxed_cast(fn))(params, t_ss.conversions()); return retval; } catch(const exception::dispatch_error &e){ @@ -237,7 +238,7 @@ namespace chaiscript // handle the case where there is only 1 function to try to call and dispatch fails on it std::vector funcs; funcs.push_back(f); - throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", plb.objects, funcs, false, t_ss); + throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, funcs, false, t_ss); } catch (const exception::bad_boxed_cast &) { throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function."); } @@ -275,15 +276,15 @@ namespace chaiscript struct Inplace_Fun_Call_AST_Node : public AST_Node { public: - Inplace_Fun_Call_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Inplace_Fun_Call_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Inplace_Fun_Call, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inplace_Fun_Call_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ - dispatch::Param_List_Builder plb; + std::vector params; if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { for (size_t i = 0; i < this->children[1]->children.size(); ++i) { - plb << this->children[1]->children[i]->eval(t_ss); + params.push_back(this->children[1]->children[i]->eval(t_ss)); } } @@ -297,7 +298,7 @@ namespace chaiscript } catch (const exception::bad_boxed_cast &) { throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function."); } - return (*fn)(plb, t_ss.conversions()); + return (*fn)(params, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, t_ss); @@ -306,7 +307,7 @@ namespace chaiscript // handle the case where there is only 1 function to try to call and dispatch fails on it std::vector funcs; funcs.push_back(fn); - throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", plb.objects, funcs, false, t_ss); + throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, funcs, false, t_ss); } catch(const exception::arity_error &e){ throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'"); @@ -340,7 +341,7 @@ namespace chaiscript struct Arg_List_AST_Node : public AST_Node { public: - Arg_List_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Arg_List_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Arg_List, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Arg_List_AST_Node() {} @@ -362,14 +363,14 @@ namespace chaiscript struct Variable_AST_Node : public AST_Node { public: - Variable_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Variable_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Variable, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Variable_AST_Node() {} }; struct Equation_AST_Node : public AST_Node { public: - Equation_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Equation_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Equation, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) {} @@ -394,7 +395,17 @@ namespace chaiscript } else if (this->children[1]->text == "=") { try { if (lhs.is_undef()) { - retval = t_ss.call_function("clone", retval); + if (!this->children.empty() && + !this->children[0]->children.empty() + && this->children[0]->children[0]->identifier == AST_Node_Type::Reference) + { + /// \todo This does not handle the case of an unassigned reference variable + /// being assigned outside of its declaration + lhs.assign(retval); + return retval; + } else { + retval = t_ss.call_function("clone", retval); + } } try { @@ -409,7 +420,7 @@ namespace chaiscript } } else if (this->children[1]->text == ":=") { - if (lhs.is_undef() || type_match(lhs, retval)) { + if (lhs.is_undef() || Boxed_Value::type_match(lhs, retval)) { lhs.assign(retval); } else { throw exception::eval_error("Mismatched types in equation"); @@ -429,19 +440,27 @@ namespace chaiscript struct Var_Decl_AST_Node : public AST_Node { public: - Var_Decl_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Var_Decl_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Var_Decl, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Var_Decl_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ - try { - t_ss.add_object(this->children[0]->text, Boxed_Value()); + if (this->children[0]->identifier == AST_Node_Type::Reference) + { + return this->children[0]->eval(t_ss); + } else { + std::string idname = this->children[0]->text; + + try { + t_ss.add_object(idname, Boxed_Value()); + } + catch (const exception::reserved_word_error &) { + throw exception::eval_error("Reserved word used as variable '" + idname + "'"); + } catch (const exception::name_conflict_error &e) { + throw exception::eval_error("Variable redefined '" + e.name() + "'"); + } + return t_ss.get_object(idname); } - catch (const exception::reserved_word_error &) { - throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'"); - } catch (const exception::name_conflict_error &e) { - throw exception::eval_error("Variable redefined '" + e.name() + "'"); - } - return t_ss.get_object(this->children[0]->text); + } virtual std::string pretty_print() const @@ -453,7 +472,7 @@ namespace chaiscript struct Comparison_AST_Node : public Binary_Operator_AST_Node { public: - Comparison_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Comparison_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Comparison, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Comparison_AST_Node() {} }; @@ -461,7 +480,7 @@ namespace chaiscript struct Addition_AST_Node : public Binary_Operator_AST_Node { public: Addition_AST_Node(const std::string &t_ast_node_text = "+", - const boost::shared_ptr &t_fname=boost::shared_ptr(), + const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Addition, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Addition_AST_Node() {} @@ -473,7 +492,7 @@ namespace chaiscript struct Subtraction_AST_Node : public Binary_Operator_AST_Node { public: Subtraction_AST_Node(const std::string &t_ast_node_text = "-", - const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, + const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Subtraction, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Subtraction_AST_Node() {} @@ -485,7 +504,7 @@ namespace chaiscript struct Multiplication_AST_Node : public Binary_Operator_AST_Node { public: Multiplication_AST_Node(const std::string &t_ast_node_text = "*", - const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, + const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Multiplication, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Multiplication_AST_Node() {} @@ -497,7 +516,7 @@ namespace chaiscript struct Division_AST_Node : public Binary_Operator_AST_Node { public: Division_AST_Node(const std::string &t_ast_node_text = "/", - const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, + const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Division, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Division_AST_Node() {} @@ -509,7 +528,7 @@ namespace chaiscript struct Modulus_AST_Node : public Binary_Operator_AST_Node { public: Modulus_AST_Node(const std::string &t_ast_node_text = "%", - const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, + const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Modulus, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Modulus_AST_Node() {} @@ -520,7 +539,7 @@ namespace chaiscript struct Array_Call_AST_Node : public AST_Node { public: - Array_Call_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Array_Call_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Array_Call, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Array_Call_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -568,7 +587,7 @@ namespace chaiscript struct Dot_Access_AST_Node : public AST_Node { public: - Dot_Access_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Dot_Access_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Dot_Access, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Dot_Access_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -577,16 +596,16 @@ namespace chaiscript if (this->children.size() > 1) { for (size_t i = 2; i < this->children.size(); i+=2) { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - dispatch::Param_List_Builder plb; - plb << retval; + std::vector params; + params.push_back(retval); if (this->children[i]->children.size() > 1) { for (size_t j = 0; j < this->children[i]->children[1]->children.size(); ++j) { - plb << this->children[i]->children[1]->children[j]->eval(t_ss); + params.push_back(this->children[i]->children[1]->children[j]->eval(t_ss)); } } - fpp.save_params(plb.objects); + fpp.save_params(params); std::string fun_name; if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) { @@ -598,7 +617,7 @@ namespace chaiscript try { chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); - retval = t_ss.call_function(fun_name, plb); + retval = t_ss.call_function(fun_name, params); } catch(const exception::dispatch_error &e){ if (e.functions.empty()) @@ -635,7 +654,7 @@ namespace chaiscript struct Quoted_String_AST_Node : public AST_Node { public: - Quoted_String_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Quoted_String_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Quoted_String, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(const_var(t_ast_node_text)) { } virtual ~Quoted_String_AST_Node() {} @@ -655,7 +674,7 @@ namespace chaiscript struct Single_Quoted_String_AST_Node : public AST_Node { public: - Single_Quoted_String_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Single_Quoted_String_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Single_Quoted_String, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(const_var(char(t_ast_node_text.at(0)))) { } virtual ~Single_Quoted_String_AST_Node() {} @@ -674,8 +693,8 @@ namespace chaiscript struct Lambda_AST_Node : public AST_Node { public: - Lambda_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : - AST_Node(t_ast_node_text, AST_Node_Type::Lambda, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } + Lambda_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Lambda, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Lambda_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ std::vector t_param_names; @@ -694,7 +713,7 @@ namespace chaiscript } return Boxed_Value(Proxy_Function(new dispatch::Dynamic_Proxy_Function - (boost::bind(chaiscript::eval::detail::eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), + (std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), this->children.back(), t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back()))); } @@ -702,7 +721,7 @@ namespace chaiscript struct Block_AST_Node : public AST_Node { public: - Block_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Block_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Block, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Block_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -731,7 +750,7 @@ namespace chaiscript struct Def_AST_Node : public AST_Node { public: - Def_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Def_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Def, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Def_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -758,21 +777,21 @@ namespace chaiscript } } - boost::shared_ptr guard; + std::shared_ptr guard; if (guardnode) { - guard = boost::shared_ptr - (new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function, - boost::ref(t_ss), guardnode, - t_param_names, _1), static_cast(numparams), guardnode)); + guard = std::shared_ptr + (new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function, + std::ref(t_ss), guardnode, + t_param_names, std::placeholders::_1), static_cast(numparams), guardnode)); } try { const std::string & l_function_name = this->children[0]->text; const std::string & l_annotation = this->annotation?this->annotation->text:""; t_ss.add(Proxy_Function - (new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function, - boost::ref(t_ss), this->children.back(), - t_param_names, _1), static_cast(numparams), this->children.back(), + (new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function, + std::ref(t_ss), this->children.back(), + t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), l_annotation, guard)), l_function_name); } catch (const exception::reserved_word_error &e) { @@ -787,7 +806,7 @@ namespace chaiscript struct While_AST_Node : public AST_Node { public: - While_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + While_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::While, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~While_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) { @@ -816,7 +835,7 @@ namespace chaiscript struct Ternary_Cond_AST_Node : public AST_Node { public: - Ternary_Cond_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Ternary_Cond_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::If, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Ternary_Cond_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -839,7 +858,7 @@ namespace chaiscript struct If_AST_Node : public AST_Node { public: - If_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + If_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::If, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~If_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -884,7 +903,7 @@ namespace chaiscript struct For_AST_Node : public AST_Node { public: - For_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + For_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::For, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~For_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -923,7 +942,7 @@ namespace chaiscript struct Switch_AST_Node : public AST_Node { public: - Switch_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Switch_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Switch, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Switch_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) { @@ -966,7 +985,7 @@ namespace chaiscript struct Case_AST_Node : public AST_Node { public: - Case_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Case_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Case, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Case_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) { @@ -980,7 +999,7 @@ namespace chaiscript struct Default_AST_Node : public AST_Node { public: - Default_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Default_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Default, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Default_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) { @@ -991,10 +1010,11 @@ namespace chaiscript return Boxed_Value(); } }; - + + struct Inline_Array_AST_Node : public AST_Node { public: - Inline_Array_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Inline_Array_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Inline_Array, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inline_Array_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1022,7 +1042,7 @@ namespace chaiscript struct Inline_Map_AST_Node : public AST_Node { public: - Inline_Map_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Inline_Map_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Inline_Map, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inline_Map_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1044,7 +1064,7 @@ namespace chaiscript struct Return_AST_Node : public AST_Node { public: - Return_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Return_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Return, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Return_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1060,7 +1080,7 @@ namespace chaiscript struct File_AST_Node : public AST_Node { public: - File_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + File_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::File, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~File_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) { @@ -1075,9 +1095,28 @@ namespace chaiscript } }; + struct Reference_AST_Node : public AST_Node { + public: + Reference_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Reference, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) + { } + + virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ + try { + t_ss.add_object(this->children[0]->text, Boxed_Value()); + } + catch (const exception::reserved_word_error &) { + throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'"); + } + return t_ss.get_object(this->children[0]->text); + } + + virtual ~Reference_AST_Node() {} + }; + struct Prefix_AST_Node : public AST_Node { public: - Prefix_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Prefix_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Prefix, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } @@ -1108,7 +1147,7 @@ namespace chaiscript struct Break_AST_Node : public AST_Node { public: - Break_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Break_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Break, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Break_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){ @@ -1118,7 +1157,7 @@ namespace chaiscript struct Continue_AST_Node : public AST_Node { public: - Continue_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Continue_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Continue, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Continue_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){ @@ -1128,7 +1167,7 @@ namespace chaiscript struct Noop_AST_Node : public AST_Node { public: - Noop_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Noop_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Noop, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(const_var(true)) { } @@ -1145,21 +1184,21 @@ namespace chaiscript struct Map_Pair_AST_Node : public AST_Node { public: - Map_Pair_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Map_Pair_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Map_Pair, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Map_Pair_AST_Node() {} }; struct Value_Range_AST_Node : public AST_Node { public: - Value_Range_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Value_Range_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Value_Range, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Value_Range_AST_Node() {} }; struct Inline_Range_AST_Node : public AST_Node { public: - Inline_Range_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Inline_Range_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Inline_Range, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Inline_Range_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1177,14 +1216,14 @@ namespace chaiscript struct Annotation_AST_Node : public AST_Node { public: - Annotation_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Annotation_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Annotation, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Annotation_AST_Node() {} }; struct Try_AST_Node : public AST_Node { public: - Try_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Try_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Try, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Try_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1202,7 +1241,7 @@ namespace chaiscript throw; } catch (const std::exception &e) { - Boxed_Value except = Boxed_Value(boost::ref(e)); + Boxed_Value except = Boxed_Value(std::ref(e)); size_t end_point = this->children.size(); if (this->children.back()->identifier == AST_Node_Type::Finally) { @@ -1313,21 +1352,21 @@ namespace chaiscript struct Catch_AST_Node : public AST_Node { public: - Catch_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Catch_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Catch, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Catch_AST_Node() {} }; struct Finally_AST_Node : public AST_Node { public: - Finally_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Finally_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Finally, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Finally_AST_Node() {} }; struct Method_AST_Node : public AST_Node { public: - Method_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Method_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Method, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Method_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1357,12 +1396,12 @@ namespace chaiscript size_t numparams = t_param_names.size(); - boost::shared_ptr guard; + std::shared_ptr guard; if (guardnode) { - guard = boost::shared_ptr - (new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function, - boost::ref(t_ss), guardnode, - t_param_names, _1), static_cast(numparams), guardnode)); + guard = std::shared_ptr + (new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function, + std::ref(t_ss), guardnode, + t_param_names, std::placeholders::_1), static_cast(numparams), guardnode)); } try { @@ -1372,26 +1411,30 @@ namespace chaiscript if (function_name == class_name) { t_ss.add(Proxy_Function (new dispatch::detail::Dynamic_Object_Constructor(class_name, Proxy_Function - (new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function, - boost::ref(t_ss), this->children.back(), - t_param_names, _1), static_cast(numparams), this->children.back(), + (new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function, + std::ref(t_ss), this->children.back(), + t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), l_annotation, guard)))), function_name); } else { - boost::optional ti; try { - ti = t_ss.get_type(class_name); + // Do know type name + t_ss.add(Proxy_Function + (new dispatch::detail::Dynamic_Object_Function(class_name, Proxy_Function + (new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function, + std::ref(t_ss), this->children.back(), + t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), + l_annotation, guard)), t_ss.get_type(class_name))), function_name); } catch (const std::range_error &) { - // No biggie, the type name is just not known + // Do not know type name + t_ss.add(Proxy_Function + (new dispatch::detail::Dynamic_Object_Function(class_name, Proxy_Function + (new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function, + std::ref(t_ss), this->children.back(), + t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), + l_annotation, guard)))), function_name); } - t_ss.add(Proxy_Function - (new dispatch::detail::Dynamic_Object_Function(class_name, Proxy_Function - (new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function, - boost::ref(t_ss), this->children.back(), - t_param_names, _1), static_cast(numparams), this->children.back(), - l_annotation, guard)), ti)), function_name); - } } catch (const exception::reserved_word_error &e) { @@ -1406,7 +1449,7 @@ namespace chaiscript struct Attr_Decl_AST_Node : public AST_Node { public: - Attr_Decl_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Attr_Decl_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Attr_Decl, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Attr_Decl_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1415,8 +1458,8 @@ namespace chaiscript t_ss.add(Proxy_Function (new dispatch::detail::Dynamic_Object_Function( this->children[0]->text, - fun(boost::function(boost::bind(&dispatch::Dynamic_Object::get_attr, - _1, + fun(std::function(std::bind(&dispatch::Dynamic_Object::get_attr, + std::placeholders::_1, this->children[1]->text ))) ) @@ -1435,42 +1478,42 @@ namespace chaiscript struct Shift_AST_Node : public Binary_Operator_AST_Node { public: - Shift_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Shift_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Shift, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Shift_AST_Node() {} }; struct Equality_AST_Node : public Binary_Operator_AST_Node { public: - Equality_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Equality_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Equality, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Equality_AST_Node() {} }; struct Bitwise_And_AST_Node : public Binary_Operator_AST_Node { public: - Bitwise_And_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Bitwise_And_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Bitwise_And, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Bitwise_And_AST_Node() {} }; struct Bitwise_Xor_AST_Node : public Binary_Operator_AST_Node { public: - Bitwise_Xor_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Bitwise_Xor_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Bitwise_Xor, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Bitwise_Xor_AST_Node() {} }; struct Bitwise_Or_AST_Node : public Binary_Operator_AST_Node { public: - Bitwise_Or_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Bitwise_Or_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Binary_Operator_AST_Node(t_ast_node_text, AST_Node_Type::Bitwise_Or, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Bitwise_Or_AST_Node() {} }; struct Logical_And_AST_Node : public AST_Node { public: - Logical_And_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Logical_And_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Logical_And, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Logical_And_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ @@ -1504,7 +1547,7 @@ namespace chaiscript struct Logical_Or_AST_Node : public AST_Node { public: - Logical_Or_AST_Node(const std::string &t_ast_node_text = "", const boost::shared_ptr &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Logical_Or_AST_Node(const std::string &t_ast_node_text = "", const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, AST_Node_Type::Logical_Or, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Logical_Or_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 888c982f..0b30cc41 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -10,8 +10,8 @@ #include #include #include +#include -#include "chaiscript_prelude.hpp" #include "chaiscript_common.hpp" namespace chaiscript @@ -47,7 +47,7 @@ namespace chaiscript std::string m_multiline_comment_begin; std::string m_multiline_comment_end; std::string m_singleline_comment; - boost::shared_ptr m_filename; + std::shared_ptr m_filename; std::vector m_match_stack; bool m_alphabet[detail::max_alphabet][detail::lengthof_alphabet]; @@ -317,13 +317,21 @@ namespace chaiscript /** * Skips ChaiScript whitespace, which means space and tab, but not cr/lf + * jespada: Modified SkipWS to skip optionally CR ('\n') */ - bool SkipWS() { + bool SkipWS(bool skip_cr=false) { bool retval = false; while (has_more_input()) { - if ( char_in_alphabet(*m_input_pos,detail::white_alphabet) ) { + if ( char_in_alphabet(*m_input_pos,detail::white_alphabet) || (skip_cr && (*m_input_pos == '\n'))) { + if(*m_input_pos == '\n') { + m_col = 1; + ++m_line; + } + else { + ++m_col; + } ++m_input_pos; - ++m_col; + retval = true; } else if (SkipComment()) { @@ -524,7 +532,7 @@ namespace chaiscript ss >> t_type; std::stringstream testu(t_val.substr(0, i)); - boost::uint64_t u; + uint64_t u; testu >> t_type >> u; bool unsignedrequired = false; @@ -536,28 +544,19 @@ namespace chaiscript long_ = true; } - BOOST_ASSERT(sizeof(long) == sizeof(boost::uint64_t) || sizeof(long) * 2 == sizeof(boost::uint64_t)); + static_assert(sizeof(long) == sizeof(uint64_t) || sizeof(long) * 2 == sizeof(uint64_t), "Unexpected sizing of integer types"); -#ifdef BOOST_MSVC - //Thank you MSVC, yes we know that a constant value is being used in the if - // statment in this compiler / architecture -#pragma warning(push) -#pragma warning(disable : 4127) -#endif - - if ( sizeof(long) < sizeof(boost::uint64_t) && (u >> ((sizeof(boost::uint64_t) - sizeof(long)) * 8)) > 0) + if ((sizeof(long) < sizeof(uint64_t)) + && (u >> ((sizeof(uint64_t) - sizeof(long)) * 8)) > 0) { //requires something bigger than long longlong_ = true; } -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif if (longlong_) { - size = sizeof(boost::int64_t) * 8; + size = sizeof(int64_t) * 8; } else if (long_) { size = sizeof(long) * 8; } @@ -588,7 +587,7 @@ namespace chaiscript { if (longlong_) { - boost::uint64_t val; + uint64_t val; ss >> val; return Boxed_Value(const_var(val)); } else if (long_) { @@ -603,7 +602,7 @@ namespace chaiscript } else { if (longlong_) { - boost::int64_t val; + int64_t val; ss >> val; return Boxed_Value(const_var(val)); } else if (long_) { @@ -641,7 +640,7 @@ namespace chaiscript } if (Binary_()) { std::string match(start, m_input_pos); - boost::int64_t temp_int = 0; + int64_t temp_int = 0; size_t pos = 0, end = match.length(); while ((pos < end) && (pos < (2 + sizeof(int) * 8))) { @@ -1250,6 +1249,8 @@ namespace chaiscript * Reads a comma-separated list of values from input */ bool Arg_List() { + + SkipWS(true); bool retval = false; size_t prev_stack_top = m_match_stack.size(); @@ -1268,6 +1269,8 @@ namespace chaiscript build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), prev_stack_top); } + SkipWS(true); + return retval; } @@ -1276,6 +1279,7 @@ namespace chaiscript */ bool Container_Arg_List() { bool retval = false; + SkipWS(true); size_t prev_stack_top = m_match_stack.size(); @@ -1310,6 +1314,8 @@ namespace chaiscript build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), prev_stack_top); } + SkipWS(true); + return retval; } @@ -1724,7 +1730,7 @@ namespace chaiscript } } - + /** * Reads a curly-brace C-style block from input */ @@ -1868,10 +1874,10 @@ namespace chaiscript size_t prev_stack_top = m_match_stack.size(); - if (Keyword("var")) { + if (Keyword("auto") || Keyword("var")) { retval = true; - if (!Id(true)) { + if (!(Reference() || Id(true))) { throw exception::eval_error("Incomplete variable declaration", File_Position(m_line, m_col), *m_filename); } @@ -1926,6 +1932,7 @@ namespace chaiscript if (Char('[')) { retval = true; Container_Arg_List(); + if (!Char(']')) { throw exception::eval_error("Missing closing square bracket ']' in container initializer", File_Position(m_line, m_col), *m_filename); } @@ -1948,6 +1955,25 @@ namespace chaiscript return retval; } + bool Reference() { + bool retval = false; + + size_t prev_stack_top = m_match_stack.size(); + + if (Symbol("&", false)) { + retval = true; + + if (!Id(true)) { + throw exception::eval_error("Incomplete '&' expression", File_Position(m_line, m_col), *m_filename); + } + + build_match(AST_NodePtr( + new eval::Reference_AST_Node()), prev_stack_top); + } + + return retval; + } + /** * Reads a unary prefixed expression from input */ @@ -2010,6 +2036,15 @@ namespace chaiscript build_match(AST_NodePtr(new eval::Prefix_AST_Node()), prev_stack_top); } + else if (Char('&', true)) { + retval = true; + + if (!Operator(m_operators.size()-1)) { + throw exception::eval_error("Incomplete '~' expression", File_Position(m_line, m_col), *m_filename); + } + + build_match(AST_NodePtr(new eval::Prefix_AST_Node()), prev_stack_top); + } return retval; } @@ -2209,6 +2244,7 @@ namespace chaiscript Symbol("-=", true, true) || Symbol("*=", true, true) || Symbol("/=", true, true) || Symbol("%=", true, true) || Symbol("<<=", true, true) || Symbol(">>=", true, true) || Symbol("&=", true, true) || Symbol("^=", true, true) || Symbol("|=", true, true)) { + SkipWS(true); if (!Equation()) { throw exception::eval_error("Incomplete equation", File_Position(m_line, m_col), *m_filename); } @@ -2304,6 +2340,11 @@ namespace chaiscript retval = true; saw_eol = false; } + else if (Block()) { + has_more = true; + retval = true; + saw_eol = true; + } else if (Equation()) { if (!saw_eol) { throw exception::eval_error("Two expressions missing line separator", File_Position(prev_line, prev_col), *m_filename); @@ -2317,11 +2358,6 @@ namespace chaiscript retval = true; saw_eol = true; } - else if (Block()) { - has_more = true; - retval = true; - saw_eol = true; - } else { has_more = false; } @@ -2338,7 +2374,7 @@ namespace chaiscript m_input_end = t_input.end(); m_line = 1; m_col = 1; - m_filename = boost::shared_ptr(new std::string(t_fname)); + m_filename = std::shared_ptr(new std::string(t_fname)); if ((t_input.size() > 1) && (t_input[0] == '#') && (t_input[1] == '!')) { while ((m_input_pos != m_input_end) && (!Eol())) { diff --git a/include/chaiscript/language/chaiscript_prelude.chai b/include/chaiscript/language/chaiscript_prelude.chai new file mode 100644 index 00000000..7af9a619 --- /dev/null +++ b/include/chaiscript/language/chaiscript_prelude.chai @@ -0,0 +1,531 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// and Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_PRELUDE_HPP_ +#define CHAISCRIPT_PRELUDE_HPP_ + +namespace chaiscript { +struct ChaiScript_Prelude { + static std::string chaiscript_prelude() { return R""( + +def lt(l, r) { + if (call_exists(`<`, l, r)) { + l < r + } else { + type_name(l) < type_name(r) + } +} + + +def gt(l, r) { + if (call_exists(`>`, l, r)) { + l > r + } else { + type_name(l) > type_name(r) + } +} + +def eq(l, r) { + if (call_exists(`==`, l, r)) { + l == r + } else { + false + } +} + +def new(x) { + eval(type_name(x))(); +} + +def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x) +{ + eval(type_name(x))(x); +} + + +# to_string for Pair() +def to_string(x) : call_exists(first, x) && call_exists(second, x) { + "<" + x.first.to_string() + ", " + x.second.to_string() + ">"; +} + +# to_string for containers +def to_string(x) : call_exists(range, x) && !x.is_type("string"){ + "[" + x.join(", ") + "]"; +} + +# Basic to_string function +def to_string(x) { + internal_to_string(x); +} + +# Prints to console with no carriage return +def puts(x) { + print_string(x.to_string()); +} + +# Prints to console with carriage return +def print(x) { + println_string(x.to_string()); +} + +# Returns the maximum value of two numbers +def max(a, b) { + if (a>b) { + a + } else { + b + } +} + +# Returns the minimum value of two numbers +def min(a, b) +{ + if (a 0) && (!r.empty())) { + inserter(r.front()); + r.pop_front(); + --i; + } +} + + +# Returns a new container with the given number of elements taken from the container +def take(container, num) { + auto retval = new(container); + take(container, num, back_inserter(retval)); + retval; +} + + +def take_while(container, f, inserter) : call_exists(range, container) { + auto r = range(container); + while ((!r.empty()) && f(r.front())) { + inserter(r.front()); + r.pop_front(); + } +} + + +# Returns a new container with the given elements match the second value function +def take_while(container, f) { + auto retval = new(container); + take_while(container, f, back_inserter(retval)); + retval; +} + + +def drop(container, num, inserter) : call_exists(range, container) { + auto r = range(container); + auto i = num; + while ((i > 0) && (!r.empty())) { + r.pop_front(); + --i; + } + while (!r.empty()) { + inserter(r.front()); + r.pop_front(); + } +} + + +# Returns a new container with the given number of elements dropped from the given container +def drop(container, num) { + auto retval = new(container); + drop(container, num, back_inserter(retval)); + retval; +} + + +def drop_while(container, f, inserter) : call_exists(range, container) { + auto r = range(container); + while ((!r.empty())&& f(r.front())) { + r.pop_front(); + } + while (!r.empty()) { + inserter(r.front()); + r.pop_front(); + } +} + + +# Returns a new container with the given elements dropped that match the second value function +def drop_while(container, f) { + auto retval = new(container); + drop_while(container, f, back_inserter(retval)); + retval; +} + + +# Applies the second value function to the container. Starts with the first two elements. Expects at least 2 elements. +def reduce(container, func) : container.size() >= 2 && call_exists(range, container) { + auto r = range(container); + auto retval = r.front(); + r.pop_front(); + retval = func(retval, r.front()); + r.pop_front(); + while (!r.empty()) { + retval = func(retval, r.front()); + r.pop_front(); + } + retval; +} + + +# Returns a string of the elements in container delimited by the second value string +def join(container, delim) { + auto retval = ""; + auto range = range(container); + if (!range.empty()) { + retval += to_string(range.front()); + range.pop_front(); + while (!range.empty()) { + retval += delim; + retval += to_string(range.front()); + range.pop_front(); + } + } + retval; +} + + +def filter(container, f, inserter) : call_exists(range, container) { + auto r = range(container); + while (!r.empty()) { + if (f(r.front())) { + inserter(r.front()); + } + r.pop_front(); + } +} + + +# Returns a new Vector which match the second value function +def filter(container, f) { + auto retval = new(container); + filter(container, f, back_inserter(retval)); + retval; +} + + +def generate_range(x, y, inserter) { + auto i = x; + while (i <= y) { + inserter(i); + ++i; + } +} + + +# Returns a new Vector which represents the range from the first value to the second value +def generate_range(x, y) { + auto retval = Vector(); + generate_range(x,y,back_inserter(retval)); + retval; +} + + +# Returns a new Vector with the first value to the second value as its elements +def collate(x, y) { + return [x, y]; +} + + +def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) { + auto r_x = range(x); + auto r_y = range(y); + while (!r_x.empty() && !r_y.empty()) { + inserter(f(r_x.front(), r_y.front())); + r_x.pop_front(); + r_y.pop_front(); + } +} + + +# Returns a new Vector which joins matching elements of the second and third value with the first value function +def zip_with(f, x, y) { + auto retval = Vector(); + zip_with(f,x,y,back_inserter(retval)); + retval; +} + + +# Returns a new Vector which joins matching elements of the first and second +def zip(x, y) { + zip_with(collate, x, y); +} + + +# Returns the position of the second value string in the first value string +def string::find(substr) : is_type(substr, "string") { + find(this, substr, size_t(0)); +} + + +# Returns the position of last match of the second value string in the first value string +def string::rfind(substr) : is_type(substr, "string") { + rfind(this, substr, size_t(-1)); +} + + +# Returns the position of the first match of elements in the second value string in the first value string +def string::find_first_of(list) : is_type(list, "string") { + find_first_of(this, list, size_t(0)); +} + + +# Returns the position of the last match of elements in the second value string in the first value string +def string::find_last_of(list) : is_type(list, "string") { + find_last_of(this, list, size_t(-1)); +} + + +# Returns the position of the first non-matching element in the second value string in the first value string +def string::find_first_not_of(list) : is_type(list, "string") { + find_first_not_of(this, list, size_t(0)); +} + + +# Returns the position of the last non-matching element in the second value string in the first value string +def string::find_last_not_of(list) : is_type(list, "string") { + find_last_not_of(this, list, size_t(-1)); +} + + +def string::ltrim() { + drop_while(this, fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'}); +} + + +def string::rtrim() { + reverse(drop_while(reverse(this), fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'})); +} + + +def string::trim() { + ltrim(rtrim(this)); +} + + +def find(container, value, compare_func) : call_exists(range, container) && is_type(compare_func, "Function") { + auto range = range(container); + while (!range.empty()) { + if (compare_func(range.front(), value)) { + return range; + } else { + range.pop_front(); + } + } + return range; +} + + +def find(container, value) { + return find(container, value, eq) +} + + +)""; +} + +}; +} + +#endif /* CHAISCRIPT_PRELUDE_HPP_ */ diff --git a/include/chaiscript/language/chaiscript_prelude.hpp b/include/chaiscript/language/chaiscript_prelude.hpp deleted file mode 100644 index 3636ae8f..00000000 --- a/include/chaiscript/language/chaiscript_prelude.hpp +++ /dev/null @@ -1,329 +0,0 @@ -// This file is distributed under the BSD License. -// See "license.txt" for details. -// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) -// http://www.chaiscript.com - -#ifndef CHAISCRIPT_PRELUDE_HPP_ -#define CHAISCRIPT_PRELUDE_HPP_ - -//Note, the expression "[x,y]" in "collate" is parsed as two separate expressions -//by C++, so CODE_STRING, takes two expressions and adds in the missing comma -#define CODE_STRING(x, y) #x ", " #y - -#define chaiscript_prelude CODE_STRING(\ -def lt(l, r) { if (call_exists(`<`, l, r)) { l < r } else { type_name(l) < type_name(r) } } \n\ -def gt(l, r) { if (call_exists(`>`, l, r)) { l > r } else { type_name(l) > type_name(r) } } \n\ -def eq(l, r) { if (call_exists(`==`, l, r)) { l == r } else { false } } \n\ -def new(x) { eval(type_name(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\ -def to_string(x) : call_exists(first, x) && call_exists(second, x) { \n\ - "<" + x.first.to_string() + ", " + x.second.to_string() + ">"; \n\ -}\n\ -# to_string for containers\n\ -def to_string(x) : call_exists(range, x) && !x.is_type("string"){ \n\ - "[" + x.join(", ") + "]"; \n\ -}\n\ -# Basic to_string function\n\ -def to_string(x) { \n\ - internal_to_string(x); \n\ -}\n\ -# Prints to console with no carriage return\n\ -def puts(x) { \n\ - print_string(x.to_string()); \n\ -} \n\ -# Prints to console with carriage return\n\ -def print(x) { \n\ - println_string(x.to_string()); \n\ -} \n\ -# Returns the maximum value of two numbers\n\ -def max(a, b) { if (a>b) { a } else { b } } \n\ -# Returns the minimum value of two numbers\n\ -def min(a, b) { if (a 0) && (!r.empty())) { \n\ - inserter(r.front()); \n\ - r.pop_front(); \n\ - --i; \n\ - } \n\ -} \n\ -# Returns a new container with the given number of elements taken from the container\n\ -def take(container, num) {\n\ - var retval = new(container); \n\ - take(container, num, back_inserter(retval)); \n\ - retval; \n\ -}\n\ -def take_while(container, f, inserter) : call_exists(range, container) { \n\ - var r = range(container); \n\ - while ((!r.empty()) && f(r.front())) { \n\ - inserter(r.front()); \n\ - r.pop_front(); \n\ - } \n\ -} \n\ -# Returns a new container with the given elements match the second value function\n\ -def take_while(container, f) {\n\ - var retval = new(container); \n\ - take_while(container, f, back_inserter(retval)); \n\ - retval;\n\ -}\n\ -def drop(container, num, inserter) : call_exists(range, container) { \n\ - var r = range(container); \n\ - var i = num; \n\ - while ((i > 0) && (!r.empty())) { \n\ - r.pop_front(); \n\ - --i; \n\ - } \n\ - while (!r.empty()) { \n\ - inserter(r.front()); \n\ - r.pop_front(); \n\ - } \n\ -} \n\ -# Returns a new container with the given number of elements dropped from the given container \n\ -def drop(container, num) {\n\ - var retval = new(container); \n\ - drop(container, num, back_inserter(retval)); \n\ - retval; \n\ -}\n\ -def drop_while(container, f, inserter) : call_exists(range, container) { \n\ - var r = range(container); \n\ - while ((!r.empty())&& f(r.front())) { \n\ - r.pop_front(); \n\ - } \n\ - while (!r.empty()) { \n\ - inserter(r.front()); \n\ - r.pop_front(); \n\ - } \n\ -} \n\ -# Returns a new container with the given elements dropped that match the second value function\n\ -def drop_while(container, f) {\n\ - var retval = new(container); \n\ - drop_while(container, f, back_inserter(retval)); \n\ - retval; \n\ -}\n\ -# Applies the second value function to the container. Starts with the first two elements. Expects at least 2 elements.\n\ -def reduce(container, func) : container.size() >= 2 && call_exists(range, container) { \n\ - var r = range(container); \n\ - var retval = r.front(); \n\ - r.pop_front(); \n\ - retval = func(retval, r.front()); \n\ - r.pop_front(); \n\ - while (!r.empty()) { \n\ - retval = func(retval, r.front()); \n\ - r.pop_front(); \n\ - } \n\ - retval; \n\ -} \n\ -# Returns a string of the elements in container delimited by the second value string\n\ -def join(container, delim) { \n\ - var retval = ""; \n\ - var range = range(container); \n\ - if (!range.empty()) { \n\ - retval += to_string(range.front()); \n\ - range.pop_front(); \n\ - while (!range.empty()) { \n\ - retval += delim; \n\ - retval += to_string(range.front()); \n\ - range.pop_front(); \n\ - } \n\ - } \n\ - retval; \n\ -} \n\ -def filter(container, f, inserter) : call_exists(range, container) { \n\ - var r = range(container); \n\ - while (!r.empty()) { \n\ - if (f(r.front())) { \n\ - inserter(r.front()); \n\ - } \n\ - r.pop_front(); \n\ - } \n\ -} \n\ -# Returns a new Vector which match the second value function\n\ -def filter(container, f) { \n\ - var retval = new(container); \n\ - filter(container, f, back_inserter(retval));\n\ - retval;\n\ -}\n\ -def generate_range(x, y, inserter) { \n\ - var i = x; \n\ - while (i <= y) { \n\ - inserter(i); \n\ - ++i; \n\ - } \n\ -} \n\ -# Returns a new Vector which represents the range from the first value to the second value\n\ -def generate_range(x, y) { \n\ - var retval = Vector(); \n\ - generate_range(x,y,back_inserter(retval)); \n\ - retval; \n\ -}\n\ -# Returns a new Vector with the first value to the second value as its elements\n\ -def collate(x, y) { \n\ - [x, y]; \n\ -} \n\ -def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) { \n\ - var r_x = range(x); \n\ - var r_y = range(y); \n\ - while (!r_x.empty() && !r_y.empty()) { \n\ - inserter(f(r_x.front(), r_y.front())); \n\ - r_x.pop_front(); \n\ - r_y.pop_front(); \n\ - } \n\ -} \n\ -# Returns a new Vector which joins matching elements of the second and third value with the first value function\n\ -def zip_with(f, x, y) { \n\ - var retval = Vector(); \n\ - zip_with(f,x,y,back_inserter(retval)); \n\ - retval;\n\ -}\n\ -# Returns a new Vector which joins matching elements of the first and second\n\ -def zip(x, y) { \n\ - zip_with(collate, x, y); \n\ -}\n\ -# Returns the position of the second value string in the first value string\n\ -def string::find(substr) : is_type(substr, "string") { \n\ - int(find(this, substr, 0)); \n\ -} \n\ -# Returns the position of last match of the second value string in the first value string\n\ -def string::rfind(substr) : is_type(substr, "string") { \n\ - int(rfind(this, substr, -1)); \n\ -} \n\ -# Returns the position of the first match of elements in the second value string in the first value string\n\ -def string::find_first_of(list) : is_type(list, "string") { \n\ - int(find_first_of(this, list, 0)); \n\ -} \n\ -# Returns the position of the last match of elements in the second value string in the first value string\n\ -def string::find_last_of(list) : is_type(list, "string") { \n\ - int(find_last_of(this, list, -1)); \n\ -} \n\ -# Returns the position of the first non-matching element in the second value string in the first value string\n\ -def string::find_first_not_of(list) : is_type(list, "string") { \n\ - int(find_first_not_of(this, list, 0)); \n\ -} \n\ -# Returns the position of the last non-matching element in the second value string in the first value string\n\ -def string::find_last_not_of(list) : is_type(list, "string") { \n\ - int(find_last_not_of(this, list, -1)); \n\ -} \n\ -def string::ltrim() { \n\ - drop_while(this, fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'}); \n\ -} \n\ -def string::rtrim() { \n\ - reverse(drop_while(reverse(this), fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'})); \n\ -} \n\ -def string::trim() { \n\ - ltrim(rtrim(this)); \n\ -} \n\ -def find(container, value, compare_func) : call_exists(range, container) && is_type(compare_func, "Function") { \n\ - var range = range(container); \n\ - while (!range.empty()) { \n\ - if (compare_func(range.front(), value)) { \n\ - return range; \n\ - } else { \n\ - range.pop_front(); \n\ - } \n\ - } \n\ - return range; \n\ -} \n\ -def find(container, value) { return find(container, value, eq) } \ -) -#endif /* CHAISCRIPT_PRELUDE_HPP_ */ diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 2d66cc6f..262ae1ab 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -8,90 +8,36 @@ #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_SEQ_ELEM(2, _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)(_class_name_translator), _constructors) \ - CHAISCRIPT_CLASS_METHODS((_module)(_class_name)(_class_name_translator)(_method_name_translator), _methods) \ - } - -#define CHAISCRIPT_CLASS_NO_CONSTRUCTOR_EX(_module, _class_name, _class_name_translator, _method_name_translator, _methods) \ - { \ - _module->add(chaiscript::user_type<_class_name>(), _class_name_translator (BOOST_PP_STRINGIZE(_class_name))); \ - 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) - -#define CHAISCRIPT_CLASS_NO_CONSTRUCTOR(_module, _class_name, _methods) \ - CHAISCRIPT_CLASS_NO_CONSTRUCTOR_EX(_module, _class_name, chaiscript::utility::class_name_translator, \ - chaiscript::utility::method_name_translator, _methods) namespace chaiscript { - /// \brief Classes and functions which provide general utility to the end user. namespace utility { - inline std::string class_name_translator(const std::string &t_name) - { - size_t colon = t_name.rfind("::"); - if (colon != std::string::npos) + + /// \todo Use of this utility, and uniform initializer lists, is causing memory errors in MSVC + + template + void add_class(ModuleType &t_module, + const std::string &t_classname, + const std::vector &t_constructors, + const std::vector> &t_funcs) { - return t_name.substr(colon+2, std::string::npos); - } else { - return t_name; + t_module.add(chaiscript::user_type(), t_classname); + + for(const chaiscript::Proxy_Function &ctor: t_constructors) + { + t_module.add(ctor, t_classname); + } + + for(auto fun: t_funcs) + { + t_module.add(fun.first, fun.second); + } + } - } - - inline std::string method_name_translator(const std::string &t_name) - { - size_t namestart = t_name.rfind("operator"); - namestart = (namestart == std::string::npos)?0:namestart+strlen("operator"); - - if (namestart == 0) - { - namestart = t_name.rfind("::"); - namestart = (namestart == std::string::npos)?0:namestart+strlen("::"); - } - - return t_name.substr(namestart, std::string::npos); - } + } } diff --git a/readme.md b/readme.md index f9a9dea0..a8919e4f 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,5 @@ -[![Build Status](https://travis-ci.org/ChaiScript/ChaiScript.png?branch=master)](https://travis-ci.org/ChaiScript/ChaiScript) +[![Build Status](https://travis-ci.org/ChaiScript/ChaiScript.png?branch=ChaiScript_5_0_CPP_11)](https://travis-ci.org/ChaiScript/ChaiScript) +[![Coverage Status](https://coveralls.io/repos/ChaiScript/ChaiScript/badge.png?branch=ChaiScript_5_0_CPP_11)](https://coveralls.io/r/ChaiScript/ChaiScript?branch=ChaiScript_5_0_CPP_11) ChaiScript @@ -9,6 +10,7 @@ http://www.chaiscript.com Release under the BSD license, see "license.txt" for details. + Introduction ============ @@ -18,26 +20,33 @@ techniques, working with the developer like he expects it to work. Being a native C++ application, it has some advantages over existing embedded scripting languages: -1) It uses a header-only approach, which makes it easy to integrate with +1. It uses a header-only approach, which makes it easy to integrate with existing projects. -2) It maintains type safety between your C++ application and the user scripts. -3) It supports a variety of C++ techniques including callbacks, overloaded +2. It maintains type safety between your C++ application and the user scripts. +3. It supports a variety of C++ techniques including callbacks, overloaded functions, class methods, and stl containers. + Requirements ============ -ChaiScript requires a recent version of Boost (http://www.boost.org) to build. +ChaiScript requires a C++11 compiler to build with support for variadic +templates. It has been tested with gcc 4.7 and clang 3.1 (with libcxx). MacOS +10.8 (Mountain Lion) is also known to support the C++11 build with Apple's +clang 4.0. Usage ===== * Add the ChaiScript include directory to your project's header search path * Add `#include ` to your source file -* Instantiate the ChaiScript engine in your application. For example, create - a new engine with the name `chai` like so: `chaiscript::ChaiScript chai` +* Instantiate the ChaiScript engine in your application. For example, create a + new engine with the name `chai` like so: `chaiscript::ChaiScript chai` +* The default behavior is to load the ChaiScript standard library from a + loadable module. A second option is to compile the library into your code, + see below for an example. -Once instantiated, the engine is ready to start running ChaiScript source. You +Once instantiated, the engine is ready to start running ChaiScript source. You have two main options for processing ChaiScript source: a line at a time using `chai.eval(string)` and a file at a time using `chai.eval_file(fname)` @@ -83,3 +92,26 @@ The shortest complete example possible follows: } + +Or, if you want to compile the std lib into your code, which reduces +runtime requirements. + + /// main.cpp + + #include + #include + + double function(int i, double j) + { + return i * j; + } + + int main() + { + chaiscript::ChaiScript chai(chaiscript::Std_Lib::library()); + chai.add(chaiscript::fun(&function), "function"); + + double d = chai.eval("function(3, 4.75);"); + } + + diff --git a/releasenotes.txt b/releasenotes.txt index 7df1dc7d..c25d0dd3 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -1,8 +1,11 @@ -Current Version: 4.3.0 +Notes: -Note: this is scheduled to be the last release that requires boost, new releases after this will require a C++11 compiler. + * There was overlap during the 5.x and 4.x development cycle, so some of the notes appear twice as the new features were developed for 4.x (which required boost) then ported to 5.x (which requires C++11). + * This is the last release of 5.x, all future development will be on the final merged 6.x line. -### Changes since 4.2.0 + +### Changes since 5.2.0 +* Official support for MSVC with C++11. All major platforms and compilers are now support for C++11 release * Enhanced unit tests * Add `continue` statement, fix various use cases for `for` loops * Fix use of suffixed numbers in vector initialization @@ -18,20 +21,22 @@ Note: this is scheduled to be the last release that requires boost, new releases * Fix various string / map / vector `size` and `count` calls for compilers which have weird overloads for them. #90 #93 #95 * Make module search path relative to the currently running executable * Build and work with wstring windows builds +* fix for some new line cases in the middle of a vector initialization from jespada -### Changes since 4.1.1 +### Changes since 5.1.0 * Add support for automatic conversion of arithmetic types when possible and when no ambiguous method dispatch exists. -### Changes since 4.1.0 -* Fix missed gcc build error in 4.1.0 - -Changes since 4.0.0 +### Changes since 5.0.0 * Fix sizing of numeric constants to match that of the C++ standard * Add support for u,ll,l,f suffixes for numeric constants * Siginificant improvement in error reporting -Changes since 3.1.0 +### Changes since 4.0.0 +* Dropped boost in favor of C++11 +* Separated out stdlib to make more options for compile time improvements + +### Changes since 3.1.0 * svenstaro: Unused variables and CMake consistency fixes * Added support for returning pointers from functions (#13) * Compile with -pedantic (#9) diff --git a/samples/example.cpp b/samples/example.cpp index 086f60df..9b518320 100644 --- a/samples/example.cpp +++ b/samples/example.cpp @@ -5,32 +5,20 @@ // http://www.chaiscript.com #include +#include #include +#include #include -#include - -#ifdef __llvm__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -#ifdef __llvm__ -#pragma clang diagnostic pop -#endif - -#include void log(const std::string &msg) { - std::cout << "[" << boost::posix_time::microsec_clock::local_time() << "] " << msg << std::endl; + std::cout << "[" << time(nullptr) << "] " << msg << std::endl; } void log(const std::string &module, const std::string &msg) { - std::cout << "[" << boost::posix_time::microsec_clock::local_time() << "] <" << module << "> " << msg << std::endl; + std::cout << "[" << time(nullptr) << "] <" << module << "> " << msg << std::endl; } void bound_log(const std::string &msg) @@ -51,10 +39,10 @@ void hello_constructor(const chaiscript::Boxed_Value & /*o*/) struct System { - std::map > m_callbacks; + std::map > m_callbacks; void add_callback(const std::string &t_name, - const boost::function &t_func) + const std::function &t_func) { m_callbacks[t_name] = t_func; } @@ -63,7 +51,7 @@ struct System void do_callbacks(const std::string &inp) { log("Running Callbacks: " + inp); - for (std::map >::iterator itr = m_callbacks.begin(); + for (std::map >::iterator itr = m_callbacks.begin(); itr != m_callbacks.end(); ++itr) { @@ -72,7 +60,7 @@ struct System } }; -void take_shared_ptr(const boost::shared_ptr &p) +void take_shared_ptr(const std::shared_ptr &p) { std::cout << *p << std::endl; } @@ -98,7 +86,7 @@ int main(int /*argc*/, char * /*argv*/[]) { // Let's use chaiscript to add a new lambda callback to our system. // The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application // in the "add_callback" function of struct System the chaiscript function is converted into a - // boost::function, so it can be handled and called easily and type-safely + // std::function, so it can be handled and called easily and type-safely chai.eval("system.add_callback(\"#1\", fun(x) { \"Callback1 \" + x });"); // Because we are sharing the "system" object with the chaiscript engine we have equal @@ -119,14 +107,14 @@ int main(int /*argc*/, char * /*argv*/[]) { // A shortcut to using eval is just to use the chai operator() chai("log(\"Test Module\", \"Test Message\");"); - //Finally, it is possible to register any boost::function as a system function, in this + //Finally, it is possible to register any std::function as a system function, in this //way, we can, for instance add a bound member function to the system - chai.add(fun(&System::do_callbacks, boost::ref(system), std::string("Bound Test")), "do_callbacks"); + chai.add(fun(&System::do_callbacks, std::ref(system), std::string("Bound Test")), "do_callbacks"); //Call bound version of do_callbacks chai("do_callbacks()"); - boost::function caller = chai.eval >("fun() { system.do_callbacks(\"From Functor\"); }"); + std::function caller = chai.eval >("fun() { system.do_callbacks(\"From Functor\"); }"); caller(); @@ -150,13 +138,13 @@ int main(int /*argc*/, char * /*argv*/[]) { //To do: Add examples of handling Boxed_Values directly when needed //Creating a functor on the stack and using it immediatly - int x = chai.eval >("fun (x, y) { return x + y; }")(5, 6); + int x = chai.eval >("fun (x, y) { return x + y; }")(5, 6); std::stringstream ss; ss << x; log("Functor test output", ss.str()); - chai.add(var(boost::shared_ptr()), "nullvar"); + chai.add(var(std::shared_ptr()), "nullvar"); chai("print(\"This should be true.\"); print(nullvar.is_var_null())"); // test the global const action @@ -178,7 +166,7 @@ int main(int /*argc*/, char * /*argv*/[]) { //Dynamic objects test chai.add(chaiscript::Proxy_Function(new dispatch::detail::Dynamic_Object_Function("TestType", fun(&hello_world))), "hello_world"); chai.add(chaiscript::Proxy_Function(new dispatch::detail::Dynamic_Object_Constructor("TestType", fun(&hello_constructor))), "TestType"); -// chai.add(fun(boost::function(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr"); +// chai.add(fun(std::function(std::bind(&dispatch::detail::Dynamic_Object_Attribute::func, "TestType", "attr", std::placeholders::_1))), "attr"); chai.eval("var x = TestType()"); // chai.eval("x.attr = \"hi\""); diff --git a/samples/memory_leak_test.cpp b/samples/memory_leak_test.cpp index bbd8a5fe..7129da21 100644 --- a/samples/memory_leak_test.cpp +++ b/samples/memory_leak_test.cpp @@ -1,13 +1,14 @@ #include -#include "chaiscript/chaiscript.hpp" +#include +#include + #ifdef READLINE_AVAILABLE #include #include #endif -using namespace chaiscript; std::string get_next_command() { #ifdef READLINE_AVAILABLE @@ -30,30 +31,32 @@ void fuction(void) class test { - ChaiScript chai; - ChaiScript::State backupState; + chaiscript::ChaiScript chai; + chaiscript::ChaiScript::State backupState; + public: - test() - { - backupState = chai.get_state(); - } - ~test(){} - - void ResetState() - { - chai.set_state(backupState); - chai.add(fun(&fuction),"Whatever()"); - } - - void RunFile(std::string sFile) - { - try { - chaiscript::Boxed_Value val = chai.eval_file(sFile); + test() + : chai(chaiscript::Std_Lib::library()) + { + backupState = chai.get_state(); } - catch (std::exception &e) { - std::cout << e.what() << std::endl; + ~test(){} + + void ResetState() + { + chai.set_state(backupState); + chai.add(chaiscript::fun(&fuction),"Whatever()"); + } + + void RunFile(std::string sFile) + { + try { + chaiscript::Boxed_Value val = chai.eval_file(sFile); + } + catch (std::exception &e) { + std::cout << e.what() << std::endl; + } } - } }; diff --git a/src/chaiscript_stdlib.cpp b/src/chaiscript_stdlib.cpp new file mode 100644 index 00000000..d4ea13e8 --- /dev/null +++ b/src/chaiscript_stdlib.cpp @@ -0,0 +1,30 @@ + +#include + + +// MSVC doesn't like that we are using C++ return types from our C declared module +// but this is the best way to do it for cross platform compatibility +#ifdef CHAISCRIPT_MSVC +#pragma warning(push) +#pragma warning(disable : 4190) +#endif + +#ifdef __llvm__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +#endif + + +CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_chaiscript_stdlib() +{ + return chaiscript::Std_Lib::library(); +} + + +#ifdef __llvm__ +#pragma clang diagnostic pop +#endif + +#ifdef CHAISCRIPT_MSVC +#pragma warning(pop) +#endif diff --git a/src/main.cpp b/src/main.cpp index 1524931e..c8d98e71 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #define _CRT_SECURE_NO_WARNINGS #include @@ -15,27 +15,39 @@ #include #include #else + +char *mystrdup (const char *s) { + size_t len = strlen(s) + 1; // Space for length plus nul + char *d = static_cast(malloc (len)); + if (d == nullptr) return nullptr; // No memory +#ifdef CHAISCRIPT_MSVC + strcpy_s(d, len, s); // Copy the characters +#else + strcpy(d,s); // Copy the characters +#endif + return d; // Return the new string +} + char* readline(const char* p) { std::string retval; std::cout << p ; std::getline(std::cin, retval); -#ifdef BOOST_MSVC - return std::cin.eof() ? NULL : _strdup(retval.c_str()); -#else - return std::cin.eof() ? NULL : strdup(retval.c_str()); -#endif + return std::cin.eof() ? NULL : mystrdup(retval.c_str()); } + + void add_history(const char*){} void using_history(){} #endif -void *cast_module_symbol(std::string (*t_path)()) + +void *cast_module_symbol(std::vector (*t_path)()) { union cast_union { - std::string (*in_ptr)(); + std::vector (*in_ptr)(); void *out_ptr; }; @@ -44,22 +56,27 @@ void *cast_module_symbol(std::string (*t_path)()) return c.out_ptr; } -std::string default_search_path() +std::vector default_search_paths() { -#ifdef BOOST_WINDOWS // force no unicode + std::vector paths; + +#ifdef CHAISCRIPT_WINDOWS // force no unicode CHAR path[4096]; int size = GetModuleFileNameA(0, path, sizeof(path)-1); std::string exepath(path, size); - size_t secondtolastslash = exepath.rfind('\\', exepath.rfind('\\') - 1); - if (secondtolastslash != std::string::npos) + size_t lastslash = exepath.rfind('\\'); + size_t secondtolastslash = exepath.rfind('\\', lastslash - 1); + if (lastslash != std::string::npos) { - return exepath.substr(0, secondtolastslash) + "\\lib\\chaiscript\\"; - } else { - return ""; + paths.push_back(exepath.substr(0, lastslash)); } + if (secondtolastslash != std::string::npos) + { + return {exepath.substr(0, secondtolastslash) + "\\lib\\chaiscript\\"}; + } #else std::string exepath; @@ -90,25 +107,31 @@ std::string default_search_path() if (exepath.empty()) { - Dl_info rInfo; + Dl_info rInfo; memset( &rInfo, 0, sizeof(rInfo) ); - if ( !dladdr(cast_module_symbol(&default_search_path), &rInfo) || !rInfo.dli_fname ) { - return ""; + if ( !dladdr(cast_module_symbol(&default_search_paths), &rInfo) || !rInfo.dli_fname ) { + return paths; } exepath = std::string(rInfo.dli_fname); } - size_t secondtolastslash = exepath.rfind('/', exepath.rfind('/') - 1); + size_t lastslash = exepath.rfind('/'); + + size_t secondtolastslash = exepath.rfind('/', lastslash - 1); + if (lastslash != std::string::npos) + { + paths.push_back(exepath.substr(0, lastslash)); + } + if (secondtolastslash != std::string::npos) { - return exepath.substr(0, secondtolastslash) + "/lib/chaiscript/"; - } else { - return ""; + paths.push_back(exepath.substr(0, secondtolastslash) + "/lib/chaiscript/"); } #endif -} + return paths; +} void help(int n) { if ( n >= 0 ) { @@ -132,7 +155,7 @@ void version(int){ std::cout << "chai: compiled " << __TIME__ << " " << __DATE__ << std::endl; } -bool throws_exception(const boost::function &f) +bool throws_exception(const std::function &f) { try { f(); @@ -143,7 +166,7 @@ bool throws_exception(const boost::function &f) return false; } -chaiscript::exception::eval_error get_eval_error(const boost::function &f) +chaiscript::exception::eval_error get_eval_error(const std::function &f) { try { f(); @@ -160,18 +183,21 @@ std::string get_next_command() { char *input_raw = readline("eval> "); if ( input_raw ) { add_history(input_raw); - std::string val(input_raw); - size_t pos = val.find_first_not_of("\t \n"); - if (pos != std::string::npos) - { - val.erase(0, pos); - } - pos = val.find_last_not_of("\t \n"); - if (pos != std::string::npos) - { - val.erase(pos+1, std::string::npos); - } + + std::string val(input_raw); + size_t pos = val.find_first_not_of("\t \n"); + if (pos != std::string::npos) + { + val.erase(0, pos); + } + pos = val.find_last_not_of("\t \n"); + if (pos != std::string::npos) + { + val.erase(pos+1, std::string::npos); + } + retval = val; + ::free(input_raw); } } @@ -204,7 +230,7 @@ void interactive(chaiscript::ChaiScript& chai) //Then, we try to print the result of the evaluation to the user if (!val.get_type_info().bare_equal(chaiscript::user_type())) { try { - std::cout << chai.eval >("to_string")(val) << std::endl; + std::cout << chai.eval >("to_string")(val) << std::endl; } catch (...) {} //If we can't, do nothing } @@ -225,11 +251,9 @@ void interactive(chaiscript::ChaiScript& chai) int main(int argc, char *argv[]) { - std::vector usepaths; - std::vector modulepaths; // Disable deprecation warning for getenv call. -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(push) #pragma warning(disable : 4996) #endif @@ -237,18 +261,20 @@ int main(int argc, char *argv[]) const char *usepath = getenv("CHAI_USE_PATH"); const char *modulepath = getenv("CHAI_MODULE_PATH"); -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif + std::vector usepaths; usepaths.push_back(""); if (usepath) { usepaths.push_back(usepath); } - std::string searchpath = default_search_path(); - modulepaths.push_back(searchpath); + std::vector modulepaths; + std::vector searchpaths = default_search_paths(); + modulepaths.insert(modulepaths.end(), searchpaths.begin(), searchpaths.end()); modulepaths.push_back(""); if (modulepath) { diff --git a/src/reflection.cpp b/src/reflection.cpp index 92713795..cb369f25 100644 --- a/src/reflection.cpp +++ b/src/reflection.cpp @@ -6,13 +6,15 @@ #include +#include +#include #include #include // MSVC doesn't like that we are using C++ return types from our C declared module // but this is the best way to do it for cross platform compatibility -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(push) #pragma warning(disable : 4190) #endif @@ -20,8 +22,8 @@ bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) { - boost::shared_ptr pf - = boost::dynamic_pointer_cast(t_pf); + std::shared_ptr pf + = std::dynamic_pointer_cast(t_pf); if (pf) { if (pf->get_parse_tree()) @@ -37,8 +39,8 @@ bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) chaiscript::AST_NodePtr get_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) { - boost::shared_ptr pf - = boost::dynamic_pointer_cast(t_pf); + std::shared_ptr pf + = std::dynamic_pointer_cast(t_pf); if (pf) { if (pf->get_parse_tree()) @@ -68,40 +70,49 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect m->add(chaiscript::base_class()); - chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); + chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); - CHAISCRIPT_CLASS_NO_CONSTRUCTOR( m, - chaiscript::exception::eval_error, - ((reason)) - ((call_stack)) - ); - - CHAISCRIPT_CLASS( m, - chaiscript::File_Position, - (chaiscript::File_Position()) - (chaiscript::File_Position(int,int)), - ((line)) - ((column)) - ); - - CHAISCRIPT_CLASS_NO_CONSTRUCTOR( m, - chaiscript::AST_Node, - ((text)) - ((identifier)) - ((filename)) - ((start)) - ((end)) - ((internal_to_string)) - ((children)) - ((replace_child)) - ); - - CHAISCRIPT_CLASS( m, - chaiscript::parser::ChaiScript_Parser, - (chaiscript::parser::ChaiScript_Parser ()), - ((parse)) - ((ast)) - ); + using namespace chaiscript; + + chaiscript::utility::add_class(*m, + "eval_error", + { }, + { {fun(&chaiscript::exception::eval_error::reason), "reason"}, + {fun(&chaiscript::exception::eval_error::call_stack), "call_stack"} } + ); + + + chaiscript::utility::add_class(*m, + "File_Position", + { constructor(), + constructor() }, + { {fun(&File_Position::line), "line"}, + {fun(&File_Position::column), "column"} } + ); + + + chaiscript::utility::add_class(*m, + "AST_Node", + { }, + { {fun(&AST_Node::text), "text"}, + {fun(&AST_Node::identifier), "identifier"}, + {fun(&AST_Node::filename), "filename"}, + {fun(&AST_Node::start), "start"}, + {fun(&AST_Node::end), "end"}, + {fun(&AST_Node::internal_to_string), "internal_to_string"}, + {fun(&AST_Node::children), "children"}, + {fun(&AST_Node::replace_child), "replace_child"} + } + ); + + + chaiscript::utility::add_class(*m, + "ChaiScript_Parser", + { constructor() }, + { {fun(&parser::ChaiScript_Parser::parse), "parse"}, + {fun(&parser::ChaiScript_Parser::ast), "ast"} } + ); + return m; @@ -113,6 +124,6 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif diff --git a/src/stl_extra.cpp b/src/stl_extra.cpp index 029e4a5d..eb6bb8c5 100644 --- a/src/stl_extra.cpp +++ b/src/stl_extra.cpp @@ -5,12 +5,13 @@ // http://www.chaiscript.com #include +#include #include #include // MSVC doesn't like that we are using C++ return types from our C declared module // but this is the best way to do it for cross platform compatibility -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(push) #pragma warning(disable : 4190) #endif @@ -29,6 +30,6 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extr #pragma clang diagnostic pop #endif -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif diff --git a/src/test_module.cpp b/src/test_module.cpp index 796f5ff0..144e8d47 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -52,7 +52,7 @@ int *get_new_int() // MSVC doesn't like that we are using C++ return types from our C declared module // but this is the best way to do it for cross platform compatibility -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(push) #pragma warning(disable : 4190) #endif @@ -103,6 +103,6 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo #pragma clang diagnostic pop #endif -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif diff --git a/unittests/3.x/assign_const.chai b/unittests/3.x/assign_const.chai new file mode 100644 index 00000000..ff6a8c3d --- /dev/null +++ b/unittests/3.x/assign_const.chai @@ -0,0 +1,2 @@ +assert_throws("Mismatched types in equation, lhs is const.", fun() { 1 = 2 } ); +assert_throws("Mismatched types in equation, lhs is const.", fun() { 1 + 2 = 2 } ); diff --git a/unittests/3.x/bind.chai b/unittests/3.x/bind.chai new file mode 100644 index 00000000..3c72673f --- /dev/null +++ b/unittests/3.x/bind.chai @@ -0,0 +1,2 @@ +var prod = bind(foldl, _, `*`, 1.0) +assert_equal(60, prod([3, 4, 5])) diff --git a/unittests/3.x/bind2.chai b/unittests/3.x/bind2.chai new file mode 100644 index 00000000..0b8ddde3 --- /dev/null +++ b/unittests/3.x/bind2.chai @@ -0,0 +1,34 @@ + +def add(x, y) +{ + return x + y; +} + +assert_equal(2, add.get_arity()); + +var b = bind(add, 2, _); + +assert_equal(1, b.get_arity()); + +var c = bind(b, 3); + +assert_equal(0, c.get_arity()); + +assert_equal(6, b(4)); +assert_equal(5, c()); + +def concat2(a,b,c,d) +{ + return to_string(a) + to_string(b) + to_string(c) + to_string(d); +} + +var d = bind(concat2, _, " Hello ", _, " World"); +assert_equal(2, d.get_arity()); + +assert_equal("1 Hello 3 World", d(1,3)); + +var e = bind(`<`, _, 5); +var types = e.get_param_types(); +assert_equal(2, types.size()); +assert_equal(true, types[0].bare_equal(bool_type)); + diff --git a/unittests/3.x/block_start.chai b/unittests/3.x/block_start.chai new file mode 100644 index 00000000..4830af1f --- /dev/null +++ b/unittests/3.x/block_start.chai @@ -0,0 +1 @@ +{print("hello")} diff --git a/unittests/3.x/bool_not.chai b/unittests/3.x/bool_not.chai new file mode 100644 index 00000000..fe4d0f77 --- /dev/null +++ b/unittests/3.x/bool_not.chai @@ -0,0 +1 @@ +assert_equal(false, !true) diff --git a/unittests/3.x/break_while.chai b/unittests/3.x/break_while.chai new file mode 100644 index 00000000..d54a3dd9 --- /dev/null +++ b/unittests/3.x/break_while.chai @@ -0,0 +1,7 @@ +var i = 0 +while (i < 10) { + if (++i == 5) { + break + } +} +assert_equal(5, i); diff --git a/unittests/3.x/char_init.chai b/unittests/3.x/char_init.chai new file mode 100644 index 00000000..ce764774 --- /dev/null +++ b/unittests/3.x/char_init.chai @@ -0,0 +1 @@ +assert_equal("b", to_string('b')) diff --git a/unittests/3.x/classification.chai b/unittests/3.x/classification.chai new file mode 100644 index 00000000..8c2cca94 --- /dev/null +++ b/unittests/3.x/classification.chai @@ -0,0 +1,7 @@ +assert_equal(true, 1.is_var_const()); +assert_equal(false, 1.is_var_reference()); +assert_equal(true, 1.is_var_pointer()); +assert_equal(false, 1.is_var_null()); +assert_equal(false, 1.is_var_undef()); +var i; +assert_equal(true, i.is_var_undef()); diff --git a/unittests/3.x/collate.chai b/unittests/3.x/collate.chai new file mode 100644 index 00000000..12632e59 --- /dev/null +++ b/unittests/3.x/collate.chai @@ -0,0 +1,3 @@ +var v = collate(1, 2) +assert_equal(1, v[0]) +assert_equal(2, v[1]) diff --git a/unittests/3.x/compare_gt.chai b/unittests/3.x/compare_gt.chai new file mode 100644 index 00000000..9a6ea456 --- /dev/null +++ b/unittests/3.x/compare_gt.chai @@ -0,0 +1 @@ +assert_equal(false, 1 > 2); diff --git a/unittests/3.x/compare_lt.chai b/unittests/3.x/compare_lt.chai new file mode 100644 index 00000000..60641103 --- /dev/null +++ b/unittests/3.x/compare_lt.chai @@ -0,0 +1 @@ +assert_equal(true, 1 < 2) diff --git a/unittests/3.x/concat.chai b/unittests/3.x/concat.chai new file mode 100644 index 00000000..3d285a5b --- /dev/null +++ b/unittests/3.x/concat.chai @@ -0,0 +1,5 @@ +var v = concat([1, 2], [3, 4]); + +assert_equal(4, v.size()); +assert_equal(1, v[0]); +assert_equal(4, v[3]); diff --git a/unittests/3.x/const_range_test.chai b/unittests/3.x/const_range_test.chai new file mode 100644 index 00000000..5ebb5808 --- /dev/null +++ b/unittests/3.x/const_range_test.chai @@ -0,0 +1,4 @@ +//If the following succeeds, the test passes + + +"Hello World".for_each(fun(x) { print(x) } ) diff --git a/unittests/3.x/convert_double_string.chai b/unittests/3.x/convert_double_string.chai new file mode 100644 index 00000000..e12b90f2 --- /dev/null +++ b/unittests/3.x/convert_double_string.chai @@ -0,0 +1 @@ +assert_equal("3.5bob", 3.5.to_string() + "bob"); diff --git a/unittests/3.x/convert_int_string.chai b/unittests/3.x/convert_int_string.chai new file mode 100644 index 00000000..0fcda326 --- /dev/null +++ b/unittests/3.x/convert_int_string.chai @@ -0,0 +1 @@ +assert_equal("3bob", 3.to_string + "bob") diff --git a/unittests/3.x/convert_string_double.chai b/unittests/3.x/convert_string_double.chai new file mode 100644 index 00000000..b7b0b6ef --- /dev/null +++ b/unittests/3.x/convert_string_double.chai @@ -0,0 +1 @@ +assert_equal(6.8, "3.5".to_double() + 3.3) diff --git a/unittests/3.x/convert_string_int.chai b/unittests/3.x/convert_string_int.chai new file mode 100644 index 00000000..e62eec95 --- /dev/null +++ b/unittests/3.x/convert_string_int.chai @@ -0,0 +1 @@ +assert_equal(8, "4".to_int() + 4) diff --git a/unittests/3.x/deep_array_lookup.chai b/unittests/3.x/deep_array_lookup.chai new file mode 100644 index 00000000..c405302d --- /dev/null +++ b/unittests/3.x/deep_array_lookup.chai @@ -0,0 +1,11 @@ +var a = [1,2,3, [4,5,6] ] + +assert_equal(a[3][0], 4) + + +def Test::Test() { this.a = [1,2,3]; } +attr Test::a; + +var t = Test(); + +assert_equal(t.a[0], 1) diff --git a/unittests/3.x/dispatch_functions.chai b/unittests/3.x/dispatch_functions.chai new file mode 100644 index 00000000..528d5b30 --- /dev/null +++ b/unittests/3.x/dispatch_functions.chai @@ -0,0 +1,11 @@ +assert_equal(`==`, `==`); +assert_not_equal(`==`, `<`); +assert_equal(`<`.get_arity(), 2); +assert_equal(`+`.get_annotation(), "Multiple method dispatch function wrapper."); +assert_equal(get_arity.get_contained_functions().size(), 0); +assert_equal(get_arity.get_arity(), 1); +assert_equal(get_arity.get_param_types().size(), 2); + +var paramtypes = get_arity.get_param_types(); + +assert_equal(true, paramtypes[1].bare_equal(Function_type)); diff --git a/unittests/3.x/drop.chai b/unittests/3.x/drop.chai new file mode 100644 index 00000000..c64b431e --- /dev/null +++ b/unittests/3.x/drop.chai @@ -0,0 +1 @@ +assert_equal([3,4], drop([1, 2, 3, 4], 2)) diff --git a/unittests/3.x/drop_while.chai b/unittests/3.x/drop_while.chai new file mode 100644 index 00000000..08e19f2f --- /dev/null +++ b/unittests/3.x/drop_while.chai @@ -0,0 +1 @@ +assert_equal([2, 3], drop_while([1, 2, 3], odd)) diff --git a/unittests/3.x/empty.chai b/unittests/3.x/empty.chai new file mode 100644 index 00000000..e69de29b diff --git a/unittests/3.x/equ_shortform.chai b/unittests/3.x/equ_shortform.chai new file mode 100644 index 00000000..41c8e1de --- /dev/null +++ b/unittests/3.x/equ_shortform.chai @@ -0,0 +1,4 @@ +var x=.5 +assert_equal(.5, x) +var y=-.5 +assert_equal(-.5, y) diff --git a/unittests/3.x/eval.chai b/unittests/3.x/eval.chai new file mode 100644 index 00000000..2f18aa41 --- /dev/null +++ b/unittests/3.x/eval.chai @@ -0,0 +1 @@ +assert_equal(7, eval("3 + 4")) diff --git a/unittests/3.x/eval_error.chai b/unittests/3.x/eval_error.chai new file mode 100644 index 00000000..d63ad759 --- /dev/null +++ b/unittests/3.x/eval_error.chai @@ -0,0 +1,39 @@ +load_module("reflection") + +def deep() +{ + try { + } catch { + + } finally { + if (2) + { + } + + } +} + +def func() +{ + deep(); +} + +def doing() +{ + for (var i = 0; i < 10; ++i) + { + func(); + } +} + +def while_doing() +{ + while (true) + { + doing(); + } +} + +var f = fun() { while_doing(); } + +assert_equal(get_eval_error(f).call_stack.size(), 16) diff --git a/unittests/3.x/even.chai b/unittests/3.x/even.chai new file mode 100644 index 00000000..5a9a9aea --- /dev/null +++ b/unittests/3.x/even.chai @@ -0,0 +1 @@ +assert_equal(true, even(4)) diff --git a/unittests/3.x/exception.chai b/unittests/3.x/exception.chai new file mode 100644 index 00000000..50df6a80 --- /dev/null +++ b/unittests/3.x/exception.chai @@ -0,0 +1,9 @@ +var x = 1 +try { + throw(x) + x = 2 +} +catch(e) { + x = e + 3 +} +assert_equal(4, x); diff --git a/unittests/3.x/exception_finally.chai b/unittests/3.x/exception_finally.chai new file mode 100644 index 00000000..d6fd834a --- /dev/null +++ b/unittests/3.x/exception_finally.chai @@ -0,0 +1,32 @@ +var finallyone = false; + +try { + throw(3) +} +catch(x) { + assert_equal(3, x) +} +finally { + finallyone = true; +} + +assert_equal(true, finallyone); + +var try2 = false; +var catch2 = false; +var finally2 = false; + + +try { + try2 = true; +} +catch { + catch2 = true; +} +finally { + finally2 = true; +} + +assert_equal(true, try2); +assert_equal(false, catch2); +assert_equal(true, finally2); diff --git a/unittests/3.x/exception_guards.chai b/unittests/3.x/exception_guards.chai new file mode 100644 index 00000000..99cd9018 --- /dev/null +++ b/unittests/3.x/exception_guards.chai @@ -0,0 +1,34 @@ +var results = []; + +for (var i = 2; i < 6; ++i) { + try { + throw(i) + } + catch(e) : e < 2 { + results.push_back("c1: " + e.to_string()); + } + catch(e) : e < 4 { + results.push_back("c2: " + e.to_string()); + } + catch(e) { + results.push_back("c3: " + e.to_string()); + } + catch { + // Should never get called + assert_equal(false, true) + } +} + +try { + throw(3) +} +catch(e) : e < 3 +{ + // Should never get called + assert_equal(false, true); +} +catch { + results.push_back("defaultcatch"); +} + +assert_equal(["c2: 2", "c2: 3", "c3: 4", "c3: 5", "defaultcatch"], results); diff --git a/unittests/3.x/filter.chai b/unittests/3.x/filter.chai new file mode 100644 index 00000000..6d805fee --- /dev/null +++ b/unittests/3.x/filter.chai @@ -0,0 +1 @@ +assert_equal([1,3], filter([1, 2, 3, 4], odd)) diff --git a/unittests/3.x/float.chai b/unittests/3.x/float.chai new file mode 100644 index 00000000..b1bdf299 --- /dev/null +++ b/unittests/3.x/float.chai @@ -0,0 +1,7 @@ +assert_equal(true, 1.2 < 2) +assert_equal(true, 1.2 > 1) +assert_equal(1.2, 1.2) + +assert_equal(true, .5 > 0) +assert_equal(true, .5 < 1) +assert_equal(0.5, .5) diff --git a/unittests/3.x/foldl.chai b/unittests/3.x/foldl.chai new file mode 100644 index 00000000..7e9db51f --- /dev/null +++ b/unittests/3.x/foldl.chai @@ -0,0 +1 @@ +assert_equal(10, foldl([1, 2, 3, 4], `+`, 0)) diff --git a/unittests/3.x/for.chai b/unittests/3.x/for.chai new file mode 100644 index 00000000..9799be24 --- /dev/null +++ b/unittests/3.x/for.chai @@ -0,0 +1,7 @@ +var ret = [] + +for (var i = 0; i < 5; ++i) { + ret.push_back(i); +} + +assert_equal([0,1,2,3,4], ret); diff --git a/unittests/3.x/for_each.chai b/unittests/3.x/for_each.chai new file mode 100644 index 00000000..242a1baf --- /dev/null +++ b/unittests/3.x/for_each.chai @@ -0,0 +1 @@ +for_each([1, 2, 3], print) diff --git a/unittests/3.x/for_each_range.chai b/unittests/3.x/for_each_range.chai new file mode 100644 index 00000000..43191bfb --- /dev/null +++ b/unittests/3.x/for_each_range.chai @@ -0,0 +1,3 @@ +var v = [1,2,3]; +var r = range(v); +for_each(r, fun(x) { assert_equal(true, x>0); } ) diff --git a/unittests/3.x/for_each_retro.chai b/unittests/3.x/for_each_retro.chai new file mode 100644 index 00000000..cc27a580 --- /dev/null +++ b/unittests/3.x/for_each_retro.chai @@ -0,0 +1,4 @@ +// Don't bother checking the output from this one, just makes sure it executes +var v = [1,2,3]; +var r = retro(range(v)); +for_each(r, print) diff --git a/unittests/3.x/function_array_adjacent.chai b/unittests/3.x/function_array_adjacent.chai new file mode 100644 index 00000000..c34e2be9 --- /dev/null +++ b/unittests/3.x/function_array_adjacent.chai @@ -0,0 +1 @@ +assert_equal(2, `+`.get_contained_functions()[0].get_arity()) diff --git a/unittests/3.x/function_introspection.chai b/unittests/3.x/function_introspection.chai new file mode 100644 index 00000000..5ad76fc7 --- /dev/null +++ b/unittests/3.x/function_introspection.chai @@ -0,0 +1,76 @@ + +#Test Function Description +def test_function(a) +{ + return a; +} + + + + +// test_function tests +assert_equal(test_function.get_arity(), 1); +assert_equal(trim(test_function.get_annotation()), "#Test Function Description"); +assert_equal(test_function.get_contained_functions().size(), 0); +assert_equal(test_function.get_param_types().size(), 2); + +assert_equal(test_function, test_function); + +assert_not_equal(test_function, `+`); + +assert_equal(test_function.call([1]), 1); + +// dynamic object function tests + +def int::test_fun() +{ + return this; +} + +assert_equal(test_fun.get_arity(), 1); +assert_equal(test_fun.get_contained_functions.size(), 1); +assert_equal(test_fun.get_param_types().size(), 2); +assert_equal(test_fun, test_fun); +var test_fun_types = test_fun.get_param_types(); +assert_equal(true, test_fun_types[0].bare_equal(Object_type)); +assert_equal(true, test_fun_types[1].bare_equal(int_type)); + + +// built-ins tests + +assert_equal(2, `==`.get_arity()); + +// < should be the merging of two functions bool <(PODObject, PODObject) and bool <(string, string) +// we want to peel it apart and make sure that's true +var types = `<`.get_param_types(); +assert_equal(3, types.size()); +assert_equal(true, types[0].bare_equal(bool_type)); +assert_equal(true, types[1].bare_equal(Object_type)); +assert_equal(true, types[2].bare_equal(Object_type)); +assert_equal(2, `<`.get_contained_functions().size()); + + +// guard existence tests + +def with_guard(x) : x > 3 {} +def without_guard(x) {} + +def group_guard(x) {} +def group_guard(x) : x > 3 {} + +assert_equal(true, with_guard.has_guard()); +assert_equal(false, without_guard.has_guard()); + +assert_equal(2, group_guard.get_contained_functions().size()); +var group = group_guard.get_contained_functions(); + +assert_equal(true, group[0].has_guard()) +assert_equal(false, group[1].has_guard()) + +assert_throws("Function does not have a guard", fun() { group[0].get_guard(); } ); +assert_throws("Function does not have a guard", fun() { without_guard.get_guard(); } ); + +var guard = with_guard.get_guard(); + +assert_equal(false, guard.has_guard()); +assert_throws("Function does not have a guard", fun() { guard.get_guard(); } ); diff --git a/unittests/3.x/function_reassignment.chai b/unittests/3.x/function_reassignment.chai new file mode 100644 index 00000000..2a885fdc --- /dev/null +++ b/unittests/3.x/function_reassignment.chai @@ -0,0 +1,3 @@ +var x = `+` +x = `-` +assert_equal(1, x(5,4)) diff --git a/unittests/3.x/generate_range.chai b/unittests/3.x/generate_range.chai new file mode 100644 index 00000000..9e25970a --- /dev/null +++ b/unittests/3.x/generate_range.chai @@ -0,0 +1 @@ +assert_equal([1,2,3,4,5,6,7,8,9,10], generate_range(1, 10)) diff --git a/unittests/3.x/global_const_in_module.chai b/unittests/3.x/global_const_in_module.chai new file mode 100644 index 00000000..c9ca65a6 --- /dev/null +++ b/unittests/3.x/global_const_in_module.chai @@ -0,0 +1,7 @@ +load_module("test_module") + + +assert_equal(to_int(TestValue1), 1) + +assert_equal(TestValue1.type_name(), "TestEnum") + diff --git a/unittests/3.x/if.chai b/unittests/3.x/if.chai new file mode 100644 index 00000000..3ec7321b --- /dev/null +++ b/unittests/3.x/if.chai @@ -0,0 +1,7 @@ +var t = false; + +if (true) { + t = true; +} + +assert_equal(true, t); diff --git a/unittests/3.x/if_else.chai b/unittests/3.x/if_else.chai new file mode 100644 index 00000000..8cb42db9 --- /dev/null +++ b/unittests/3.x/if_else.chai @@ -0,0 +1,13 @@ +var i = 3 +var b1 = false; +var b2 = false; + +if (i == 2) { + b1 = true; +} +else { + b2 = true; +} + +assert_equal(false, b1); +assert_equal(true, b2); diff --git a/unittests/3.x/if_elseif.chai b/unittests/3.x/if_elseif.chai new file mode 100644 index 00000000..75b85b5f --- /dev/null +++ b/unittests/3.x/if_elseif.chai @@ -0,0 +1,18 @@ +var b1 = false; +var b2 = false; +var b3 = false; + +var i = 3 +if (i == 2) { + b1 = true; +} +else if (i == 4) { + b2 = true; +} +else if (i == 3) { + b3 = true; +} + +assert_equal(false, b1); +assert_equal(false, b2); +assert_equal(true, b3); diff --git a/unittests/3.x/if_elseif_else.chai b/unittests/3.x/if_elseif_else.chai new file mode 100644 index 00000000..26ed0d26 --- /dev/null +++ b/unittests/3.x/if_elseif_else.chai @@ -0,0 +1,14 @@ +var i = 3 +var b = false +if (i == 2) { + assert_equal(false, true) +} +else if (i == 4) { + assert_equal(false, true) +} +else { + assert_equal(true, true) + b = true +} + +assert_equal(true, b) diff --git a/unittests/3.x/index_operator.chai b/unittests/3.x/index_operator.chai new file mode 100644 index 00000000..e8af5cf6 --- /dev/null +++ b/unittests/3.x/index_operator.chai @@ -0,0 +1,10 @@ + +// tests more complex parses of the index operator + +def Bob::bob3() { return [1,2,3]; } +def Bob::Bob() {} +var b = Bob(); + + +assert_equal(b.bob3()[0], 1); +assert_equal((b.bob3())[1], 2); diff --git a/unittests/3.x/inheritance.chai b/unittests/3.x/inheritance.chai new file mode 100644 index 00000000..1fcd346b --- /dev/null +++ b/unittests/3.x/inheritance.chai @@ -0,0 +1,8 @@ +load_module("test_module") + +var t0 = TestBaseType() +var t = TestDerivedType(); + +assert_equal(t0.func(), 0); +assert_equal(t.func(), 1); + diff --git a/unittests/3.x/instring_eval.chai b/unittests/3.x/instring_eval.chai new file mode 100644 index 00000000..a72b2fc4 --- /dev/null +++ b/unittests/3.x/instring_eval.chai @@ -0,0 +1,3 @@ +var bob = 5.5 +assert_equal("5.5", "${bob}") +assert_equal("val: 8 and 8", "val: ${5.5 + 2.5} and ${bob + 2.5}") diff --git a/unittests/3.x/instring_eval_more.chai b/unittests/3.x/instring_eval_more.chai new file mode 100644 index 00000000..17768f82 --- /dev/null +++ b/unittests/3.x/instring_eval_more.chai @@ -0,0 +1,4 @@ +assert_equal("\$ {4 + 5}", "$ {4 + 5}") +assert_equal("\$9", "$${4+5}") +assert_equal("Value: \${4 + 5}", "Value: \${4 + 5}") +assert_equal("Value: \$9", "Value: \$${4 + 5}") diff --git a/unittests/3.x/invalid_function_assignment.chai b/unittests/3.x/invalid_function_assignment.chai new file mode 100644 index 00000000..99b098db --- /dev/null +++ b/unittests/3.x/invalid_function_assignment.chai @@ -0,0 +1 @@ +assert_throws("Illegal const function assignment", fun() { clone = `-` } ); diff --git a/unittests/3.x/invalid_function_reassignment.chai b/unittests/3.x/invalid_function_reassignment.chai new file mode 100644 index 00000000..cc7cb5af --- /dev/null +++ b/unittests/3.x/invalid_function_reassignment.chai @@ -0,0 +1 @@ +assert_throws("Invalid function reassignment", fun() { var x = 5; x = `-`; } ); diff --git a/unittests/3.x/is_undef.chai b/unittests/3.x/is_undef.chai new file mode 100644 index 00000000..38572f0f --- /dev/null +++ b/unittests/3.x/is_undef.chai @@ -0,0 +1,4 @@ +var i; +assert_equal(true, i.is_var_undef()); +i = 5; +assert_equal(false, i.is_var_undef()); diff --git a/unittests/3.x/join.chai b/unittests/3.x/join.chai new file mode 100644 index 00000000..1891c468 --- /dev/null +++ b/unittests/3.x/join.chai @@ -0,0 +1 @@ +assert_equal("1*2*3", join([1, 2, 3], "*")) diff --git a/unittests/3.x/lambda.chai b/unittests/3.x/lambda.chai new file mode 100644 index 00000000..6b65a1ba --- /dev/null +++ b/unittests/3.x/lambda.chai @@ -0,0 +1,2 @@ +var bob = fun(x) { x + 1 } +assert_equal(4, bob(3)); diff --git a/unittests/3.x/list_push_back.chai b/unittests/3.x/list_push_back.chai new file mode 100644 index 00000000..4d88deb8 --- /dev/null +++ b/unittests/3.x/list_push_back.chai @@ -0,0 +1,8 @@ +load_module("stl_extra") + +var x = List() +x.push_back(3) +x.push_back("A") + +assert_equal(3, x.front()); +assert_equal("A", x.back()); diff --git a/unittests/3.x/list_push_front.chai b/unittests/3.x/list_push_front.chai new file mode 100644 index 00000000..86e28329 --- /dev/null +++ b/unittests/3.x/list_push_front.chai @@ -0,0 +1,8 @@ +load_module("stl_extra") + +var x = List() +x.push_front(3) +x.push_front("A") + +assert_equal("A", x.front()); +assert_equal(3, x.back()); diff --git a/unittests/3.x/load_module.chai b/unittests/3.x/load_module.chai new file mode 100644 index 00000000..a231a200 --- /dev/null +++ b/unittests/3.x/load_module.chai @@ -0,0 +1,2 @@ +load_module("test_module") +assert_equal("Hello World", hello_world()); diff --git a/unittests/3.x/loop_inner_outer.chai b/unittests/3.x/loop_inner_outer.chai new file mode 100644 index 00000000..64a25e6e --- /dev/null +++ b/unittests/3.x/loop_inner_outer.chai @@ -0,0 +1,9 @@ +var total = 0 + +for (var i = 0; i < 10; ++i) { + for (var j = 0; j < 10; ++j) { + total += 1 + } +} + +assert_equal(100, total); diff --git a/unittests/3.x/malformed_inline_map.chai b/unittests/3.x/malformed_inline_map.chai new file mode 100644 index 00000000..d267bcfe --- /dev/null +++ b/unittests/3.x/malformed_inline_map.chai @@ -0,0 +1,2 @@ + +assert_throws("Parse failure", fun() { eval("[\"hello\":5,\"j\",\"k\"]") } ); diff --git a/unittests/3.x/map.chai b/unittests/3.x/map.chai new file mode 100644 index 00000000..a0a31ee1 --- /dev/null +++ b/unittests/3.x/map.chai @@ -0,0 +1 @@ +assert_equal([true, false, true], map([1,2,3], odd)) diff --git a/unittests/3.x/map_access.chai b/unittests/3.x/map_access.chai new file mode 100644 index 00000000..19ebc1ad --- /dev/null +++ b/unittests/3.x/map_access.chai @@ -0,0 +1,2 @@ +var x = ["bob":2, "fred":3] +assert_equal(3, x["fred"]) diff --git a/unittests/3.x/map_inplace_init.chai b/unittests/3.x/map_inplace_init.chai new file mode 100644 index 00000000..b1d8221b --- /dev/null +++ b/unittests/3.x/map_inplace_init.chai @@ -0,0 +1,3 @@ +var x = ["bob":1, "fred":2] + +assert_equal(2, x.size()); diff --git a/unittests/3.x/math_add.chai b/unittests/3.x/math_add.chai new file mode 100644 index 00000000..bcb90369 --- /dev/null +++ b/unittests/3.x/math_add.chai @@ -0,0 +1 @@ +assert_equal(3, (1 + 2)) diff --git a/unittests/3.x/math_add_mixed.chai b/unittests/3.x/math_add_mixed.chai new file mode 100644 index 00000000..b000cafe --- /dev/null +++ b/unittests/3.x/math_add_mixed.chai @@ -0,0 +1 @@ +assert_equal(3.5, 1.5 + 2) diff --git a/unittests/3.x/math_dec.chai b/unittests/3.x/math_dec.chai new file mode 100644 index 00000000..e746f298 --- /dev/null +++ b/unittests/3.x/math_dec.chai @@ -0,0 +1,3 @@ +var i = 3 +assert_equal(2, --i) +assert_equal(2, i) diff --git a/unittests/3.x/math_div.chai b/unittests/3.x/math_div.chai new file mode 100644 index 00000000..971f2170 --- /dev/null +++ b/unittests/3.x/math_div.chai @@ -0,0 +1 @@ +assert_equal(2, 10/5) diff --git a/unittests/3.x/math_inc.chai b/unittests/3.x/math_inc.chai new file mode 100644 index 00000000..ec317c03 --- /dev/null +++ b/unittests/3.x/math_inc.chai @@ -0,0 +1,3 @@ +var i = 3 +assert_equal(4, ++i) +assert_equal(4, i) diff --git a/unittests/3.x/math_mod.chai b/unittests/3.x/math_mod.chai new file mode 100644 index 00000000..326c35a9 --- /dev/null +++ b/unittests/3.x/math_mod.chai @@ -0,0 +1 @@ +assert_equal(2, 11 % 3) diff --git a/unittests/3.x/math_mult.chai b/unittests/3.x/math_mult.chai new file mode 100644 index 00000000..94c355d6 --- /dev/null +++ b/unittests/3.x/math_mult.chai @@ -0,0 +1 @@ +assert_equal(12, 3 * 4) diff --git a/unittests/3.x/math_negate.chai b/unittests/3.x/math_negate.chai new file mode 100644 index 00000000..36bae880 --- /dev/null +++ b/unittests/3.x/math_negate.chai @@ -0,0 +1 @@ +assert_equal(-7, -(3 + 4)) diff --git a/unittests/3.x/math_paren.chai b/unittests/3.x/math_paren.chai new file mode 100644 index 00000000..01b7f205 --- /dev/null +++ b/unittests/3.x/math_paren.chai @@ -0,0 +1 @@ +assert_equal(27, 3*(4+5)) diff --git a/unittests/3.x/math_sub.chai b/unittests/3.x/math_sub.chai new file mode 100644 index 00000000..7e8342c1 --- /dev/null +++ b/unittests/3.x/math_sub.chai @@ -0,0 +1 @@ +assert_equal(2, 5 - 3) diff --git a/unittests/3.x/max.chai b/unittests/3.x/max.chai new file mode 100644 index 00000000..533e7e84 --- /dev/null +++ b/unittests/3.x/max.chai @@ -0,0 +1 @@ +assert_equal(5, max(3, 5)) diff --git a/unittests/3.x/memberscope.chai b/unittests/3.x/memberscope.chai new file mode 100644 index 00000000..fe46810a --- /dev/null +++ b/unittests/3.x/memberscope.chai @@ -0,0 +1,12 @@ +attr Vector3::x +attr Vector3::y +attr Vector3::z + +def Vector3::Vector3(x, y, z) { + this.x = x + this.y = y + this.z = z +} + +var v = Vector3(1,2,3); +assert_equal(1, v.x); diff --git a/unittests/3.x/method_sugar.chai b/unittests/3.x/method_sugar.chai new file mode 100644 index 00000000..521400bc --- /dev/null +++ b/unittests/3.x/method_sugar.chai @@ -0,0 +1 @@ +assert_equal(6, [1, 2, 3].sum()) diff --git a/unittests/3.x/min.chai b/unittests/3.x/min.chai new file mode 100644 index 00000000..0ef1ba79 --- /dev/null +++ b/unittests/3.x/min.chai @@ -0,0 +1 @@ +assert_equal(3, min(3, 5)) diff --git a/unittests/3.x/mmd1.chai b/unittests/3.x/mmd1.chai new file mode 100644 index 00000000..ff38a3c5 --- /dev/null +++ b/unittests/3.x/mmd1.chai @@ -0,0 +1,20 @@ +def bob(x, y, z) { + x + y + z +} + +def bob(x, y) { + x - y +} + +def bob(x) { + -x +} + +def bob() { + 10 +} + +assert_equal(10, bob()) +assert_equal(-5, bob(5)) +assert_equal(-1, bob(5,6)) +assert_equal(18, bob(5,6,7)) diff --git a/unittests/3.x/mmd2.chai b/unittests/3.x/mmd2.chai new file mode 100644 index 00000000..1c5f1771 --- /dev/null +++ b/unittests/3.x/mmd2.chai @@ -0,0 +1,9 @@ +def bob(x, y) : x > 10 { x - y } + +def bob(x, y) : x > 5 { x - y + 10 } + +def bob(x, y) { x + y } + +assert_equal(7, bob(3,4)) +assert_equal(9, bob(6,7)) +assert_equal(-1, bob(11,12)) diff --git a/unittests/3.x/multiline.chai b/unittests/3.x/multiline.chai new file mode 100644 index 00000000..f13be4e6 --- /dev/null +++ b/unittests/3.x/multiline.chai @@ -0,0 +1,9 @@ +var x = [1, 2, + 3, 4] + +assert_equal(1, x[0]) + +var y = map(x, + fun(x) { x + 1 }) + +assert_equal(2, y[0]) diff --git a/unittests/3.x/number_formats.chai b/unittests/3.x/number_formats.chai new file mode 100644 index 00000000..c80ece04 --- /dev/null +++ b/unittests/3.x/number_formats.chai @@ -0,0 +1,3 @@ +assert_equal(10, 012) +assert_equal(31, 0x1f) +assert_equal(3, 0b11) diff --git a/unittests/3.x/object_attr.chai b/unittests/3.x/object_attr.chai new file mode 100644 index 00000000..c2da08ea --- /dev/null +++ b/unittests/3.x/object_attr.chai @@ -0,0 +1,6 @@ +attr bob::z +def bob::bob() { this.z = 10 } +var x = bob() +def bob::fred(x) { this.z - x } + +assert_equal(7, x.fred(3)) diff --git a/unittests/3.x/object_attr_same_name.chai b/unittests/3.x/object_attr_same_name.chai new file mode 100644 index 00000000..fa20bac4 --- /dev/null +++ b/unittests/3.x/object_attr_same_name.chai @@ -0,0 +1,9 @@ +attr bob::z +def bob::bob() { this.z = 10 } + +attr bob2::z +def bob2::bob2() { this.z = 12 } + +var b = bob(); +var b2 = bob2(); + diff --git a/unittests/3.x/object_clone.chai b/unittests/3.x/object_clone.chai new file mode 100644 index 00000000..4659f41a --- /dev/null +++ b/unittests/3.x/object_clone.chai @@ -0,0 +1,11 @@ +attr bob::z +def bob::bob() { } + +var x = bob(); +x.z = 10; + +var y = clone(x); +y.z = 20; + +assert_equal(10, x.z) +assert_equal(20, y.z) diff --git a/unittests/3.x/object_constructor_guards.chai b/unittests/3.x/object_constructor_guards.chai new file mode 100644 index 00000000..f48c00a1 --- /dev/null +++ b/unittests/3.x/object_constructor_guards.chai @@ -0,0 +1,10 @@ +attr bob::val + +def bob::bob(x) : x < 10 { this.val = "Less Than Ten: " + x.to_string(); } +def bob::bob(x) { this.val = "Any Other Value: " + x.to_string(); } + +var b = bob(12) +var c = bob(3) + +assert_equal("Any Other Value: 12", b.val ) +assert_equal("Less Than Ten: 3", c.val ) diff --git a/unittests/3.x/object_method_guards.chai b/unittests/3.x/object_method_guards.chai new file mode 100644 index 00000000..addc8508 --- /dev/null +++ b/unittests/3.x/object_method_guards.chai @@ -0,0 +1,7 @@ +def bob::bob() { } +def bob::fred(e) : e < 10 { assert_equal(true, e<10) } +def bob::fred(e) { assert_equal(true, e >= 10) } + +var b = bob() +b.fred(3) +b.fred(12) diff --git a/unittests/3.x/odd.chai b/unittests/3.x/odd.chai new file mode 100644 index 00000000..dbaf2a01 --- /dev/null +++ b/unittests/3.x/odd.chai @@ -0,0 +1 @@ +assert_equal(false, odd(4)) diff --git a/unittests/3.x/operator_overload.chai b/unittests/3.x/operator_overload.chai new file mode 100644 index 00000000..9bd2eb79 --- /dev/null +++ b/unittests/3.x/operator_overload.chai @@ -0,0 +1,9 @@ +def Bob::`+`(y) { this.x + y.x } +def Bob::Bob() { } +attr Bob::x +var b = Bob() +var c = Bob() +b.x = 4 +c.x = 5 + +assert_equal(9, b+c) diff --git a/unittests/3.x/operator_overload2.chai b/unittests/3.x/operator_overload2.chai new file mode 100644 index 00000000..b4afbe7b --- /dev/null +++ b/unittests/3.x/operator_overload2.chai @@ -0,0 +1,9 @@ +def Bob::Bob() { } +attr Bob::x +def `-`(a, b) : is_type(a, "Bob") && is_type(b, "Bob") { a.x - b.x } +var b = Bob() +var c = Bob() +b.x = 4 +c.x = 5 + +assert_equal(-1, b-c) diff --git a/unittests/3.x/operators_float.chai b/unittests/3.x/operators_float.chai new file mode 100644 index 00000000..931606fb --- /dev/null +++ b/unittests/3.x/operators_float.chai @@ -0,0 +1,16 @@ +var i = 1.0; +var j = 2.0; +var k = 3.0; + +assert_equal(3, i + j) +assert_equal(1.0, +i) +assert_equal(-1, i-j) +assert_equal(-1, -i) +assert_equal(1.5, k/j) +assert_equal(6, j*k) + +assert_equal(0, i -= i) +assert_equal(3, j *= 1.5) +assert_equal(1.5, j /= 2) +assert_equal(2.5, j += 1) +assert_throws("No modulus for float", fun() { k % 2 } ); diff --git a/unittests/3.x/operators_int.chai b/unittests/3.x/operators_int.chai new file mode 100644 index 00000000..4627b552 --- /dev/null +++ b/unittests/3.x/operators_int.chai @@ -0,0 +1,31 @@ +var i = 1; +var j = 2; +var k = 3; + +assert_equal(3, i + j); +assert_equal(1, +i); +assert_equal(-1, i - j); +assert_equal(-1, -i); +assert_equal(2, j & k); +assert_equal(-3, ~j); +assert_equal(1, j ^ k); +assert_equal(3, i | j); +assert_equal(2, j / i); +assert_equal(4, i << j); +assert_equal(6, j * k); +assert_equal(1, k % j); +assert_equal(1, j >> i); + +assert_equal(0, i &= 2); +assert_equal(1, j ^= 3); +assert_equal(3, j |= 2); +assert_equal(-1, i -= 1); +assert_equal(6, j <<= 1); +assert_equal(12, j *= 2); +assert_equal(6, j /= 2); +assert_equal(2, j %= 4); +assert_equal(1, j >>= 1); +assert_equal(2, j += 1); +assert_equal(1, --j); +assert_equal(2, ++j); + diff --git a/unittests/3.x/pair.chai b/unittests/3.x/pair.chai new file mode 100644 index 00000000..9b3c8049 --- /dev/null +++ b/unittests/3.x/pair.chai @@ -0,0 +1,5 @@ +var p = Pair("Hello", "World") + +assert_equal(p.first, "Hello") +assert_equal(p.second, "World") + diff --git a/unittests/3.x/pointer_passed_to_constructor.chai b/unittests/3.x/pointer_passed_to_constructor.chai new file mode 100644 index 00000000..6495ee38 --- /dev/null +++ b/unittests/3.x/pointer_passed_to_constructor.chai @@ -0,0 +1,8 @@ +load_module("test_module") + +var i = 1; +var t0 = TestBaseType(i); + +var t1 = TestBaseType(get_new_int()) + + diff --git a/unittests/3.x/precedence_1.chai b/unittests/3.x/precedence_1.chai new file mode 100644 index 00000000..a5388625 --- /dev/null +++ b/unittests/3.x/precedence_1.chai @@ -0,0 +1 @@ +assert_equal(14, 2 + 3 * 4) diff --git a/unittests/3.x/precedence_2.chai b/unittests/3.x/precedence_2.chai new file mode 100644 index 00000000..27a19d4a --- /dev/null +++ b/unittests/3.x/precedence_2.chai @@ -0,0 +1 @@ +assert_equal(-2, 5 - 4 - 3) diff --git a/unittests/3.x/precedence_3.chai b/unittests/3.x/precedence_3.chai new file mode 100644 index 00000000..6eecbf64 --- /dev/null +++ b/unittests/3.x/precedence_3.chai @@ -0,0 +1 @@ +assert_equal(0, 10 / 5 % 2) diff --git a/unittests/3.x/precedence_eq.chai b/unittests/3.x/precedence_eq.chai new file mode 100644 index 00000000..325d667e --- /dev/null +++ b/unittests/3.x/precedence_eq.chai @@ -0,0 +1,3 @@ +var x = var y = 4 +assert_equal(4, x); +assert_equal(4, y); diff --git a/unittests/3.x/product.chai b/unittests/3.x/product.chai new file mode 100644 index 00000000..03ba3cfa --- /dev/null +++ b/unittests/3.x/product.chai @@ -0,0 +1 @@ +assert_equal(24, product([1, 2, 3, 4])) diff --git a/unittests/3.x/range.chai b/unittests/3.x/range.chai new file mode 100644 index 00000000..ddef4f2a --- /dev/null +++ b/unittests/3.x/range.chai @@ -0,0 +1,4 @@ +var x = [1, 2, 3, 4] +var r = range(x) +r.pop_front() +assert_equal(2, r.front()); diff --git a/unittests/3.x/range_back.chai b/unittests/3.x/range_back.chai new file mode 100644 index 00000000..6bf56721 --- /dev/null +++ b/unittests/3.x/range_back.chai @@ -0,0 +1,4 @@ +var x = [1, 2, 3, 4] +var r = range(x) +r.pop_back() +assert_equal(3, r.back()) diff --git a/unittests/3.x/range_contains.chai b/unittests/3.x/range_contains.chai new file mode 100644 index 00000000..28a99b12 --- /dev/null +++ b/unittests/3.x/range_contains.chai @@ -0,0 +1,5 @@ +var v = [1,2,"hi", "world", 5.5] +assert_equal(true, v.contains(5.5)) +assert_equal(false, v.contains(0)) +assert_equal(false, v.contains(1, lt)) +assert_equal(true, v.contains(2, `==`)) diff --git a/unittests/3.x/range_find.chai b/unittests/3.x/range_find.chai new file mode 100644 index 00000000..08045e5a --- /dev/null +++ b/unittests/3.x/range_find.chai @@ -0,0 +1,6 @@ +var v = [2, 1, "Hi", 5.5] +var r = v.find("Hi"); + +assert_equal("Hi", r.front()) +var r2 = v.find(2, `<`); +assert_equal(1, r2.front()); diff --git a/unittests/3.x/range_inplace.chai b/unittests/3.x/range_inplace.chai new file mode 100644 index 00000000..d661f5de --- /dev/null +++ b/unittests/3.x/range_inplace.chai @@ -0,0 +1 @@ +assert_equal([3,4,5,6], [3..6]) diff --git a/unittests/3.x/reduce.chai b/unittests/3.x/reduce.chai new file mode 100644 index 00000000..3b255b31 --- /dev/null +++ b/unittests/3.x/reduce.chai @@ -0,0 +1 @@ +assert_equal(10, reduce([1, 2, 3, 4], `+`)) diff --git a/unittests/ref_equal.chai b/unittests/3.x/ref_equal.chai similarity index 100% rename from unittests/ref_equal.chai rename to unittests/3.x/ref_equal.chai diff --git a/unittests/3.x/reflection_test.chai b/unittests/3.x/reflection_test.chai new file mode 100644 index 00000000..88b39ccc --- /dev/null +++ b/unittests/3.x/reflection_test.chai @@ -0,0 +1,37 @@ +load_module("reflection") +var parser := ChaiScript_Parser() +var parse_success = parser.parse("3 + 4", "INPUT") +var a := parser.ast() + +assert_equal(eval(a), 7) + +var childs := a.children.front().children +var node := childs[0] + +var parser2 := ChaiScript_Parser() +parser2.parse("9", "INPUT") + + +a.children.front().replace_child(childs[0], parser2.ast()) + +assert_equal(eval(a), 13) +assert_equal(node.filename, "INPUT") + + + +def my_fun() +{ + return 1; +} + + +assert_equal(true, my_fun.has_parse_tree()); +assert_equal(false, `+`.has_parse_tree()); + +assert_throws("Function does not have a parse tree", fun() { `+`.get_parse_tree(); } ); + +var parsetree := my_fun.get_parse_tree(); + +assert_equal(1, eval(parsetree)); + +print(parsetree.text()); diff --git a/unittests/3.x/retro.chai b/unittests/3.x/retro.chai new file mode 100644 index 00000000..d7f6818d --- /dev/null +++ b/unittests/3.x/retro.chai @@ -0,0 +1,4 @@ +var x = [1, 2, 3, 4] +var r = retro(range(x)) +r.pop_front() +assert_equal(3, r.front()) diff --git a/unittests/3.x/retroretro.chai b/unittests/3.x/retroretro.chai new file mode 100644 index 00000000..09af3ca7 --- /dev/null +++ b/unittests/3.x/retroretro.chai @@ -0,0 +1,7 @@ +var x = [1, 2, 3, 4] +var r = retro(range(x)) +r.pop_back() +var r2 = retro(r) +r2.pop_front() +assert_equal(2, r.back()) +assert_equal(3, r2.front()) diff --git a/unittests/3.x/return.chai b/unittests/3.x/return.chai new file mode 100644 index 00000000..512f52fc --- /dev/null +++ b/unittests/3.x/return.chai @@ -0,0 +1,5 @@ +def sam() { + return 5 +} + +assert_equal(5, sam()) diff --git a/unittests/3.x/runtime_error.chai b/unittests/3.x/runtime_error.chai new file mode 100644 index 00000000..e1e2fc10 --- /dev/null +++ b/unittests/3.x/runtime_error.chai @@ -0,0 +1,11 @@ +var caught = false + +try { + throw(runtime_error("error")) +} +catch(e) { + caught = true + assert_equal("error", e.what()) +} + +assert_equal(true, caught) diff --git a/unittests/3.x/shift.chai b/unittests/3.x/shift.chai new file mode 100644 index 00000000..03f7ea3a --- /dev/null +++ b/unittests/3.x/shift.chai @@ -0,0 +1 @@ +assert_equal(8, 2 << 2) diff --git a/unittests/3.x/string_charptr.chai b/unittests/3.x/string_charptr.chai new file mode 100644 index 00000000..a3065ce4 --- /dev/null +++ b/unittests/3.x/string_charptr.chai @@ -0,0 +1,6 @@ +assert_equal(true, "hello".c_str().is_var_const()) +assert_equal("char", "hello".c_str().type_name()) + +assert_equal(true, "hello".data().is_var_const()) +assert_equal("char", "hello".data().type_name()) + diff --git a/unittests/3.x/string_concat.chai b/unittests/3.x/string_concat.chai new file mode 100644 index 00000000..40bf4aaf --- /dev/null +++ b/unittests/3.x/string_concat.chai @@ -0,0 +1 @@ +assert_equal("hello, there", "hello, " + "there") diff --git a/unittests/3.x/string_find.chai b/unittests/3.x/string_find.chai new file mode 100644 index 00000000..f2cc1f82 --- /dev/null +++ b/unittests/3.x/string_find.chai @@ -0,0 +1 @@ +assert_equal(3, find("123abab", "ab")) diff --git a/unittests/3.x/string_find_first_not_of.chai b/unittests/3.x/string_find_first_not_of.chai new file mode 100644 index 00000000..4d5fd8d4 --- /dev/null +++ b/unittests/3.x/string_find_first_not_of.chai @@ -0,0 +1 @@ +assert_equal(2, find_first_not_of("abcd", "abd")) diff --git a/unittests/3.x/string_find_first_of.chai b/unittests/3.x/string_find_first_of.chai new file mode 100644 index 00000000..0200bb2c --- /dev/null +++ b/unittests/3.x/string_find_first_of.chai @@ -0,0 +1 @@ +assert_equal(1, find_first_of("abab", "bec")) diff --git a/unittests/3.x/string_find_last_not_of.chai b/unittests/3.x/string_find_last_not_of.chai new file mode 100644 index 00000000..0090f9f9 --- /dev/null +++ b/unittests/3.x/string_find_last_not_of.chai @@ -0,0 +1 @@ +assert_equal(3, find_last_not_of("abab", "ac")) diff --git a/unittests/3.x/string_find_last_of.chai b/unittests/3.x/string_find_last_of.chai new file mode 100644 index 00000000..72f0f6a0 --- /dev/null +++ b/unittests/3.x/string_find_last_of.chai @@ -0,0 +1 @@ +assert_equal(3, find_last_of("abab", "bec")) diff --git a/unittests/3.x/string_init.chai b/unittests/3.x/string_init.chai new file mode 100644 index 00000000..a3d11632 --- /dev/null +++ b/unittests/3.x/string_init.chai @@ -0,0 +1 @@ +print("bob") diff --git a/unittests/3.x/string_literal_access.chai b/unittests/3.x/string_literal_access.chai new file mode 100644 index 00000000..e8943a1b --- /dev/null +++ b/unittests/3.x/string_literal_access.chai @@ -0,0 +1 @@ +assert_equal('b', "abc"[1]) diff --git a/unittests/3.x/string_rfind.chai b/unittests/3.x/string_rfind.chai new file mode 100644 index 00000000..01675f34 --- /dev/null +++ b/unittests/3.x/string_rfind.chai @@ -0,0 +1 @@ +assert_equal(5, rfind("123abab", "ab")) diff --git a/unittests/3.x/sum.chai b/unittests/3.x/sum.chai new file mode 100644 index 00000000..7502ae7e --- /dev/null +++ b/unittests/3.x/sum.chai @@ -0,0 +1 @@ +assert_equal(10, sum([1, 2, 3, 4])) diff --git a/unittests/3.x/switch_break.chai b/unittests/3.x/switch_break.chai new file mode 100644 index 00000000..8d362759 --- /dev/null +++ b/unittests/3.x/switch_break.chai @@ -0,0 +1,22 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + break; + } + case (2) { + total += 2; + break; + } + case (3) { + total += 4; + break; + } + case (4) { + total += 8; + break; + } +} + +assert_equal(total, 2) diff --git a/unittests/3.x/switch_default.chai b/unittests/3.x/switch_default.chai new file mode 100644 index 00000000..8c48aa50 --- /dev/null +++ b/unittests/3.x/switch_default.chai @@ -0,0 +1,18 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + } + case (3) { + total += 4; + } + case (4) { + total += 8; + } + default { + total += 16; + } +} + +assert_equal(total, 16) diff --git a/unittests/3.x/switch_empty.chai b/unittests/3.x/switch_empty.chai new file mode 100644 index 00000000..8d3a1669 --- /dev/null +++ b/unittests/3.x/switch_empty.chai @@ -0,0 +1,4 @@ +switch(true) { } + +// We just have to get here without error for success +assert_equal(true, true); diff --git a/unittests/3.x/switch_fallthru.chai b/unittests/3.x/switch_fallthru.chai new file mode 100644 index 00000000..627b6493 --- /dev/null +++ b/unittests/3.x/switch_fallthru.chai @@ -0,0 +1,18 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + } + case (2) { + total += 2; + } + case (3) { + total += 4; + } + case (4) { + total += 8; + } +} + +assert_equal(total, 14); diff --git a/unittests/3.x/switch_fallthru_and_break.chai b/unittests/3.x/switch_fallthru_and_break.chai new file mode 100644 index 00000000..3c93071b --- /dev/null +++ b/unittests/3.x/switch_fallthru_and_break.chai @@ -0,0 +1,19 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + } + case (2) { + total += 2; + } + case (3) { + total += 4; + break; + } + case (4) { + total += 8; + } +} + +assert_equal(total, 6) diff --git a/unittests/3.x/take.chai b/unittests/3.x/take.chai new file mode 100644 index 00000000..5110392e --- /dev/null +++ b/unittests/3.x/take.chai @@ -0,0 +1 @@ +assert_equal(2, take([1, 2, 3, 4], 2).back()) diff --git a/unittests/3.x/take_while.chai b/unittests/3.x/take_while.chai new file mode 100644 index 00000000..56a4ba22 --- /dev/null +++ b/unittests/3.x/take_while.chai @@ -0,0 +1 @@ +assert_equal([1], take_while([1, 2, 3, 4], odd)) diff --git a/unittests/3.x/type_info.chai b/unittests/3.x/type_info.chai new file mode 100644 index 00000000..fc2dd3e7 --- /dev/null +++ b/unittests/3.x/type_info.chai @@ -0,0 +1,11 @@ +assert_equal("string", string_type.name()); +assert_equal(false, string_type.is_type_const()); +assert_equal(false, string_type.is_type_reference()); +assert_equal(false, string_type.is_type_void()); +assert_equal(false, string_type.is_type_undef()); +assert_equal(false, string_type.is_type_pointer()); +assert_equal("string", "string".get_type_info().name()); +assert_equal(true, string_type.bare_equal("string".get_type_info())); + +assert_equal(true, "bob".is_type(string_type)); + diff --git a/unittests/3.x/unit_test.inc b/unittests/3.x/unit_test.inc new file mode 100644 index 00000000..d746e7bf --- /dev/null +++ b/unittests/3.x/unit_test.inc @@ -0,0 +1,53 @@ +def assert_equal(x, y) +{ + if (x == y) + { + // Passes + } else { + // Fails + print("assert_equal failure: got " + to_string(y) + " expected " + to_string(x)); + exit(-1); + } +} + +def assert_false(f) +{ + if (f) + { + print("assert_false failure"); + exit(-1); + } +} + +def assert_true(f) +{ + if (!f) + { + print("assert_false failure"); + exit(-1); + } +} + +def assert_not_equal(x, y) +{ + if (!(x == y)) + { + // Passes + } else { + // Fails + print("assert_not_equal failure: got " + to_string(y) + " which was not expected."); + exit(-1); + } +} + +def assert_throws(desc, x) +{ + if (throws_exception(x)) + { + // Passes + } else { + // Fails + print("assert_throws failure, function did not throw exception: " + to_string(desc)); + exit(-1); + } +} diff --git a/unittests/3.x/use.chai b/unittests/3.x/use.chai new file mode 100644 index 00000000..efd587da --- /dev/null +++ b/unittests/3.x/use.chai @@ -0,0 +1,9 @@ +use("use.inc") + +assert_equal("hello", greet()) + +// Include it a second time and see if there are any errors +use("use.inc") + +assert_equal("hello", greet()) + diff --git a/unittests/3.x/use.inc b/unittests/3.x/use.inc new file mode 100644 index 00000000..204cec40 --- /dev/null +++ b/unittests/3.x/use.inc @@ -0,0 +1,4 @@ +def greet { + return("hello") +} + diff --git a/unittests/3.x/vector_access.chai b/unittests/3.x/vector_access.chai new file mode 100644 index 00000000..34d483cd --- /dev/null +++ b/unittests/3.x/vector_access.chai @@ -0,0 +1,2 @@ +var x = [1, 2, 3] +assert_equal(3, x[2]) diff --git a/unittests/3.x/vector_erase_at.chai b/unittests/3.x/vector_erase_at.chai new file mode 100644 index 00000000..9a96218f --- /dev/null +++ b/unittests/3.x/vector_erase_at.chai @@ -0,0 +1,3 @@ +var x = [1, 2, 3] +x.erase_at(1) +assert_equal([1,3], x); diff --git a/unittests/3.x/vector_inplace_init.chai b/unittests/3.x/vector_inplace_init.chai new file mode 100644 index 00000000..f16c15b3 --- /dev/null +++ b/unittests/3.x/vector_inplace_init.chai @@ -0,0 +1,2 @@ +var x = [1, 2, 3] +assert_equal(3, x.size()) diff --git a/unittests/3.x/vector_insert_at.chai b/unittests/3.x/vector_insert_at.chai new file mode 100644 index 00000000..4f6ec45b --- /dev/null +++ b/unittests/3.x/vector_insert_at.chai @@ -0,0 +1,3 @@ +var x = [1, 2, 3] +x.insert_at(1, 6) +assert_equal([1,6,2,3], x); diff --git a/unittests/3.x/vector_literal_acccess.chai b/unittests/3.x/vector_literal_acccess.chai new file mode 100644 index 00000000..29a7c05f --- /dev/null +++ b/unittests/3.x/vector_literal_acccess.chai @@ -0,0 +1 @@ +assert_equal(1, [1,2,3][0]) diff --git a/unittests/3.x/vector_of_one.chai b/unittests/3.x/vector_of_one.chai new file mode 100644 index 00000000..f4bb01bf --- /dev/null +++ b/unittests/3.x/vector_of_one.chai @@ -0,0 +1,2 @@ +var x = [1] +assert_equal(1, x[0]) diff --git a/unittests/3.x/vector_paren_literal_access.chai b/unittests/3.x/vector_paren_literal_access.chai new file mode 100644 index 00000000..a0c6b966 --- /dev/null +++ b/unittests/3.x/vector_paren_literal_access.chai @@ -0,0 +1 @@ +assert_equal(1, ([1,2,3])[0]) diff --git a/unittests/3.x/vector_push_back.chai b/unittests/3.x/vector_push_back.chai new file mode 100644 index 00000000..715082bd --- /dev/null +++ b/unittests/3.x/vector_push_back.chai @@ -0,0 +1,5 @@ +var x = [1, 2] +x.push_back(3) +assert_equal(3, x.size()) +assert_equal(3, x.back()) +assert_equal(1, x.front()) diff --git a/unittests/3.x/vector_push_empty.chai b/unittests/3.x/vector_push_empty.chai new file mode 100644 index 00000000..29c568d1 --- /dev/null +++ b/unittests/3.x/vector_push_empty.chai @@ -0,0 +1,4 @@ +var bob = [] +bob.push_back(3) +assert_equal(1, bob.size()) +assert_equal(3, bob.front()) diff --git a/unittests/3.x/zip.chai b/unittests/3.x/zip.chai new file mode 100644 index 00000000..d39583f2 --- /dev/null +++ b/unittests/3.x/zip.chai @@ -0,0 +1,5 @@ +var z = zip([1, 2, 3], [4, 5, 6]) + +assert_equal([1,4], z[0]) +assert_equal([2,5], z[1]) +assert_equal([3,6], z[2]) diff --git a/unittests/3.x/zip_with.chai b/unittests/3.x/zip_with.chai new file mode 100644 index 00000000..1fe3dd90 --- /dev/null +++ b/unittests/3.x/zip_with.chai @@ -0,0 +1,3 @@ +var z = zip_with(`+`, [1, 2, 3], [4, 5, 6]) + +assert_equal([5,7,9], z) diff --git a/unittests/bind.chai b/unittests/bind.chai index 3c72673f..a3af3004 100644 --- a/unittests/bind.chai +++ b/unittests/bind.chai @@ -1,2 +1,2 @@ -var prod = bind(foldl, _, `*`, 1.0) +auto prod = bind(foldl, _, `*`, 1.0) assert_equal(60, prod([3, 4, 5])) diff --git a/unittests/bind2.chai b/unittests/bind2.chai index 0b8ddde3..1adf6b8e 100644 --- a/unittests/bind2.chai +++ b/unittests/bind2.chai @@ -6,11 +6,11 @@ def add(x, y) assert_equal(2, add.get_arity()); -var b = bind(add, 2, _); +auto b = bind(add, 2, _); assert_equal(1, b.get_arity()); -var c = bind(b, 3); +auto c = bind(b, 3); assert_equal(0, c.get_arity()); @@ -22,13 +22,13 @@ def concat2(a,b,c,d) return to_string(a) + to_string(b) + to_string(c) + to_string(d); } -var d = bind(concat2, _, " Hello ", _, " World"); +auto d = bind(concat2, _, " Hello ", _, " World"); assert_equal(2, d.get_arity()); assert_equal("1 Hello 3 World", d(1,3)); -var e = bind(`<`, _, 5); -var types = e.get_param_types(); +auto e = bind(`<`, _, 5); +auto types = e.get_param_types(); assert_equal(2, types.size()); assert_equal(true, types[0].bare_equal(bool_type)); diff --git a/unittests/boxed_cast_test.cpp b/unittests/boxed_cast_test.cpp index 0064e0de..c3c8931d 100644 --- a/unittests/boxed_cast_test.cpp +++ b/unittests/boxed_cast_test.cpp @@ -46,7 +46,7 @@ bool test_type_conversion(const Boxed_Value &bv, bool expectedpass) std::cerr << "Error with type conversion test. From: " << (bv.is_const()?(std::string("const ")):(std::string())) << bv.get_type_info().name() << " To: " - << (boost::is_const::value?(std::string("const ")):(std::string())) << typeid(To).name() + << (std::is_const::value?(std::string("const ")):(std::string())) << typeid(To).name() << " test was expected to " << ((expectedpass)?(std::string("succeed")):(std::string("fail"))) << " but did not" << std::endl; } @@ -57,8 +57,8 @@ template bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtr, bool TPtrConst, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT, bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef, - bool BoostRef, bool BoostConstRef, bool ConstBoostRef, bool ConstBoostConstRef, - bool ConstBoostRefRef, bool ConstBoostConstRefRef, bool Number, + bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef, + bool ConstWrappedRefRef, bool ConstWrappedConstRefRef, bool Number, bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef, bool ConstTPtrConstRef) { bool passed = true; @@ -70,22 +70,22 @@ bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTR passed &= test_type_conversion(bv, ConstTPtr); passed &= test_type_conversion(bv, TPtrConst); passed &= test_type_conversion(bv, ConstTPtrConst); - passed &= test_type_conversion >(bv, SharedPtrT); - passed &= test_type_conversion >(bv, SharedConstPtrT); - passed &= test_type_conversion &>(bv, false); - passed &= test_type_conversion &>(bv, false); - passed &= test_type_conversion >(bv, ConstSharedPtrT); - passed &= test_type_conversion >(bv, ConstSharedConstPtrT); - passed &= test_type_conversion &>(bv, ConstSharedPtrTRef); - passed &= test_type_conversion &>(bv, ConstSharedPtrTConstRef); - passed &= test_type_conversion >(bv, BoostRef); - passed &= test_type_conversion >(bv, BoostConstRef); - passed &= test_type_conversion &>(bv, false); - passed &= test_type_conversion &>(bv, false); - passed &= test_type_conversion >(bv, ConstBoostRef); - passed &= test_type_conversion >(bv, ConstBoostConstRef); - passed &= test_type_conversion &>(bv, ConstBoostRefRef); - passed &= test_type_conversion &>(bv, ConstBoostConstRefRef); + passed &= test_type_conversion >(bv, SharedPtrT); + passed &= test_type_conversion >(bv, SharedConstPtrT); + passed &= test_type_conversion &>(bv, false); + passed &= test_type_conversion &>(bv, false); + passed &= test_type_conversion >(bv, ConstSharedPtrT); + passed &= test_type_conversion >(bv, ConstSharedConstPtrT); + passed &= test_type_conversion &>(bv, ConstSharedPtrTRef); + passed &= test_type_conversion &>(bv, ConstSharedPtrTConstRef); + passed &= test_type_conversion >(bv, WrappedRef); + passed &= test_type_conversion >(bv, WrappedConstRef); + passed &= test_type_conversion &>(bv, false); + passed &= test_type_conversion &>(bv, false); + passed &= test_type_conversion >(bv, ConstWrappedRef); + passed &= test_type_conversion >(bv, ConstWrappedConstRef); + passed &= test_type_conversion &>(bv, ConstWrappedRefRef); + passed &= test_type_conversion &>(bv, ConstWrappedConstRefRef); passed &= test_type_conversion(bv, Number); passed &= test_type_conversion(bv, ConstNumber); passed &= test_type_conversion(bv, false); @@ -137,13 +137,13 @@ bool built_in_type_test(const T &initial, bool ispod) true, false, true, false, true, ispod && true, ispod && true, ispod && true, ispod && false, true); - passed &= do_test(var(boost::ref(i)), true, true, true, true, true, + passed &= do_test(var(std::ref(i)), true, true, true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, true, true, true, ispod && true, ispod && true, ispod && true, true, true); - passed &= do_test(var(boost::cref(i)), true, true, false, true, false, + passed &= do_test(var(std::cref(i)), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, true, false, true, false, true, @@ -167,7 +167,7 @@ bool built_in_type_test(const T &initial, bool ispod) true, false, true, false, true, ispod && true, ispod && true, ispod && true, false, true); - passed &= do_test(var(boost::ref(ir)), true, true, false, true, false, + passed &= do_test(var(std::ref(ir)), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, true, false, true, false, true, @@ -180,7 +180,7 @@ bool built_in_type_test(const T &initial, bool ispod) true, false, true, false, true, ispod && true, ispod && true, ispod && true, false, true); - passed &= do_test(const_var(boost::ref(ir)), true, true, false, true, false, + passed &= do_test(const_var(std::ref(ir)), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, true, false, true, false, true, @@ -205,7 +205,7 @@ bool built_in_type_test(const T &initial, bool ispod) /** shared_ptr tests **/ - boost::shared_ptr ip(new T(initial)); + std::shared_ptr ip(new T(initial)); passed &= do_test(var(ip), true, true, true, true, true, true, true, true, true, true, @@ -220,7 +220,7 @@ bool built_in_type_test(const T &initial, bool ispod) ispod && true, ispod && true, ispod && true, false, true); /** const shared_ptr tests **/ - boost::shared_ptr ipc(new T(initial)); + std::shared_ptr ipc(new T(initial)); passed &= do_test(var(ipc), true, true, false, true, false, true, false, true, false, true, @@ -293,16 +293,16 @@ int main() /* bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtr, bool TPtrConst, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT, - bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef, bool BoostRef, - bool BoostConstRef, bool ConstBoostRef, bool ConstBoostConstRef, bool ConstBoostRefRef, bool ConstBoostConstRefRef, + bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef, bool WrappedRef, + bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef, bool ConstWrappedRefRef, bool ConstWrappedConstRefRef, bool Number, bool ConstNumber, bool ConstNumberRef */ passed &= built_in_type_test(5, true); passed &= built_in_type_test(1.1, true); passed &= built_in_type_test('a', true); - passed &= built_in_type_test('a', true); - passed &= built_in_type_test('a', true); + passed &= built_in_type_test('a', true); + passed &= built_in_type_test('a', true); passed &= built_in_type_test(false, false); passed &= built_in_type_test("Hello World", false); diff --git a/unittests/break_while.chai b/unittests/break_while.chai index d54a3dd9..bfede2ce 100644 --- a/unittests/break_while.chai +++ b/unittests/break_while.chai @@ -1,4 +1,4 @@ -var i = 0 +auto i = 0 while (i < 10) { if (++i == 5) { break diff --git a/unittests/classification.chai b/unittests/classification.chai index 8c2cca94..cc56fbee 100644 --- a/unittests/classification.chai +++ b/unittests/classification.chai @@ -3,5 +3,5 @@ assert_equal(false, 1.is_var_reference()); assert_equal(true, 1.is_var_pointer()); assert_equal(false, 1.is_var_null()); assert_equal(false, 1.is_var_undef()); -var i; +auto i; assert_equal(true, i.is_var_undef()); diff --git a/unittests/collate.chai b/unittests/collate.chai index 12632e59..3a32973c 100644 --- a/unittests/collate.chai +++ b/unittests/collate.chai @@ -1,3 +1,3 @@ -var v = collate(1, 2) +auto v = collate(1, 2) assert_equal(1, v[0]) assert_equal(2, v[1]) diff --git a/unittests/concat.chai b/unittests/concat.chai index 3d285a5b..53950a6e 100644 --- a/unittests/concat.chai +++ b/unittests/concat.chai @@ -1,4 +1,4 @@ -var v = concat([1, 2], [3, 4]); +auto v = concat([1, 2], [3, 4]); assert_equal(4, v.size()); assert_equal(1, v[0]); diff --git a/unittests/const_range_test.chai b/unittests/const_range_test.chai index 5ebb5808..044c13d9 100644 --- a/unittests/const_range_test.chai +++ b/unittests/const_range_test.chai @@ -1,4 +1,3 @@ //If the following succeeds, the test passes - "Hello World".for_each(fun(x) { print(x) } ) diff --git a/unittests/cpp_lambda_test.cpp b/unittests/cpp_lambda_test.cpp new file mode 100644 index 00000000..d38983de --- /dev/null +++ b/unittests/cpp_lambda_test.cpp @@ -0,0 +1,29 @@ +#include + + +int main() +{ + + // We cannot deduce the type of a lambda expression, you must either wrap it + // in an std::function or provide the signature + + + chaiscript::ChaiScript chai; + + // provide the signature + chai.add(chaiscript::fun([] { return "hello"; } ), "f1"); + + // wrap + chai.add(chaiscript::fun(std::function([] { return "world"; } )), "f2"); + + if (chai.eval("f1()") == "hello" + && chai.eval("f2()") == "world") + { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } + + + +} diff --git a/unittests/deep_array_lookup.chai b/unittests/deep_array_lookup.chai index c405302d..8a86eaa3 100644 --- a/unittests/deep_array_lookup.chai +++ b/unittests/deep_array_lookup.chai @@ -1,4 +1,4 @@ -var a = [1,2,3, [4,5,6] ] +auto a = [1,2,3, [4,5,6] ] assert_equal(a[3][0], 4) @@ -6,6 +6,6 @@ assert_equal(a[3][0], 4) def Test::Test() { this.a = [1,2,3]; } attr Test::a; -var t = Test(); +auto t = Test(); assert_equal(t.a[0], 1) diff --git a/unittests/dispatch_functions.chai b/unittests/dispatch_functions.chai index 528d5b30..1887844e 100644 --- a/unittests/dispatch_functions.chai +++ b/unittests/dispatch_functions.chai @@ -6,6 +6,6 @@ assert_equal(get_arity.get_contained_functions().size(), 0); assert_equal(get_arity.get_arity(), 1); assert_equal(get_arity.get_param_types().size(), 2); -var paramtypes = get_arity.get_param_types(); +auto paramtypes = get_arity.get_param_types(); assert_equal(true, paramtypes[1].bare_equal(Function_type)); diff --git a/unittests/dynamic_object_test.cpp b/unittests/dynamic_object_test.cpp index 8383e039..3e09ef64 100644 --- a/unittests/dynamic_object_test.cpp +++ b/unittests/dynamic_object_test.cpp @@ -1,3 +1,4 @@ + #include template @@ -14,10 +15,9 @@ void assert_equal(const LHS &lhs, const RHS &rhs) int main() { - chaiscript::ChaiScript chai; - chai("attr bob::z; def bob::bob() { this.z = 10 }; var x = bob()"); + chai("attr bob::z; def bob::bob() { this.z = 10 }; auto x = bob()"); chaiscript::dispatch::Dynamic_Object &mydo = chai.eval("x"); diff --git a/unittests/equ_shortform.chai b/unittests/equ_shortform.chai index 41c8e1de..b7ec906a 100644 --- a/unittests/equ_shortform.chai +++ b/unittests/equ_shortform.chai @@ -1,4 +1,4 @@ -var x=.5 +auto x=.5 assert_equal(.5, x) -var y=-.5 +auto y=-.5 assert_equal(-.5, y) diff --git a/unittests/eval_error.chai b/unittests/eval_error.chai index d63ad759..b2737a11 100644 --- a/unittests/eval_error.chai +++ b/unittests/eval_error.chai @@ -20,7 +20,7 @@ def func() def doing() { - for (var i = 0; i < 10; ++i) + for (auto i = 0; i < 10; ++i) { func(); } @@ -34,6 +34,6 @@ def while_doing() } } -var f = fun() { while_doing(); } +auto f = fun() { while_doing(); } assert_equal(get_eval_error(f).call_stack.size(), 16) diff --git a/unittests/exception.chai b/unittests/exception.chai index 50df6a80..94e82d83 100644 --- a/unittests/exception.chai +++ b/unittests/exception.chai @@ -1,4 +1,4 @@ -var x = 1 +auto x = 1 try { throw(x) x = 2 diff --git a/unittests/exception_finally.chai b/unittests/exception_finally.chai index d6fd834a..76003c60 100644 --- a/unittests/exception_finally.chai +++ b/unittests/exception_finally.chai @@ -1,4 +1,4 @@ -var finallyone = false; +auto finallyone = false; try { throw(3) @@ -12,9 +12,9 @@ finally { assert_equal(true, finallyone); -var try2 = false; -var catch2 = false; -var finally2 = false; +auto try2 = false; +auto catch2 = false; +auto finally2 = false; try { diff --git a/unittests/exception_guards.chai b/unittests/exception_guards.chai index 99cd9018..12792985 100644 --- a/unittests/exception_guards.chai +++ b/unittests/exception_guards.chai @@ -1,6 +1,6 @@ -var results = []; +auto results = []; -for (var i = 2; i < 6; ++i) { +for (auto i = 2; i < 6; ++i) { try { throw(i) } diff --git a/unittests/for.chai b/unittests/for.chai index 389c02e9..e2d83709 100644 --- a/unittests/for.chai +++ b/unittests/for.chai @@ -1,6 +1,6 @@ -var ret = [] +auto ret = [] -for (var i = 0; i < 5; ++i) { +for (auto i = 0; i < 5; ++i) { ret.push_back(i); } diff --git a/unittests/for_each_range.chai b/unittests/for_each_range.chai index 43191bfb..3a92641d 100644 --- a/unittests/for_each_range.chai +++ b/unittests/for_each_range.chai @@ -1,3 +1,3 @@ -var v = [1,2,3]; -var r = range(v); +auto v = [1,2,3]; +auto r = range(v); for_each(r, fun(x) { assert_equal(true, x>0); } ) diff --git a/unittests/for_each_retro.chai b/unittests/for_each_retro.chai index cc27a580..4cd0ff51 100644 --- a/unittests/for_each_retro.chai +++ b/unittests/for_each_retro.chai @@ -1,4 +1,4 @@ // Don't bother checking the output from this one, just makes sure it executes -var v = [1,2,3]; -var r = retro(range(v)); +auto v = [1,2,3]; +auto r = retro(range(v)); for_each(r, print) diff --git a/unittests/function_introspection.chai b/unittests/function_introspection.chai index 5ad76fc7..6d808dfe 100644 --- a/unittests/function_introspection.chai +++ b/unittests/function_introspection.chai @@ -31,7 +31,7 @@ assert_equal(test_fun.get_arity(), 1); assert_equal(test_fun.get_contained_functions.size(), 1); assert_equal(test_fun.get_param_types().size(), 2); assert_equal(test_fun, test_fun); -var test_fun_types = test_fun.get_param_types(); +auto test_fun_types = test_fun.get_param_types(); assert_equal(true, test_fun_types[0].bare_equal(Object_type)); assert_equal(true, test_fun_types[1].bare_equal(int_type)); @@ -42,7 +42,7 @@ assert_equal(2, `==`.get_arity()); // < should be the merging of two functions bool <(PODObject, PODObject) and bool <(string, string) // we want to peel it apart and make sure that's true -var types = `<`.get_param_types(); +auto types = `<`.get_param_types(); assert_equal(3, types.size()); assert_equal(true, types[0].bare_equal(bool_type)); assert_equal(true, types[1].bare_equal(Object_type)); @@ -62,7 +62,7 @@ assert_equal(true, with_guard.has_guard()); assert_equal(false, without_guard.has_guard()); assert_equal(2, group_guard.get_contained_functions().size()); -var group = group_guard.get_contained_functions(); +auto group = group_guard.get_contained_functions(); assert_equal(true, group[0].has_guard()) assert_equal(false, group[1].has_guard()) @@ -70,7 +70,7 @@ assert_equal(false, group[1].has_guard()) assert_throws("Function does not have a guard", fun() { group[0].get_guard(); } ); assert_throws("Function does not have a guard", fun() { without_guard.get_guard(); } ); -var guard = with_guard.get_guard(); +auto guard = with_guard.get_guard(); assert_equal(false, guard.has_guard()); assert_throws("Function does not have a guard", fun() { guard.get_guard(); } ); diff --git a/unittests/function_ordering_test.cpp b/unittests/function_ordering_test.cpp index b4209a97..00552207 100644 --- a/unittests/function_ordering_test.cpp +++ b/unittests/function_ordering_test.cpp @@ -22,7 +22,7 @@ int main() chai.add(chaiscript::fun(&test_two), "test_fun"); int res1 = chai.eval("test_fun(1)"); - int res2 = chai.eval("var i = 1; test_fun(i)"); + int res2 = chai.eval("auto i = 1; test_fun(i)"); int res3 = chai.eval("test_fun(\"bob\")"); int res4 = chai.eval("test_fun(\"hi\")"); diff --git a/unittests/function_reassignment.chai b/unittests/function_reassignment.chai index 2a885fdc..6ddbce3a 100644 --- a/unittests/function_reassignment.chai +++ b/unittests/function_reassignment.chai @@ -1,3 +1,3 @@ -var x = `+` +auto x = `+` x = `-` assert_equal(1, x(5,4)) diff --git a/unittests/function_redefinition.chai b/unittests/function_redefinition.chai index caabd3d2..f82a414c 100644 --- a/unittests/function_redefinition.chai +++ b/unittests/function_redefinition.chai @@ -1,2 +1,2 @@ -assert_throws("Function already defined", fun() { def foo(x) { x + 1 }; def foo(x) { x + 1 } } ); +assert_throws("Function already defined", fun(){ def foo(x) { x + 1 }; def foo(x) { x + 1 } } ); diff --git a/unittests/functor_cast_test.cpp b/unittests/functor_cast_test.cpp index 1f6f7ec1..7c76ca20 100644 --- a/unittests/functor_cast_test.cpp +++ b/unittests/functor_cast_test.cpp @@ -1,6 +1,6 @@ #include -double test_call(const boost::function &f, int val) +double test_call(const std::function &f, int val) { return f(val); } diff --git a/unittests/functor_creation_test.cpp b/unittests/functor_creation_test.cpp index 6578a6d5..bea12447 100644 --- a/unittests/functor_creation_test.cpp +++ b/unittests/functor_creation_test.cpp @@ -1,5 +1,6 @@ #include + int main() { @@ -7,15 +8,15 @@ int main() chai.eval("def func() { print(\"Hello World\"); } "); - boost::function f = chai.eval >("func"); + std::function f = chai.eval >("func"); f(); - if (chai.eval >("to_string")(6) != "6") + if (chai.eval >("to_string")(6) != "6") { return EXIT_FAILURE; } - if (chai.eval >("to_string")(chaiscript::var(6)) == "6") + if (chai.eval >("to_string")(chaiscript::var(6)) == "6") { return EXIT_SUCCESS; } else { diff --git a/unittests/heap_allocated_chaiscript_test.cpp b/unittests/heap_allocated_chaiscript_test.cpp new file mode 100644 index 00000000..ce37cbac --- /dev/null +++ b/unittests/heap_allocated_chaiscript_test.cpp @@ -0,0 +1,10 @@ +#include + + +int main() +{ + chaiscript::ChaiScript *chai = new chaiscript::ChaiScript(); + delete chai; + + return EXIT_SUCCESS; +} diff --git a/unittests/if.chai b/unittests/if.chai index 3ec7321b..c4249291 100644 --- a/unittests/if.chai +++ b/unittests/if.chai @@ -1,4 +1,4 @@ -var t = false; +auto t = false; if (true) { t = true; diff --git a/unittests/if_else.chai b/unittests/if_else.chai index 8cb42db9..611ee911 100644 --- a/unittests/if_else.chai +++ b/unittests/if_else.chai @@ -1,6 +1,6 @@ -var i = 3 -var b1 = false; -var b2 = false; +auto i = 3 +auto b1 = false; +auto b2 = false; if (i == 2) { b1 = true; diff --git a/unittests/if_elseif.chai b/unittests/if_elseif.chai index 75b85b5f..7e4b5d58 100644 --- a/unittests/if_elseif.chai +++ b/unittests/if_elseif.chai @@ -1,8 +1,8 @@ -var b1 = false; -var b2 = false; -var b3 = false; +auto b1 = false; +auto b2 = false; +auto b3 = false; -var i = 3 +auto i = 3 if (i == 2) { b1 = true; } diff --git a/unittests/if_elseif_else.chai b/unittests/if_elseif_else.chai index 26ed0d26..0f96df7c 100644 --- a/unittests/if_elseif_else.chai +++ b/unittests/if_elseif_else.chai @@ -1,5 +1,5 @@ -var i = 3 -var b = false +auto i = 3 +auto b = false if (i == 2) { assert_equal(false, true) } diff --git a/unittests/index_operator.chai b/unittests/index_operator.chai index e8af5cf6..f8074042 100644 --- a/unittests/index_operator.chai +++ b/unittests/index_operator.chai @@ -3,7 +3,7 @@ def Bob::bob3() { return [1,2,3]; } def Bob::Bob() {} -var b = Bob(); +auto b = Bob(); assert_equal(b.bob3()[0], 1); diff --git a/unittests/inheritance.chai b/unittests/inheritance.chai index 0231a509..e1c33afa 100644 --- a/unittests/inheritance.chai +++ b/unittests/inheritance.chai @@ -1,7 +1,7 @@ load_module("test_module") -var t0 = TestBaseType() -var t = TestDerivedType(); +auto t0 = TestBaseType() +auto t = TestDerivedType(); assert_equal(t0.func(), 0); assert_equal(t.func(), 1); diff --git a/unittests/instring_eval.chai b/unittests/instring_eval.chai index a72b2fc4..32eb2b91 100644 --- a/unittests/instring_eval.chai +++ b/unittests/instring_eval.chai @@ -1,3 +1,3 @@ -var bob = 5.5 +auto bob = 5.5 assert_equal("5.5", "${bob}") assert_equal("val: 8 and 8", "val: ${5.5 + 2.5} and ${bob + 2.5}") diff --git a/unittests/invalid_function_reassignment.chai b/unittests/invalid_function_reassignment.chai index cc7cb5af..784372ac 100644 --- a/unittests/invalid_function_reassignment.chai +++ b/unittests/invalid_function_reassignment.chai @@ -1 +1 @@ -assert_throws("Invalid function reassignment", fun() { var x = 5; x = `-`; } ); +assert_throws("Invalid function reassignment", fun() { auto x = 5; x = `-`; } ); diff --git a/unittests/is_undef.chai b/unittests/is_undef.chai index 38572f0f..894bd3fc 100644 --- a/unittests/is_undef.chai +++ b/unittests/is_undef.chai @@ -1,4 +1,4 @@ -var i; +auto i; assert_equal(true, i.is_var_undef()); i = 5; assert_equal(false, i.is_var_undef()); diff --git a/unittests/lambda.chai b/unittests/lambda.chai index 6b65a1ba..9b717ec5 100644 --- a/unittests/lambda.chai +++ b/unittests/lambda.chai @@ -1,2 +1,2 @@ -var bob = fun(x) { x + 1 } +auto bob = fun(x) { x + 1 } assert_equal(4, bob(3)); diff --git a/unittests/list_push_back.chai b/unittests/list_push_back.chai index 4d88deb8..19d17e13 100644 --- a/unittests/list_push_back.chai +++ b/unittests/list_push_back.chai @@ -1,6 +1,6 @@ load_module("stl_extra") -var x = List() +auto x = List() x.push_back(3) x.push_back("A") diff --git a/unittests/list_push_front.chai b/unittests/list_push_front.chai index 86e28329..fe318216 100644 --- a/unittests/list_push_front.chai +++ b/unittests/list_push_front.chai @@ -1,6 +1,6 @@ load_module("stl_extra") -var x = List() +auto x = List() x.push_front(3) x.push_front("A") diff --git a/unittests/loop_inner_outer.chai b/unittests/loop_inner_outer.chai index 64a25e6e..bda275ff 100644 --- a/unittests/loop_inner_outer.chai +++ b/unittests/loop_inner_outer.chai @@ -1,7 +1,7 @@ -var total = 0 +auto total = 0 -for (var i = 0; i < 10; ++i) { - for (var j = 0; j < 10; ++j) { +for (auto i = 0; i < 10; ++i) { + for (auto j = 0; j < 10; ++j) { total += 1 } } diff --git a/unittests/map_access.chai b/unittests/map_access.chai index 19ebc1ad..d544036d 100644 --- a/unittests/map_access.chai +++ b/unittests/map_access.chai @@ -1,2 +1,2 @@ -var x = ["bob":2, "fred":3] +auto x = ["bob":2, "fred":3] assert_equal(3, x["fred"]) diff --git a/unittests/map_inplace_init.chai b/unittests/map_inplace_init.chai index 138ef038..f86bb4f1 100644 --- a/unittests/map_inplace_init.chai +++ b/unittests/map_inplace_init.chai @@ -1,4 +1,4 @@ -var x = ["bob":1, "fred":2] +auto x = ["bob":1, "fred":2] assert_equal(2, x.size()); diff --git a/unittests/math_dec.chai b/unittests/math_dec.chai index e746f298..58a24e2f 100644 --- a/unittests/math_dec.chai +++ b/unittests/math_dec.chai @@ -1,3 +1,3 @@ -var i = 3 +auto i = 3 assert_equal(2, --i) assert_equal(2, i) diff --git a/unittests/math_inc.chai b/unittests/math_inc.chai index ec317c03..a5953a5c 100644 --- a/unittests/math_inc.chai +++ b/unittests/math_inc.chai @@ -1,3 +1,3 @@ -var i = 3 +auto i = 3 assert_equal(4, ++i) assert_equal(4, i) diff --git a/unittests/memberscope.chai b/unittests/memberscope.chai index fe46810a..f1cf7c15 100644 --- a/unittests/memberscope.chai +++ b/unittests/memberscope.chai @@ -8,5 +8,5 @@ def Vector3::Vector3(x, y, z) { this.z = z } -var v = Vector3(1,2,3); +auto v = Vector3(1,2,3); assert_equal(1, v.x); diff --git a/unittests/multifile_test_chai.cpp b/unittests/multifile_test_chai.cpp index 57b89528..ac288ffc 100644 --- a/unittests/multifile_test_chai.cpp +++ b/unittests/multifile_test_chai.cpp @@ -1,12 +1,14 @@ #include "multifile_test_chai.hpp" +#include + Multi_Test_Chai::Multi_Test_Chai() - : m_chai(new chaiscript::ChaiScript()) + : m_chai(new chaiscript::ChaiScript(chaiscript::Std_Lib::library())) { } -boost::shared_ptr Multi_Test_Chai::get_chai() +std::shared_ptr Multi_Test_Chai::get_chai() { return m_chai; } diff --git a/unittests/multifile_test_chai.hpp b/unittests/multifile_test_chai.hpp index 430b6bc5..c2e306d5 100644 --- a/unittests/multifile_test_chai.hpp +++ b/unittests/multifile_test_chai.hpp @@ -5,10 +5,10 @@ class Multi_Test_Chai public: Multi_Test_Chai(); - boost::shared_ptr get_chai(); + std::shared_ptr get_chai(); private: - boost::shared_ptr m_chai; + std::shared_ptr m_chai; }; diff --git a/unittests/multifile_test_main.cpp b/unittests/multifile_test_main.cpp index 8352ec8b..94bbb6f9 100644 --- a/unittests/multifile_test_main.cpp +++ b/unittests/multifile_test_main.cpp @@ -8,7 +8,7 @@ int main() Multi_Test_Chai chaitest; Multi_Test_Module chaimodule; - boost::shared_ptr chai = chaitest.get_chai(); + std::shared_ptr chai = chaitest.get_chai(); chai->add(chaimodule.get_module()); return chai->eval("get_module_value()"); } diff --git a/unittests/multiline.chai b/unittests/multiline.chai index f13be4e6..dfa213c3 100644 --- a/unittests/multiline.chai +++ b/unittests/multiline.chai @@ -1,9 +1,9 @@ -var x = [1, 2, +auto x = [1, 2, 3, 4] assert_equal(1, x[0]) -var y = map(x, +auto y = map(x, fun(x) { x + 1 }) assert_equal(2, y[0]) diff --git a/unittests/multithreaded_test.cpp b/unittests/multithreaded_test.cpp index 4129e409..26e4d553 100644 --- a/unittests/multithreaded_test.cpp +++ b/unittests/multithreaded_test.cpp @@ -4,7 +4,6 @@ #include #include -#include int expected_value(int num_iters) { @@ -35,7 +34,10 @@ void do_work(chaiscript::ChaiScript &c, int id) int main() { // Disable deprecation warning for getenv call. -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC +#ifdef max // Why microsoft? why? +#undef max +#endif #pragma warning(push) #pragma warning(disable : 4996) #endif @@ -43,7 +45,7 @@ int main() const char *usepath = getenv("CHAI_USE_PATH"); const char *modulepath = getenv("CHAI_MODULE_PATH"); -#ifdef BOOST_MSVC +#ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif @@ -63,17 +65,21 @@ int main() chaiscript::ChaiScript chai(modulepaths,usepaths); - boost::thread_group threads; + std::vector > threads; // Ensure at least two, but say only 7 on an 8 core processor - int num_threads = std::max(boost::thread::hardware_concurrency() - 1, 2u); + int num_threads = std::max(std::thread::hardware_concurrency() - 1, 2u); for (int i = 0; i < num_threads; ++i) { - threads.create_thread(boost::bind(&do_work, boost::ref(chai), i)); + threads.push_back(std::shared_ptr(new std::thread(do_work, std::ref(chai), i))); + } + + for (int i = 0; i < num_threads; ++i) + { + threads[i]->join(); } - threads.join_all(); for (int i = 0; i < num_threads; ++i) diff --git a/unittests/object_attr.chai b/unittests/object_attr.chai index c2da08ea..7076345f 100644 --- a/unittests/object_attr.chai +++ b/unittests/object_attr.chai @@ -1,6 +1,6 @@ attr bob::z def bob::bob() { this.z = 10 } -var x = bob() +auto x = bob() def bob::fred(x) { this.z - x } assert_equal(7, x.fred(3)) diff --git a/unittests/object_attr_same_name.chai b/unittests/object_attr_same_name.chai index fa20bac4..11315675 100644 --- a/unittests/object_attr_same_name.chai +++ b/unittests/object_attr_same_name.chai @@ -4,6 +4,6 @@ def bob::bob() { this.z = 10 } attr bob2::z def bob2::bob2() { this.z = 12 } -var b = bob(); -var b2 = bob2(); +auto b = bob(); +auto b2 = bob2(); diff --git a/unittests/object_clone.chai b/unittests/object_clone.chai index 4659f41a..d1673e83 100644 --- a/unittests/object_clone.chai +++ b/unittests/object_clone.chai @@ -1,10 +1,10 @@ attr bob::z def bob::bob() { } -var x = bob(); +auto x = bob(); x.z = 10; -var y = clone(x); +auto y = clone(x); y.z = 20; assert_equal(10, x.z) diff --git a/unittests/object_constructor_guards.chai b/unittests/object_constructor_guards.chai index f48c00a1..d574eaa5 100644 --- a/unittests/object_constructor_guards.chai +++ b/unittests/object_constructor_guards.chai @@ -3,8 +3,8 @@ attr bob::val def bob::bob(x) : x < 10 { this.val = "Less Than Ten: " + x.to_string(); } def bob::bob(x) { this.val = "Any Other Value: " + x.to_string(); } -var b = bob(12) -var c = bob(3) +auto b = bob(12) +auto c = bob(3) assert_equal("Any Other Value: 12", b.val ) assert_equal("Less Than Ten: 3", c.val ) diff --git a/unittests/object_lifetime_test.cpp b/unittests/object_lifetime_test.cpp index a58e3d2b..3b7ed2fe 100644 --- a/unittests/object_lifetime_test.cpp +++ b/unittests/object_lifetime_test.cpp @@ -29,12 +29,19 @@ int main() { chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module()); - CHAISCRIPT_CLASS( m, - Test, - (Test ()) - (Test (const Test &)), - ((count)) - ); + /* + chaiscript::utility::add_class(*m, + "Test", + { chaiscript::constructor(), + chaiscript::constructor() }, + { {chaiscript::fun(&Test::count), "count"} } + ); + */ + + m->add(chaiscript::user_type(), "Test"); + m->add(chaiscript::constructor(), "Test"); + m->add(chaiscript::constructor(), "Test"); + m->add(chaiscript::fun(&Test::count), "count"); chaiscript::ChaiScript chai; chai.add(m); @@ -42,15 +49,16 @@ int main() int count = chai.eval("count()"); - int count2 = chai.eval("var i = 0; { var t = Test(); } return i;"); + int count2 = chai.eval("auto i = 0; { auto t = Test(); } return i;"); - int count3 = chai.eval("i = 0; { var t = Test(); i = count(); } return i;"); + int count3 = chai.eval("i = 0; { auto t = Test(); i = count(); } return i;"); - int count4 = chai.eval("i = 0; { var t = Test(); { var t2 = Test(); i = count(); } } return i;"); + int count4 = chai.eval("i = 0; { auto t = Test(); { auto t2 = Test(); i = count(); } } return i;"); - int count5 = chai.eval("i = 0; { var t = Test(); { var t2 = Test(); } i = count(); } return i;"); + int count5 = chai.eval("i = 0; { auto t = Test(); { auto t2 = Test(); } i = count(); } return i;"); + + int count6 = chai.eval("i = 0; { auto t = Test(); { auto t2 = Test(); } } i = count(); return i;"); - int count6 = chai.eval("i = 0; { var t = Test(); { var t2 = Test(); } } i = count(); return i;"); if (count == 0 && count2 == 0 diff --git a/unittests/object_method_guards.chai b/unittests/object_method_guards.chai index addc8508..5199c04f 100644 --- a/unittests/object_method_guards.chai +++ b/unittests/object_method_guards.chai @@ -2,6 +2,6 @@ def bob::bob() { } def bob::fred(e) : e < 10 { assert_equal(true, e<10) } def bob::fred(e) { assert_equal(true, e >= 10) } -var b = bob() +auto b = bob() b.fred(3) b.fred(12) diff --git a/unittests/operator_overload.chai b/unittests/operator_overload.chai index 9bd2eb79..387209be 100644 --- a/unittests/operator_overload.chai +++ b/unittests/operator_overload.chai @@ -1,8 +1,8 @@ def Bob::`+`(y) { this.x + y.x } def Bob::Bob() { } attr Bob::x -var b = Bob() -var c = Bob() +auto b = Bob() +auto c = Bob() b.x = 4 c.x = 5 diff --git a/unittests/operator_overload2.chai b/unittests/operator_overload2.chai index b4afbe7b..a992dc7d 100644 --- a/unittests/operator_overload2.chai +++ b/unittests/operator_overload2.chai @@ -1,8 +1,8 @@ def Bob::Bob() { } attr Bob::x def `-`(a, b) : is_type(a, "Bob") && is_type(b, "Bob") { a.x - b.x } -var b = Bob() -var c = Bob() +auto b = Bob() +auto c = Bob() b.x = 4 c.x = 5 diff --git a/unittests/operators_float.chai b/unittests/operators_float.chai index 9a61d905..823d4289 100644 --- a/unittests/operators_float.chai +++ b/unittests/operators_float.chai @@ -1,6 +1,6 @@ -var i = 1.0; -var j = 2.0; -var k = 3.0; +auto i = 1.0; +auto j = 2.0; +auto k = 3.0; assert_equal(3, i + j) assert_equal(1.0, +i) @@ -13,4 +13,4 @@ assert_equal(0, i -= i) assert_equal(3, j *= 1.5) assert_equal(1.5, j /= 2) assert_equal(2.5, j += 1) -assert_throws("No modulous for float", fun() { k % 2 } ); +assert_throws("No modulus for float", fun() { k % 2 } ); diff --git a/unittests/operators_int.chai b/unittests/operators_int.chai index 4627b552..395ce27d 100644 --- a/unittests/operators_int.chai +++ b/unittests/operators_int.chai @@ -1,6 +1,6 @@ -var i = 1; -var j = 2; -var k = 3; +auto i = 1; +auto j = 2; +auto k = 3; assert_equal(3, i + j); assert_equal(1, +i); diff --git a/unittests/pair.chai b/unittests/pair.chai index 9b3c8049..2e30f666 100644 --- a/unittests/pair.chai +++ b/unittests/pair.chai @@ -1,4 +1,4 @@ -var p = Pair("Hello", "World") +auto p = Pair("Hello", "World") assert_equal(p.first, "Hello") assert_equal(p.second, "World") diff --git a/unittests/pointer_passed_to_constructor.chai b/unittests/pointer_passed_to_constructor.chai index 6495ee38..988a2382 100644 --- a/unittests/pointer_passed_to_constructor.chai +++ b/unittests/pointer_passed_to_constructor.chai @@ -1,8 +1,8 @@ load_module("test_module") -var i = 1; -var t0 = TestBaseType(i); +auto i = 1; +auto t0 = TestBaseType(i); -var t1 = TestBaseType(get_new_int()) +auto t1 = TestBaseType(get_new_int()) diff --git a/unittests/precedence_eq.chai b/unittests/precedence_eq.chai index 325d667e..39f2944e 100644 --- a/unittests/precedence_eq.chai +++ b/unittests/precedence_eq.chai @@ -1,3 +1,3 @@ -var x = var y = 4 +auto x = auto y = 4 assert_equal(4, x); assert_equal(4, y); diff --git a/unittests/range.chai b/unittests/range.chai index ddef4f2a..97a430b1 100644 --- a/unittests/range.chai +++ b/unittests/range.chai @@ -1,4 +1,4 @@ -var x = [1, 2, 3, 4] -var r = range(x) +auto x = [1, 2, 3, 4] +auto r = range(x) r.pop_front() assert_equal(2, r.front()); diff --git a/unittests/range_back.chai b/unittests/range_back.chai index 6bf56721..b572f944 100644 --- a/unittests/range_back.chai +++ b/unittests/range_back.chai @@ -1,4 +1,4 @@ -var x = [1, 2, 3, 4] -var r = range(x) +auto x = [1, 2, 3, 4] +auto r = range(x) r.pop_back() assert_equal(3, r.back()) diff --git a/unittests/range_contains.chai b/unittests/range_contains.chai index 28a99b12..e79051e9 100644 --- a/unittests/range_contains.chai +++ b/unittests/range_contains.chai @@ -1,4 +1,4 @@ -var v = [1,2,"hi", "world", 5.5] +auto v = [1,2,"hi", "world", 5.5] assert_equal(true, v.contains(5.5)) assert_equal(false, v.contains(0)) assert_equal(false, v.contains(1, lt)) diff --git a/unittests/range_find.chai b/unittests/range_find.chai index 08045e5a..1bdb1ba9 100644 --- a/unittests/range_find.chai +++ b/unittests/range_find.chai @@ -1,6 +1,6 @@ -var v = [2, 1, "Hi", 5.5] -var r = v.find("Hi"); +auto v = [2, 1, "Hi", 5.5] +auto r = v.find("Hi"); assert_equal("Hi", r.front()) -var r2 = v.find(2, `<`); +auto r2 = v.find(2, `<`); assert_equal(1, r2.front()); diff --git a/unittests/reflection_test.chai b/unittests/reflection_test.chai index 88b39ccc..42566bc1 100644 --- a/unittests/reflection_test.chai +++ b/unittests/reflection_test.chai @@ -1,14 +1,14 @@ load_module("reflection") -var parser := ChaiScript_Parser() -var parse_success = parser.parse("3 + 4", "INPUT") -var a := parser.ast() +auto& parser = ChaiScript_Parser() +auto parse_success = parser.parse("3 + 4", "INPUT") +auto& a = parser.ast() assert_equal(eval(a), 7) -var childs := a.children.front().children -var node := childs[0] +auto& childs = a.children.front().children +auto& node = childs[0] -var parser2 := ChaiScript_Parser() +auto& parser2 = ChaiScript_Parser() parser2.parse("9", "INPUT") @@ -30,7 +30,7 @@ assert_equal(false, `+`.has_parse_tree()); assert_throws("Function does not have a parse tree", fun() { `+`.get_parse_tree(); } ); -var parsetree := my_fun.get_parse_tree(); +auto& parsetree = my_fun.get_parse_tree(); assert_equal(1, eval(parsetree)); diff --git a/unittests/retro.chai b/unittests/retro.chai index d7f6818d..780a06d9 100644 --- a/unittests/retro.chai +++ b/unittests/retro.chai @@ -1,4 +1,4 @@ -var x = [1, 2, 3, 4] -var r = retro(range(x)) +auto x = [1, 2, 3, 4] +auto r = retro(range(x)) r.pop_front() assert_equal(3, r.front()) diff --git a/unittests/retroretro.chai b/unittests/retroretro.chai index 09af3ca7..36c568c9 100644 --- a/unittests/retroretro.chai +++ b/unittests/retroretro.chai @@ -1,7 +1,7 @@ -var x = [1, 2, 3, 4] -var r = retro(range(x)) +auto x = [1, 2, 3, 4] +auto r = retro(range(x)) r.pop_back() -var r2 = retro(r) +auto r2 = retro(r) r2.pop_front() assert_equal(2, r.back()) assert_equal(3, r2.front()) diff --git a/unittests/runtime_error.chai b/unittests/runtime_error.chai index e1e2fc10..b20c2c8b 100644 --- a/unittests/runtime_error.chai +++ b/unittests/runtime_error.chai @@ -1,4 +1,4 @@ -var caught = false +auto caught = false try { throw(runtime_error("error")) diff --git a/unittests/scoping.chai b/unittests/scoping.chai new file mode 100644 index 00000000..e0121005 --- /dev/null +++ b/unittests/scoping.chai @@ -0,0 +1 @@ +{ { { { assert_true(true); assert_true(true); } } } } diff --git a/unittests/short_comparison_test.cpp b/unittests/short_comparison_test.cpp index a57e39c9..5aacfdc2 100644 --- a/unittests/short_comparison_test.cpp +++ b/unittests/short_comparison_test.cpp @@ -18,7 +18,7 @@ int main() chai.add(chaiscript::fun(&Test::get_value), "get_value"); - chai.eval("var t := Test();"); + chai.eval("auto &t = Test();"); if (chai.eval("t.get_value() == 5")) { diff --git a/unittests/type_info_test.cpp b/unittests/type_info_test.cpp index 361be80f..56f2681c 100644 --- a/unittests/type_info_test.cpp +++ b/unittests/type_info_test.cpp @@ -1,6 +1,8 @@ // Tests to make sure that the order in which function dispatches occur is correct +#include #include +#include void test_type(const chaiscript::Type_Info &ti, bool t_is_const, bool t_is_pointer, bool t_is_reference, bool t_is_void, bool t_is_undef) diff --git a/unittests/utility_test.cpp b/unittests/utility_test.cpp index 43e90171..12796588 100644 --- a/unittests/utility_test.cpp +++ b/unittests/utility_test.cpp @@ -1,4 +1,7 @@ +#include +#include #include +#include class Test { @@ -15,23 +18,30 @@ 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))) - ((operator=)) - ); + using namespace chaiscript; - chaiscript::ChaiScript chai; + /// \todo fix overload resolution for fun<> + chaiscript::utility::add_class(*m, + "Test", + { constructor(), + constructor() }, + { {fun(&Test::function), "function"}, + {fun(&Test::function2), "function2"}, + {fun(&Test::function3), "function3"}, + {fun(static_cast(&Test::functionOverload)), "functionOverload" }, + {fun(static_cast(&Test::functionOverload)), "functionOverload" }, + {fun(static_cast(&Test::operator=)), "=" } + + } + ); + + + + chaiscript::ChaiScript chai(chaiscript::Std_Lib::library());; chai.add(m); - if (chai.eval("var t = Test(); t.function2(); ") == "Function2" - && chai.eval("var t2 = Test(); t2.functionOverload(1); ") == "int" - && chai.eval("var t3 = Test(); t3.functionOverload(1.1); ") == "double") + if (chai.eval("auto t = Test(); t.function2(); ") == "Function2" + && chai.eval("auto t2 = Test(); t2.functionOverload(1); ") == "int" + && chai.eval("auto t3 = Test(); t3.functionOverload(1.1); ") == "double") { chai.eval("t = Test();"); return EXIT_SUCCESS; diff --git a/unittests/var_decl.chai b/unittests/var_decl.chai new file mode 100644 index 00000000..a896e6ec --- /dev/null +++ b/unittests/var_decl.chai @@ -0,0 +1 @@ +auto x diff --git a/unittests/var_ref_decl.chai b/unittests/var_ref_decl.chai new file mode 100644 index 00000000..58bfa241 --- /dev/null +++ b/unittests/var_ref_decl.chai @@ -0,0 +1,19 @@ +auto l = 5 +auto & k = l; + + +assert_equal(l, k) + +l = 10 + +assert_equal(10, l) +assert_equal(k, l) + +auto & j +j = l // assignment outside of declaration does *not* result in reference assignment +j = 15 + +assert_equal(15, j) +assert_equal(k, l) +assert_equal(10, l) + diff --git a/unittests/variable_redefinition.chai b/unittests/variable_redefinition.chai index b1600e6c..c59107c5 100644 --- a/unittests/variable_redefinition.chai +++ b/unittests/variable_redefinition.chai @@ -1,2 +1,2 @@ -assert_throws("Variable already defined", fun() { var y = 10; var y = 20; }) +assert_throws("Variable already defined", fun() { auto y = 10; auto y = 20; }) diff --git a/unittests/vector_access.chai b/unittests/vector_access.chai index 34d483cd..58269a25 100644 --- a/unittests/vector_access.chai +++ b/unittests/vector_access.chai @@ -1,2 +1,2 @@ -var x = [1, 2, 3] +auto x = [1, 2, 3] assert_equal(3, x[2]) diff --git a/unittests/vector_erase_at.chai b/unittests/vector_erase_at.chai index 9a96218f..348cd819 100644 --- a/unittests/vector_erase_at.chai +++ b/unittests/vector_erase_at.chai @@ -1,3 +1,3 @@ -var x = [1, 2, 3] +auto x = [1, 2, 3] x.erase_at(1) assert_equal([1,3], x); diff --git a/unittests/vector_inplace_init.chai b/unittests/vector_inplace_init.chai index e7ae1249..56e06906 100644 --- a/unittests/vector_inplace_init.chai +++ b/unittests/vector_inplace_init.chai @@ -1,8 +1,9 @@ -var x = [1, 2, 3] +auto x = [1, 2, 3] assert_equal(3, x.size()) + // Make sure vector elements are copied into place for consistency with // map inplace construction var i = 1; @@ -12,3 +13,9 @@ assert_equal(1, y[0]); i = 3; assert_equal(3, i); assert_equal(1, y[0]); + + +// make sure initialization with a break in the middle works as expected +var a = [0.0,0.0, + 1.0,1.0] + diff --git a/unittests/vector_insert_at.chai b/unittests/vector_insert_at.chai index 4f6ec45b..1b42e1cf 100644 --- a/unittests/vector_insert_at.chai +++ b/unittests/vector_insert_at.chai @@ -1,3 +1,3 @@ -var x = [1, 2, 3] +auto x = [1, 2, 3] x.insert_at(1, 6) assert_equal([1,6,2,3], x); diff --git a/unittests/vector_of_one.chai b/unittests/vector_of_one.chai index f4bb01bf..2763fc19 100644 --- a/unittests/vector_of_one.chai +++ b/unittests/vector_of_one.chai @@ -1,2 +1,2 @@ -var x = [1] +auto x = [1] assert_equal(1, x[0]) diff --git a/unittests/vector_push_back.chai b/unittests/vector_push_back.chai index 715082bd..82ba4b44 100644 --- a/unittests/vector_push_back.chai +++ b/unittests/vector_push_back.chai @@ -1,4 +1,4 @@ -var x = [1, 2] +auto x = [1, 2] x.push_back(3) assert_equal(3, x.size()) assert_equal(3, x.back()) diff --git a/unittests/vector_push_empty.chai b/unittests/vector_push_empty.chai index 29c568d1..4cb7afea 100644 --- a/unittests/vector_push_empty.chai +++ b/unittests/vector_push_empty.chai @@ -1,4 +1,4 @@ -var bob = [] +auto bob = [] bob.push_back(3) assert_equal(1, bob.size()) assert_equal(3, bob.front()) diff --git a/unittests/zip.chai b/unittests/zip.chai index d39583f2..6aa5b36c 100644 --- a/unittests/zip.chai +++ b/unittests/zip.chai @@ -1,4 +1,4 @@ -var z = zip([1, 2, 3], [4, 5, 6]) +auto z = zip([1, 2, 3], [4, 5, 6]) assert_equal([1,4], z[0]) assert_equal([2,5], z[1]) diff --git a/unittests/zip_with.chai b/unittests/zip_with.chai index 1fe3dd90..ca2665ac 100644 --- a/unittests/zip_with.chai +++ b/unittests/zip_with.chai @@ -1,3 +1,3 @@ -var z = zip_with(`+`, [1, 2, 3], [4, 5, 6]) +auto z = zip_with(`+`, [1, 2, 3], [4, 5, 6]) assert_equal([5,7,9], z)